ReadProcessMemory 仅适用于断点
ReadProcessMemory only works with breakpoint
我开始创建一个进程,如果它失败就记录下来,然后一个 while 循环等待 window 被发现。
PROCESS_INFORMATION p;
STARTUPINFO s;
ZeroMemory(&s, sizeof(s));
s.cb = sizeof(s);
ZeroMemory(&p, sizeof(p));
if (!CreateProcessA("D:\SteamLibrary\steamapps\common\Fallout 4\Wolf4SDL.exe", "", NULL, NULL, FALSE, 0, NULL, NULL, &s, &p))
{
_MESSAGE("CreateProcess failed (%d).", GetLastError());
}
//wait for the process to start
while (FindWindowA(NULL, "Wolfenstein 3D") == NULL);
然后为两个进程设置 vars - x64,即 64 位地址。 “地址”是一个指针。 addrOff 是静态偏移量。
HANDLE procHandle = p.hProcess;
unsigned long long addr;
unsigned long long addrOff = 0x00000001401a7718;
SIZE_T NumberOfBytesToRead = sizeof(addr);
SIZE_T NumberOfBytesActuallyRead;
现在阅读,以及一些基本的调试消息
ReadProcessMemory(procHandle, (LPCVOID)(addrOff), &addr, NumberOfBytesToRead, &NumberOfBytesActuallyRead);
_MESSAGE("addr: %p",addr);
_MESSAGE("numBytesRead: %d", NumberOfBytesActuallyRead);
所以这就是问题所在 - 如果我在其中放置一个断点,addr
将为正在读取的静态偏移量提供适当的值。如果我不这样做,addr
的值将是 0x0000000000000000。在这两种情况下,NumberOfBytesActuallyRead
都将具有适当的值 8。即使不查看我的日志,该过程也会存在并说明 - 但查看我的日志可以证实这一点。
不用说,这几乎不可能调试这个问题。现在,我想到了一个奇怪的现象——我注意到在示例中人们将偏移量添加到基地址,而我只是使用偏移量。因此,由于我的 addrOff
值可能包含基地址,所以我在两种情况下都检查了基地址 - 它们都是相同的。并且为了完成,基地址码。
unsigned long long dwBase = -1;
EnumProcessModules(procHandle, hModules, 0, &cModules);
hModules = new HMODULE[cModules / sizeof(HMODULE)];
if (EnumProcessModules(procHandle, hModules, cModules / sizeof(HMODULE), &cModules)) {
for (size_t i = 0; i < cModules / sizeof(HMODULE); i++) {
if (GetModuleBaseName(procHandle, hModules[i], szBuf, sizeof(szBuf))) {
if (std::string("Wolf4SDL.exe").compare(szBuf) == 0) {
dwBase = (unsigned long long)hModules[i];
break;
}
}
}
}
非常简单。
你正在读的变量,你读的时候还是0
当您使用断点时,您查看代码并按继续的时间延迟是另一个进程设置变量的时间。
我开始创建一个进程,如果它失败就记录下来,然后一个 while 循环等待 window 被发现。
PROCESS_INFORMATION p;
STARTUPINFO s;
ZeroMemory(&s, sizeof(s));
s.cb = sizeof(s);
ZeroMemory(&p, sizeof(p));
if (!CreateProcessA("D:\SteamLibrary\steamapps\common\Fallout 4\Wolf4SDL.exe", "", NULL, NULL, FALSE, 0, NULL, NULL, &s, &p))
{
_MESSAGE("CreateProcess failed (%d).", GetLastError());
}
//wait for the process to start
while (FindWindowA(NULL, "Wolfenstein 3D") == NULL);
然后为两个进程设置 vars - x64,即 64 位地址。 “地址”是一个指针。 addrOff 是静态偏移量。
HANDLE procHandle = p.hProcess;
unsigned long long addr;
unsigned long long addrOff = 0x00000001401a7718;
SIZE_T NumberOfBytesToRead = sizeof(addr);
SIZE_T NumberOfBytesActuallyRead;
现在阅读,以及一些基本的调试消息
ReadProcessMemory(procHandle, (LPCVOID)(addrOff), &addr, NumberOfBytesToRead, &NumberOfBytesActuallyRead);
_MESSAGE("addr: %p",addr);
_MESSAGE("numBytesRead: %d", NumberOfBytesActuallyRead);
所以这就是问题所在 - 如果我在其中放置一个断点,addr
将为正在读取的静态偏移量提供适当的值。如果我不这样做,addr
的值将是 0x0000000000000000。在这两种情况下,NumberOfBytesActuallyRead
都将具有适当的值 8。即使不查看我的日志,该过程也会存在并说明 - 但查看我的日志可以证实这一点。
不用说,这几乎不可能调试这个问题。现在,我想到了一个奇怪的现象——我注意到在示例中人们将偏移量添加到基地址,而我只是使用偏移量。因此,由于我的 addrOff
值可能包含基地址,所以我在两种情况下都检查了基地址 - 它们都是相同的。并且为了完成,基地址码。
unsigned long long dwBase = -1;
EnumProcessModules(procHandle, hModules, 0, &cModules);
hModules = new HMODULE[cModules / sizeof(HMODULE)];
if (EnumProcessModules(procHandle, hModules, cModules / sizeof(HMODULE), &cModules)) {
for (size_t i = 0; i < cModules / sizeof(HMODULE); i++) {
if (GetModuleBaseName(procHandle, hModules[i], szBuf, sizeof(szBuf))) {
if (std::string("Wolf4SDL.exe").compare(szBuf) == 0) {
dwBase = (unsigned long long)hModules[i];
break;
}
}
}
}
非常简单。
你正在读的变量,你读的时候还是0
当您使用断点时,您查看代码并按继续的时间延迟是另一个进程设置变量的时间。