我试图写一个到内存的跳转,但似乎找不到任何可以解释其工作原理的地方。

typedef UINT(WINAPI* tResetWriteWatch)(LPVOID lpBaseAddress, SIZE_T dwRegionSize);

UINT WINAPI ResetWriteWatchHook(LPVOID lpBaseAddress, SIZE_T dwRegionSize){
    printf("Function called\n");
    return 0;
}

void main(){
    DWORD64 hookAddr = (DWORD64)&ResetWriteWatch;
    WriteJump(hookAddr, ResetWriteWatchHook/*Let's say it's 0x7FE12345678*/);//Writes E9 XX XX XX XX to memory
}

我的主要问题是我不理解:如何将asm JMP 0x7FE12345678转换为E9 XX XX XX XX,以便可以在hookAddr上编写它。

进程是64位。

最佳答案

这是在32位程序上的通常做法(不确定64位程序有多少不同),但这应该使您知道去哪里。由于VirtualProtect,这特定于Windows,但是如果您在Linux上,则可以使用mprotect

#include <stdio.h>
#include <windows.h>

void foo() {
    printf("Foo!");
}

void my_foo() {
    printf("My foo!");
}

int setJMP(void *from, void *to) {
    DWORD protection;
    if (!VirtualProtect(from, 5, PAGE_EXECUTE_READWRITE, &protection)) { // We must be able to write to it (don't necessarily need execute and read)
        return 0;
    }

    *(char *)from = 0xE9; // jmp opcode
    *(int *)(from + 1) = (int)(to - from - 5); // relative addr

    return VirtualProtect(from, 5, protection, &protection); // Restore original protection
}

int main() {
    setJMP(foo, my_foo);
    foo(); // outputs "My foo!"

    return 0;
}

关于c++ - 写跳转到内存,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40814633/

10-14 08:00