问题
So I have been trying to get into memory reading in C++ and I thought a cool project would be to read all addresses a process is using (similar to how Cheat Engine works).
I started by reading
Link1: Read Memory of Process C++
Link2: Read memory of 64bit process address
Link3: http://www.cplusplus.com/forum/general/42132/
And I also watched a tutorial on youtube where he explained how a process (game) worked with addresses. Link to youtube video: https://www.youtube.com/watch?v=wiX5LmdD5yk
This resulted in me making three different methods:
DWORD GetProcId(const wchar_t* procName) {
DWORD pid = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hSnap != INVALID_HANDLE_VALUE) {
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if(Process32First(hSnap, &procEntry)) {
do {
if(!_wcsicmp(procEntry.szExeFile, procName)) {
pid = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return pid;
}
This method is to get the process-id which I could also just type manually by finding the same PID in task-manager (which gave me the same baseaddress later on).
uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName) {
uintptr_t modBaseAddr = 0;
//I use 0x10 instead of TH32CS_SNAPMODULE32 since it didnt work and according to documentation
// this is the value it should have.
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;
}
This method (I assume) will return the base address of the process. Which for example in my code I tried to find the base address of the discord.exe process. When discord.exe wasn't running I got 0 and when it was running I got an address (which I believe is the correct base address, correct me if I am wrong).
And my main
method:
int main() {
DWORD procId = GetProcId(L"Discord.exe");
uintptr_t moduleBase = GetModuleBaseAddress(procId, L"Discord.exe");
HANDLE hProcess = 0;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, procId);
uintptr_t dynamicPtrBaseAddr = moduleBase;
std::cout << "Dynamic: " << dynamicPtrBaseAddr << std::endl;
int value = 0;
int arr [10000] = {};
for (int i = 0; i < 100000; i++) {
ReadProcessMemory(hProcess, (BYTE*)dynamicPtrBaseAddr, &value, sizeof(value),0);
dynamicPtrBaseAddr += 1;
arr[i] = value;
}
}
Where I try to put all the values of all 100000 addresses in an array.
So my questions are:
- Have I retrieved the base address of the process correctly?
- For reading the other addresses I just increase dynamicPtrBaseAddr by 1, is there a better way to implement an offset? Or is this the correct way?
- Now I increase the base address by 100000. Can I find the last address of the process instead?
I compile with g++ main.cpp -o test -lpsapi -DUNICODE
(MinGW).
回答1:
You must run as administrator and you must compile for the same bitness as the target process.
You should not be reading 1 byte at a time, especially in an external hack.
You should be using VirtualQueryEx() to properly loop through only proper memory regions:
DWORD procid = GetProcId("ac_client.exe");
unsigned char* addr = 0;
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procid);
MEMORY_BASIC_INFORMATION mbi;
while (VirtualQueryEx(hProc, addr, &mbi, sizeof(mbi)))
{
if (mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS && mbi.Protect != PAGE_GUARD)
{
std::cout << "base : 0x" << std::hex << mbi.BaseAddress << " end : 0x" << std::hex << (uintptr_t)mbi.BaseAddress + mbi.RegionSize << "\n";
}
addr += mbi.RegionSize;
}
This ensures you're only reading proper memory. Next you would reach each region into a local buffer in one go, this will increase speed dramatically as you won't have the overhead of calling the API for each byte.
What you're looks like you're trying to do is pattern scanning. You can find our pattern scanning tutorials in the same place you found the original tutorial you were following.
来源:https://stackoverflow.com/questions/61419055/c-read-memory-addresses-within-process-range-only