【发布时间】:2020-08-29 19:37:37
【问题描述】:
我一直在尝试仅读取进程范围内的所有内存地址(请参阅问题:C++ read memory addresses within process range only)。我成功地从记忆中读取,并且似乎我收到了正确的baseaddress 用于该过程。我遇到的问题是找到我认为程序会有的特定值。
例如,如果我玩了一个游戏,分数 500,我想在内存中找到 500。我遍历了所有地址,但找不到值。所以我决定阅读我自己的程序(它是 64 位的)并将值设置为 500,打印它的地址并手动搜索,看看是否找到它。
int number = 500;
std::cout << &number;
由于某种原因,它写入的地址超出了进程范围。
我计算地址范围:
uintptr_t moduleBase = GetModuleBaseAddress(procId, L"x.exe");
uintptr_t moduleSize = GetModuleSize(procId, L"x.exe");
// Set base and last address and print them for user
uintptr_t dynamicPtrBaseAddr = moduleBase;
uintptr_t dynamicPtrLastAddr = (moduleBase + moduleSize);
使用的方法:
uintptr_t GetModuleSize(DWORD procId, const wchar_t* modName) {
uintptr_t modBaseSize = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | 0x10, procId);
if(hSnap != INVALID_HANDLE_VALUE) {
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if(Module32First(hSnap, &modEntry)) {
do {
if(!_wcsicmp(modEntry.szModule, modName)) {
modBaseSize = (uintptr_t)modEntry.modBaseSize;
break;
}
} while(Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseSize;
}
和
uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName) {
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | 0x10, procId);
if(hSnap != INVALID_HANDLE_VALUE) {
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if(Module32First(hSnap, &modEntry)) {
do {
if(!_wcsicmp(modEntry.szModule, modName)) {
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while(Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
由于number 的值超出范围,我认为GetModuleSize 可能不正确。
我的最后一个地址是:0x4F4628,
std::cout << &number; 给我0x6DFDD4
我的问题是:
- GetModuleSize 是不是计算最后一个地址的不正确方法 应用程序?如果是这样,我可以更正吗?
- 通过将最后一个地址乘以 2,我能够读取该值
的
&number。这是因为 modulesize 给了我一个 32 位的范围,还是给我的地址超出了进程的范围?
我编译时使用:g++ main.cpp -o x -lpsapi -DUNICODE -m64,并且必须将 libgcc_s_seh-1.dll 添加到我的路径中才能运行我的程序。
我在github上的整个项目:https://github.com/Darclander/memory-reading
(不确定将整个代码发布在这里是否更好)。
【问题讨论】: