WINAPI ReadProcessMemory总是相同的地址

时间:2012-05-19 23:43:16

标签: c++ winapi readprocessmemory object-address

我使用WINAPI函数ReadProcessMemory从进程(地址:0x58F03C)读取一些数据:

DWORD proc_id;
GetWindowThreadProcessId(hwnd, &proc_id);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id);
int value=0;

while (1)
{
    ReadProcessMemory(hProcess, (LPVOID)0x58F03C, &value, sizeof(value), 0);
    cout << "val: " << value << endl;
}

由于每次重新启动进程时地址都会更改,我想知道是否有办法始终获取相同的地址?必须有一个,因为我看到很多“培训师 - 程序”能够做到这一点。他们如何获得正确的地址值来读取/写入?

目前,我通过扫描CheatEngine的值来获取它,然后对更改后的值执行下一次扫描。

感谢。

2 个答案:

答案 0 :(得分:2)

您遇到动态内存分配。在CheatEngine世界中,这些被称为“指针”。

考虑一下uint32_t'内存中的一些数据(例如DWORD / malloc)。如果找到数据的地址,则无法保证下次启动该过程时,地址将相同。这是因为malloc返回的内存可以基于内存中的不同点。

用于打败动态内存分配的技巧是找到一个静态堆地址,它可以引导您获得您感兴趣的值的地址.CheatEngine教程向您展示了如何完成此操作。这同样适用于多级指针。在更高级别,这对应于动态分配的内存,该内存保存指向其他动态分配的内存的指针,依此类推。

CheatEngine中用于获取指针的方法大致如下:

  • 在您感兴趣的数据值的地址处设置访问硬件断点
  • 当代码访问它时,硬件断点将显示代码的样子

代码通常如下所示:

mov eax, 0x1234ABCD 
dec dword ptr ds:[eax+0x85]

这可能与某些代码相对应,这些代码在被敌人击中时会减少HP。在这种情况下,0x1234ABCD是指针,偏移量是0x85。在C代码中,可能会发生这种情况:

struct some_struct* blah = malloc(...);
...
blah->HP--;

0x1234ABCD将是blah的地址。 HP值位于blah指向的块内部。内存块的偏移量为0x85。然后,如果您正在编写培训师,则会在0x1234ABCD处读取DWORDQWORD,如果为64位)并将值添加到0x85。这将为您提供HP值的地址。

答案 1 :(得分:0)

如果地址位于数据部分的可执行文件中,预分配变量存在(不适合堆和堆栈),这将有效...

查看"Enumerating All Modules For a Process" example on MSDN

它使用EnumProcessModules()来获取模块句柄。这些是图像基地址。

您可以获取可执行文件的图像基址,并通过它调整您的地址。