为什么这个钩子跳到了错误的地址?

时间:2014-08-15 20:23:34

标签: c++ assembly hook

所以我目前正在学习钩子和注射,并为自己构建一个小测试应用程序。我在那里做的是:

  1. 在流程中分配一些内存(使用VirtualAllocEx
  2. 将代码编写到此代码洞穴中(使用WriteProcessMemory
  3. 在应用程序内挂钩一个函数以跳转到此代码洞穴
  4. 现在我遇到了一些问题,我不确定它们为什么会发生。 我创建洞穴的代码是:

        DWORD procID = GetCurrentProcessId();
        HANDLE procHandle = OpenProcess((PROCESS_VM_WRITE | PROCESS_VM_OPERATION), false, procID);
        if (procHandle == NULL) {
            std::cout << "OpenProcess failed..." << std::endl;
            return -1;
        }
    
        DWORD leng = (unsigned int)dynASM_end - (unsigned int)dynASM;
        leng += 270;
    
        LPVOID allocAddr = VirtualAllocEx(procHandle, NULL, leng, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        std::cout << "BaseAddr: " << allocAddr << std::endl;
    
        int check = WriteProcessMemory(procHandle, (void*)((char*)allocAddr + 0x10E), dynASM, leng - 270, NULL);
        unsigned int bExec = 1;
        check = WriteProcessMemory(procHandle, allocAddr, &bExec, sizeof(unsigned int), NULL);
        if (check) {
            std::cout << "Successfully written asm to process!" << std::endl;
        }
    

    现在这是非常基本的。 VirtualAllocEx始终返回0x00030000,这可能吗? 这是我简单的汇编代码:

    void testCall()
    {
        std::cout << "Hook worked!" << std::endl;
    }
    
    __declspec(naked) void dynASM()
    {
        __asm {
            push ebp
            mov ebp, esp
            call testCall
            mov esp, ebp
            pop ebp
            ret
        }
    }
    
    __declspec(naked) void dynASM_end()
    {
    }
    

    我相信我可以用这种方式调用函数testCall,不能吗?这是我在编解码器中输入的代码,如上所示。

    现在,我想要挂钩的另一个类中的函数有一个偏移量。此功能仅包括:

    __declspec(naked) void Core::HookFunc()
    {
        __asm {
            mov edi, edi
            push ebp
            mov ebp, esp
    
            mov esp, ebp
            pop ebp
            ret
        }
    }
    

    我试着像这样挂钩:

    DWORD hookFuncOffset = 0x14510;
    DWORD jumpTo = (DWORD)((char*)allocAddr + 0x10E);
    DWORD baseAddr = (DWORD)GetModuleHandle(NULL);
    
    BYTE* finalAddr = (BYTE*)((DWORD)baseAddr + hookFuncOffset);
    
    DWORD oldProtect, bkpProtect, relAdr;
    VirtualProtect(finalAddr, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
    
    relAdr = (DWORD)(jumpTo - (DWORD)finalAddr) - 5;
    
    *finalAddr = 0xE9;
    *((DWORD*)finalAddr + 0x1) = relAdr;
    
    VirtualProtect(finalAddr, 5, oldProtect, &bkpProtect);
    

    allocAddr是我上面分配的代码洞的地址。 现在在调试时我可以看到relAddr0xFFFABBF9,这对我来说似乎很高。但是,如果我查看Visual Studio的反汇编视图,jmp创建的0xF9939B14会导致{{1}},从而导致访问冲突异常。我相信,即使jmp会导致&#34;正确&#34;地址它也会抛出异常。我做错了什么?

0 个答案:

没有答案