C/C++ 外部特征碼尋址-hook終結者2過CRC檢測


    #include "Windows.h"
#include "tlhelp32.h"
#include "String.h"
#include "Shlwapi.h"
#include "iostream"
using namespace std;

HANDLE hProcess;
LPVOID lp_address;
LPVOID lp_ret_value_address;
DWORD lp_ret_jmp;
DWORD lp_to_jmp;

template <typename T>
T Read(LPVOID Address)
{
    T Data;
    ReadProcessMemory(hProcess, (LPVOID)Address, &Data, sizeof(T), nullptr);
    return Data;
}

uintptr_t FindPattern(uintptr_t start, uintptr_t length, const unsigned char* pattern, const char* mask)
{
    size_t pos = 0;
    auto maskLength = strlen(mask) - 1;

    auto startAdress = start;
    for (auto it = startAdress; it < startAdress + length; ++it)
    {
        if (Read<unsigned char>(LPVOID(it)) == pattern[pos] || mask[pos] == '?')
        {
            if (mask[pos + 1] == '\0')
                return it - maskLength;

            pos++;
        }
        else pos = 0;
    }
    return 0;
}

//特征碼尋址
uintptr_t FindPattern(HMODULE hModule, const unsigned char* pattern, const char* mask)
{
    IMAGE_DOS_HEADER DOSHeader = Read<IMAGE_DOS_HEADER>(hModule);
    IMAGE_NT_HEADERS NTHeaders = Read<IMAGE_NT_HEADERS>(LPVOID(uintptr_t(hModule) + DOSHeader.e_lfanew));

    return FindPattern(
        reinterpret_cast<uintptr_t>(hModule) + NTHeaders.OptionalHeader.BaseOfCode,
        reinterpret_cast<uintptr_t>(hModule) + NTHeaders.OptionalHeader.SizeOfCode, pattern, mask);
}

HMODULE GetProcessModuleHandleByName(DWORD pid, LPCSTR ModuleName)
{
    MODULEENTRY32 ModuleInfo;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
    if (!hSnapshot)
    {
        return 0;
    }
    ZeroMemory(&ModuleInfo, sizeof(MODULEENTRY32));
    ModuleInfo.dwSize = sizeof(MODULEENTRY32);
    if (!Module32First(hSnapshot, &ModuleInfo))
    {
        return 0;
    }
    do
    {
        if (!lstrcmpi(ModuleInfo.szModule, ModuleName))
        {
            CloseHandle(hSnapshot);
            return ModuleInfo.hModule;
        }
    } while (Module32Next(hSnapshot, &ModuleInfo));
    CloseHandle(hSnapshot);
    return 0;
}

DWORD GetProcessIDByName(const char* pName)
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (INVALID_HANDLE_VALUE == hSnapshot) {
        return NULL;
    }
    PROCESSENTRY32 pe = { sizeof(pe) };
    for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe)) {
        if (strcmp(pe.szExeFile, pName) == 0) {
            CloseHandle(hSnapshot);
            return pe.th32ProcessID;
        }
        //printf("%-6d %s\n", pe.th32ProcessID, pe.szExeFile);
    }
    CloseHandle(hSnapshot);
    return 0;
}


//內聯匯編被寫入
inline __declspec(naked) void ret_hook()
{
    __asm
    {
        mov edi,edi
        push ebp
        mov ebp,esp
        mov edx, edi
    }
}

int main()
{
    SetConsoleTitleA("[Pass CRC ~《終結者2:審判日》 1.123311.297055 ] ");

    DWORD OldProtect = NULL;
    int Pid = GetProcessIDByName("zjz.exe");
    hProcess = INVALID_HANDLE_VALUE;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);//游戲進程句柄

    cout << "進程ID:" << Pid << endl << endl << "進程句柄:" << hProcess << endl << endl;


    lp_address = VirtualAllocEx(hProcess, NULL, 128, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

    //cout << "分配的寫入hook的地址:" << lp_address << hex << endl;

    //bcryptPrimitives.dll+24AFF - CC                    - int 3 

    HMODULE hbcryptPrimitives = GetProcessModuleHandleByName(Pid, "bcryptPrimitives.dll");


    //這邊自己搞檢測地址
    lp_ret_jmp = (DWORD)hbcryptPrimitives + 0x24B05;
    lp_to_jmp = (DWORD)hbcryptPrimitives + 0x24B00;

    //cout << "跳回的地址計算:" << lp_ret_jmp << endl;


    /*寫ret hook*/
    if (WriteProcessMemory(hProcess, lp_address, ret_hook, 50, NULL) != 0) {
        //cout << "寫入成功!" << endl;
        BYTE jmp_e9 = { 0xe9 };
        WriteProcessMemory(hProcess, (LPVOID)((DWORD)lp_address + 0x7), (LPVOID)&jmp_e9, 1, NULL);
        int jmp_ret = (int)lp_ret_jmp - ((DWORD)lp_address + 0x7) - 5;
        WriteProcessMemory(hProcess, (LPVOID)((DWORD)lp_address + 0x8), (LPVOID)&jmp_ret, 4, NULL);


        /*to hook*/
        BYTE jmp_to_e9 = { 0xe9 };
        WriteProcessMemory(hProcess, (LPVOID)lp_to_jmp, (LPVOID)&jmp_to_e9, 1, NULL);
        int jmp_to_hook = (int)lp_address - lp_to_jmp - 5;
        WriteProcessMemory(hProcess, (LPVOID)(lp_to_jmp + 0x1), (LPVOID)&jmp_to_hook, 4, NULL);
    }
    /*ret jmp*/



    cout << "CRC檢測已經成功過掉!請盡情開啟功能玩耍!" << endl << endl;

    cout << "QQ404087015  QQ群786070465-游戲逆向信息安全-xd團隊" << endl << endl;

    cout << "網易雲課堂搜索 “逆向” ,關注我們!了解更多!" << endl;


    getchar();
    return 0;
}

 

有同學問的特征碼尋址,大致調用方法如下:

//uintptr_t Fnd = FindPattern(hModule, (const unsigned char*)"\x8B\xFF\x55\x8B\xEC\x81\xEC\xC4\x00\x00\x00\xA1",
//"xxxxxxxxxxxx");

 

關鍵字:“FindPattern”,外網有很多大佬寫,不同的方式都可以,大家可以自己封裝,上面代碼為我自己封裝的,可能會出現一些問題在所難免。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM