我使用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
的值来获取它,然后对更改后的值执行下一次扫描。
感谢。
答案 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处读取DWORD
(QWORD
,如果为64位)并将值添加到0x85。这将为您提供HP值的地址。
答案 1 :(得分:0)
如果地址位于数据部分的可执行文件中,预分配变量存在(不适合堆和堆栈),这将有效...
查看"Enumerating All Modules For a Process" example on MSDN。
它使用EnumProcessModules()来获取模块句柄。这些是图像基地址。
您可以获取可执行文件的图像基址,并通过它调整您的地址。