我正在使用WinAPI的ReadProcessMemory()
来阅读游戏中的一些“隐藏”信息。
我使用Cheat Engine找出静态指针,但我不知道如何从中读取。
Cheat Engine给了我一个指向这样的指针:"mygame.exe"+1C50
我是WinAPI的新用户,如何将"mygame.exe"+1C50
转换为我可以使用ReadProcessMemory()
阅读的地址?
编辑:我尝试简化问题,但我想我应该首先给出完整的代码。 所以我在这里使用静态地址和多级指针,但我仍然坚持获取基地址或w / e。
以下是完整代码和a picture of my cheat engine address:
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
using namespace std;
HANDLE GetProcessHandle(const char *procName);
int main()
{
const char *procName = "prism3d.exe";
HANDLE hProc = GetProcessHandle(procName);
if (hProc) {
/* This works if I use the dynamic address (f.e. 0x02C2C4DC),
but it changes every time I restart the game.
I need to use the static address (prism3d.exe+A1C) to get
the dynamic address for my "nuke".
*/
float nuke;
ReadProcessMemory(hProc, (void*)0x02C2C4DC, &nuke, 4, 0);
cout << nuke;
}
CloseHandle(hProc);
return 0;
}
HANDLE GetProcessHandle(const char *procName)
{
HANDLE hProc = NULL;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (Process32First(hSnapshot, &pe32)) {
do {
if (!strcmp(pe32.szExeFile, procName)) {
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
break;
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return hProc;
}
编辑2:
这是我尝试阅读核武器的价值的方法,但是它给了我随机数,每次重新开始游戏都有所不同(有时它是0
,有时是324324324
等等......):
if (hProc) [
DWORD baseAddr = (DWORD)GetModuleHandle(procName) + 0xA1C50; // also tried this with GetModuleHandle(NULL)
DWORD mainAddr;
ReadProcessMemory(hProc, (void*)(baseAddr + 0x111C), &mainAddr, 4, 0);
// Nuke
float nuke;
DWORD nukeAddr;
ReadProcessMemory(hProc, (void*)(mainAddr + 0x48), &nukeAddr, 4, 0);
ReadProcessMemory(hProc, (void*)nukeAddr, &nuke, 4, 0);
cout << nuke;
}
答案 0 :(得分:7)
基本偏移通常是内存中模块的开始,你可以用GetModuleHandle
得到它(返回的地址是内存中PE的开始)。我通常会说,因为某些约定定义了相对于代码部分开头的基础,然后您需要从PE中读取。
您可以执行以下操作:
UINT_PTR addr = (UINT_PTR)GetModuleHandle("game.dll") + 0x1C50;
ReadProcessMemory(hProc,(void*)addr,pBuffer,nSize,&BytesRead);
以上只有在您所定位的进程的地址空间中运行时(通过dll注入),才能通过远程进程(如您的示例所示)执行此操作,您需要枚举处理模块以获取对您感兴趣的模块的有效句柄。
MSDN有一个here的例子,稍微重构一下,你可以创建一个检查名称的函数,如果它匹配则返回HMODULE
,这会给你模块库地址。