转换"application's"内存地址
Converting "application's" memory address
所以我正在为微软的蜘蛛纸牌编写我的第一个培训师。首先,我需要对所有的内存地址进行逆向工程,直到找到一个静态地址。我使用了偏移,这样我就可以很容易地将它们恢复。
我发现了这个:
1000157F78 <-- starting value(never changes)
+ E8 <-- offsets to pointers
+ 14
002DC3D4 <-- final adress(changes every time)
这就是我的教练如何获得他的最终记忆地址:
DWORD FindFinalAddr(HANDLE hProc, BYTE offsets[], DWORD baseAddress, unsigned char pointerLevel)
{
DWORD pointer = baseAddress;
DWORD pTemp = 0;
DWORD pointerAddr = 0;
// set base address
ReadProcessMemory(hProc, (LPCVOID)pointer, &pTemp, (DWORD)sizeof(pTemp), NULL);
for (int c = 0; c < pointerLevel; c++)
{
pointerAddr = pTemp + (DWORD)offsets[c];
ReadProcessMemory(hProc, (LPCVOID)pointerAddr, &pTemp, (DWORD)sizeof(pTemp), NULL);
}
return pointerAddr;
}
在这种情况下,我(大致)这样做:FindFinalAddr(hProc, {0xE8, 0x14}, 0x1000157F78, 2);
当Spider Solitaire打开并且我刚刚找到静态值时,这很好。但当我关闭并重新打开它时,它就不再有效了。
我发现1000157F78
实际上是SpiderSolitaire.exe+B5F78
,它就像一个偏移。如果我在作弊引擎中输入这个,我会得到正确的内存地址,但我不能简单地在代码中输入。
现在我的问题是:如何将SpiderSolitaire.exe+B5F78
转换为正确的内存地址?
注意:SpiderSolitaire.exe是64位的。
编辑:我试过以下几种:
void * entryPoint = (void*) hProc;
DWORD base_addr = ((DWORD)(entryPoint) + 0xB5F78);
但这不起作用,因为入口点是5C
。它(在这个会话中)应该给出的地址是FF7A5F78
,但实际发生的是5C + B5F78 = B5F4D
。
我认为您可以使用GetModuleInformation查询加载地址,为模块句柄参数传递NULL
。如果这不起作用,您可以通过EnumProcessModules和GetModuleBaseName进行更长的路由。
经过长时间的研究,我找到了自己的答案!这段代码获取模块的基本地址(AKA入口点)(您需要包括TlHelp32.h和tchar.h):
DWORD getModuleBaseAddr(DWORD procId, TCHAR * lpszModuleName)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, procId);
DWORD moduleBaseAddr = 0;
if (hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 mentry32 = { 0 };
mentry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &mentry32))
{
do
{
if (_tcscmp(mentry32.szModule, lpszModuleName) == 0)
{
moduleBaseAddr = (DWORD)mentry32.modBaseAddr;
break;
}
} while (Module32Next(hSnapshot, &mentry32));
}
}
else
{
std::cout << "Error on finding module base address: " << GetLastError() << "n";
}
return moduleBaseAddr;
}
你给它pid和模块的名称(比如game.exe),然后它浏览模块并检查它们是否相同,然后它返回基本地址。
现在,我用蜘蛛纸牌测试了这个。它给了我一个错误。那是因为我编译的代码是32位的,SpiderSolitaire.exe是64位的,这是因为我的Windows7是64位。
因此,请确保您的代码与您的目标代码具有相同的平台目标!
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 使用内存地址访问结构的属性值
- 为什么C++总是显示十六进制内存地址,而不仅仅是整数?
- 将布局映射到内存地址
- 为什么同一个变量的内存地址不同?
- 无法将内存地址转换为值
- 给定特定内存地址的数组的动态内存分配
- 在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效
- 获取 R 数据帧的内存地址
- c++ 编译器是否保护常量内存地址免受任何更改?
- 如何防止矢量的内存地址更改
- cout 打印内存地址而不是值
- 如何运行外部程序,向其传递内存地址以读取/写入?
- 循环中的变量被设置为下一个数组的元素始终具有相同的内存地址?
- 重载 ostream << 运算符,指针作为参数,导致输出上的内存地址
- C++在变量的内存地址上做什么来"deallocate"它?
- 在指向现有内存地址的 hpp 文件中声明成员函数的最佳方法
- 为什么我无法获取 MSVS2019 / C++ 中字符或uint8_t变量的内存地址?