I am trying to write a process memory scanner that scans for nonzero values in the memory:
MEMORY_BASIC_INFORMATION mbi;
char* addr = 0;
dtype readVal = 0;
while (VirtualQueryEx(hProc, addr, &mbi, sizeof(mbi))) { // HANDLE hProc is defined earlier
if (mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS) {
for (int i = 0; i < mbi.RegionSize; i += sizeof(readVal)) {
BOOL ret = ReadProcessMemory(hProc, (char*) mbi.BaseAddress + i, &readVal, sizeof(readVal), 0);
printf("ReadProcessMemory returns %d\n", ret); // returns 5 (ERROR_ACCESS_DENIED)
if (readVal != 0) {
printf("Found a good value!");
system("pause");
}
}
}
addr += mbi.RegionSize;
}
I tried it on chrome.exe and the scanner found a ton of nonzero values. But when I tried it on a game process that comes with an anticheat it fails to work, ReadProcessMemory returns ERROR_ACCESS_DENIED in each call of ReadProcessMemory. The handle hProc had no problem attaching to the game process and the correct PID was found. Why is that and how can we increase our privilege to bypass the anticheat?
A trimmed down version of your code does approximately this:
There's a (probably) uninitialized value (
readVal), some code with a code path that doesn't alter the value, followed by a read access. Doing so has no specified behavior. Its behavior is thus implied to be undefined.To fix your code you'll need to make two changes:
readValneeds to be initialized, and reset in the innermost loop. Though without knowing what data typereadValis, it's impossible to know whether it is or isn't initialized. That's left as an exercise.FALSE. You will need to check for failure, and optionally call GetLastError if you need extended error information.We don't know, since you decided to keep vital information private (e.g. the specific name and version of the target). Bypassing software protection is designed to be difficult. Spend a decade in binary exploitation and you might be prepared to come up with a way. Not something Stack Overflow can help you with.