I have been trying to read all memory addresses within a process range only, (see question: C++ read memory addresses within process range only). I succeeded with reading from memory and it seems like I received the correct baseaddress
for the process. The problem I was having was to find specific values which I assumed the program would have.
For example if I played a game and had the score 500, I wanted to find 500 in the memory. I stepped through all the addresses but could not find the value. So I decided to read my own program (which is 64-bit) and set a value to 500, print its address and manually search and see if I found it.
int number = 500;
std::cout << &number;
For some reason the address it was written to was out of bounds of the process range.
I calculate the address range with:
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);
Methods used:
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;
}
and
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;
}
Since the value of number
is written out of bounds I assume that GetModuleSize
, might be incorrect.
Last address for me is: 0x4F4628
,
std::cout << &number;
gives me 0x6DFDD4
My questions are:
- Is GetModuleSize an incorrect way of calculating the last address for the application? If so, can I correct it?
- By multiplying the last address with 2, I was able to read the value
of
&number
. Is this because modulesize gives me a 32-bit range or is this giving me addresses out of bounds for the process?
I compile with: g++ main.cpp -o x -lpsapi -DUNICODE -m64
, and had to add libgcc_s_seh-1.dll
to my path in order to run my program.
My entire project on github: https://github.com/Darclander/memory-reading
(Not sure if it is better for me to post the entire code on here).