因此,我有一个模板函数使用ReadProcessMemory从一个外部程序读取我的游戏进行调试。
这是一项功能:
template<typename T>
T read(DWORD addy)
{
T buffer;
ReadProcessMemory(targetProcess, (LPVOID)addy, &buffer, sizeof(T), NULL);
assert(buffer != NULL);
return buffer;
}现在,我想阅读一个多级别指针,其中包含了几个取消引用,例如:
*(*(game.exe+0x12345)+0x50)+0x70我的目标是能够用我的模板函数做到这一点:
float data = read<float>(((game.exe+0x12345)+0x50)+0x70);没有取消引用,即使可能,也不使用括号。
我正在考虑使用参数pack作为模板,但我不确定它在我的情况下是否是最佳的。
如下所示:
template<typename T>
T retVal(T val){
return *val;
}
template<typename T, typename ...LvlsType>
T read(DWORD addy, LvlsType... levels){
T buffer;
ReadProcessMemory(targetProcess, (LPVOID)addy, &buffer, sizeof(T), NULL);
assert(buffer != NULL);
return retVal(...levels);
}在这种情况下这是正确的吗?
否则你们会有什么建议吗?
提前谢谢。
发布于 2020-07-10 19:48:47
DWORD addy应该是DWORD_PTR addy,甚至是void* addy。
而assert()是无用的。您需要检查ReadProcessMemory()的返回值。
无论如何,您都无法避免读取多个值。游戏有多个指针,你需要逐个阅读它们,并跟随地址,就像游戏一样。因此,您使用read<float>(((game.exe+0x12345)+0x50)+0x70);的尝试将不起作用。
您需要首先读取位于address game.exe+0x12345的指针值。然后,您需要将0x50添加到该值,并读取位于该地址的指针值。然后将0x70添加到该值并读取位于该地址的float。
你可以尝试更像这样的东西:
template<typename T>
T read(DWORD_PTR addy)
{
T buffer;
if (!ReadProcessMemory(targetProcess, (LPVOID)addy, &buffer, sizeof(T), NULL))
throw ...;
return buffer;
}
template<typename T, typename... OffsetTypes>
T read(DWORD_PTR addy, DWORD offset, OffsetTypes... offsets)
{
DWORD ptr = read<DWORD>(addy);
return read<T>(ptr + offset, offsets...);
}
...
DWORD_PTR baseAddr = ...; // base address of game.exe process
float data = read<float>(baseAddr+0x12345, 0x50, 0x70);DWORD ptr在read()的可变版本中的使用假设game.exe是32位EXE。如果它是64位EXE,则将DWORD ptr改为DWORD64 ptr,并确保将代码编译为64位,以便DWORD_PTR addy将是DWORD64,并能够到达所有可能的64位地址。
https://stackoverflow.com/questions/62839883
复制相似问题