为什么我应该在 WriteProcessMemory() 函数的第二个参数中使用 (void*)?

Why should I use (void*) in second parameter of WriteProcessMemory() func?

我正在尝试为游戏创建游戏训练器。我找到了所需的内存地址,现在我想将我的值写入该地址。

例如:弹药地址为:0x0E9AFD07

WindowsAPI中的WriteProcessMemory()函数可以做到这一点

我的来源:

int main(){
    DWORD pid;
    int address = 0x0E9AFD07;
    const int data = 20;
    HWND hwnd = FindWindow(0 , "Max Payne v1.05");
    GetWindowThreadProcessId(hwnd , &pid);
    HANDLE hndl = OpenProcess(PROCESS_ALL_ACCESS , false ,pid);
    WriteProcessMemory(hndl , &address , &data , 4 , NULL); 

    return 0;
}

但是这个代码不起作用!

如果我应该像下面这样使用 WriteProcessMemory

WriteProcessMemory(hndl , (void*)0x0E9AFD07 , &data , 4 , NULL); 

然后函数的第二个参数是LPVOID类型,我读到LPVOID是指向任何东西的指针。

那么,为什么我不能将指向 int(地址变量)的指针传递给第二个参数?

为什么要使用 (void*)

请注意,您的两个代码片段等价;相反,他们要求 WriteProcessMemory 函数将数据写入 不同的 位置。

在第二个片段中,您传递 0x0E9AFD07(作为 void*),它告诉函数从给定地址(传递的十六进制值)开始将数据写入内存。

但是,在第一个片段中,您传递了 int 变量的地址(恰好包含值 0x0E9AFD07);这将指示函数将数据写入该变量的位置 - 因此,覆盖那里的 0x0E9AFD07 值(或尝试这样做失败)。

如果要传递存储在局部变量中的地址,则需要将该变量的 value 转换为 void* 指针,如下所示:

int main(){
    DWORD pid;
    int address = 0x0E9AFD07;
    const int data = 20;
    HWND hwnd = FindWindow(0 , "Max Payne v1.05");
    GetWindowThreadProcessId(hwnd , &pid);
    HANDLE hndl = OpenProcess(PROCESS_ALL_ACCESS , false ,pid);
    // The "int" variable's VALUE is the target address, so cast/pass that...
    WriteProcessMemory(hndl , (void*)address , &data , 4 , NULL); 

    return 0;
}
  • Why should I use (void*)

    因为这就是手册告诉您函数所期望的。具体来说:

    lpBaseAddress

    A pointer to the base address in the specified process to which data is written. Before data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for write access, and if it is not accessible, the function fails.

  • 出于同样的原因,您不能依次传递包含该地址的局部变量的地址,因为这不是函数所期望的。

  • LPVOID 只是 Windows void* 的乱码,它们是相同的类型。

  • 为了将整数地址转换为指针类型,您需要强制转换,因为 C 和 C++ 就是这样设计的。您不能将整数分配给指针,请参阅

  • 值得注意的是 0x0E9AFD07 是一个未对齐的地址,因此向该地址写入一个 4 字节整数是可疑的。