CreateToolhelp32Snapshot

CreateToolhelp32Snapshot

此代码在64位应用程序中运行。目标应用程序是32位。

每次运行此代码时,CreateToolhelp32Snapshot()返回INVALID_HANDLE_VALUE,然后GetLastError()返回ERROR_PARTIAL_COPY。因此它跳过循环并返回false。

BOOL HookInjector::InjectIntoProcess(DWORD pID)
{
    //Get Handle to Remote Process
    HANDLE Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    ....
    //Check to see if 64-bit or 32-bit application
    IsWow64Process(Proc, &isWow64);
    size_t szCurProc = sizeof(void*); //returns 8
    if (isWow64)
    {
        __debugbreak();
        //Get list of all Modules associated with the Process
        HANDLE hProc32Module;
        do {
            hProc32Module = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE32, pID);
        }
        while ((hProc32Module == INVALID_HANDLE_VALUE) && (GetLastError() == ERROR_BAD_LENGTH));

    if (hProc32Module == INVALID_HANDLE_VALUE) {
        __debugbreak();
        DWORD err = GetLastError(); //just to see the error code which is 0x12b
        return false;
    }

        //Find the module for Kernel.dll and get the base address of it
        MODULEENTRY32 entryModule;
        entryModule.dwSize = sizeof(MODULEENTRY32);
        BOOL isGetModuleSuccess = Module32First(hProc32Module, &entryModule);
        DWORD errEndofList = GetLastError();
        BOOL isSuccessful = false;
        while (errEndofList != ERROR_NO_MORE_FILES && isGetModuleSuccess)
        {
            if (_tcscmp(entryModule.szModule, KERNEL32_DLL)){
                isSuccessful = true;
                break;
            }
            isGetModuleSuccess = Module32Next(hProc32Module, &entryModule);
            errEndofList = GetLastError();
        }

        if (!isSuccessful)
        {
            __debugbreak();
            CloseHandle(hProc32Module);
            return false;
        }

        //Get handle for Kernel.dll module
        hKernel32 = entryModule.hModule;
        CloseHandle(hProc32Module);
    }
    else
    {
        ....

最佳答案

根据documentation,只有当尝试访问64位进程的32位进程调用CreateToolhelp32Snapshot()时,ERROR_PARTIAL_COPY才会失败,并且CreateToolhelp32Snapshot()失败:



首先,请确保您的应用程序确实是为64位编译的。只有在64位进程中调用TH32CS_SNAPMODULE32时,才可以使用CreateToolhelp32Snapshot():



您也没有考虑到GetLastError()仅在API函数失败时才更新,除非另有说明。您的循环假设每次API调用后GetLastError()都会更新,这是不正确的。

尝试类似这样的方法:

BOOL HookInjector::InjectIntoProcess(DWORD pID)
{
    //Get Handle to Remote Process
    HANDLE Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    ....

    DWORD dwFlag;
    #ifdef _WIN64
    //Check if Remote Process is a 32-bit application
    BOOL isWow64 = FALSE;
    IsWow64Process(Proc, &isWow64);
    if (!isWow64) return false;
    // TH32CS_SNAPMODULE32 includes 32bit modules when used by a 64bit process...
    dwFlag = TH32CS_SNAPMODULE32;
    #else
    // TH32CS_SNAPMODULE includes 32bit modules when used by a 32bit process...
    dwFlag = TH32CS_SNAPMODULE;
    #endif

    __debugbreak();

    //Get list of all Modules associated with the Process

    HANDLE hProc32Module;
    do {
        hProc32Module = CreateToolhelp32Snapshot(dwFlag, pID);
    }
    while ((hProc32Module == INVALID_HANDLE_VALUE) && (GetLastError() == ERROR_BAD_LENGTH));

    if (hProc32Module == INVALID_HANDLE_VALUE) {
        __debugbreak();
        return false;
    }

    //Find the module for Kernel.dll and get the base address of it

    hKernel32 = NULL;

    MODULEENTRY32 entryModule = {0};
    entryModule.dwSize = sizeof(MODULEENTRY32);

    BOOL isGetModuleSuccess = Module32First(hProc32Module, &entryModule);
    while (isGetModuleSuccess) {
        if (_tcscmp(entryModule.szModule, KERNEL32_DLL)) {
            hKernel32 = entryModule.hModule;
            break;
        }
        isGetModuleSuccess = Module32Next(hProc32Module, &entryModule);
    }

    if (!hKernel32) {
        __debugbreak();
        CloseHandle(hProc32Module);
        return false;
    }

    CloseHandle(hProc32Module);

    ....
}

09-12 09:31