Reputation: 3
I got a function that scans memory for a byte array ( XX ? XX XX XX etc).
My code is fine for windows 7 but ends up getting an ACCESS_VIOLATION on windows 10 as memory doesn't seem to work the same way as it does on windows 7.
My issue is that I need to start scanning before the address that GetModuleHandle(0) returns as the byte array I'm searching for gets loaded in memory while the game(64 bits) is loading.
How can I get where does memory starts on the game or verify if lpCurrentByte is in memory?
static DWORD64 ScanC(DWORD64 dwLength, std::string s) {
std::vector<PatternByte> p;
std::istringstream iss(s);
std::string w;
while (iss >> w) {
if (w.data()[0] == '?') { // Wildcard
p.push_back(PatternByte());
}
else if (w.length() == 2 && isxdigit(w.data()[0]) && isxdigit(w.data()[1])) { // Hex
p.push_back(PatternByte(w));
}
else {
return NULL;
}
}
for (DWORD64 i = 0; i < dwLength; i++) {
UINT8* lpCurrentByte = (UINT8*)(0x10000000 + i);
bool found = true;
for (size_t ps = 0; ps < p.size(); ps++) {//Sa plante la
if (p[ps].ignore == false && lpCurrentByte[ps] != p[ps].data) {
found = false;
break;
}
}
if (found) {
return (DWORD64)lpCurrentByte;
}
}
return NULL;
}
Upvotes: 0
Views: 1258
Reputation: 3
I'm posting an answer since I can't seem to edit my post(Every character I type in gets rolled back). I also forgot to mention that I'm running this code internally(From an injected dll)
I tried the following function(Using VirtualQuery as light_keeer suggested).
It does work, but the address I'm scanning for isn't always in the first "memory region" that my code detects and I can't seem to figure out how to get the other ones, everything I try either returns me in memory returning ACCESS_VIOLATION when I read it or returning me in the middle of a memory region that I can read(Not at the beggining of it).
DWORD WINAPI GetFirstAddressInMemory(LPVOID lpParam){
DWORD64 memoryRegionStart = 0x0000010000000000;
DWORD64 memoryRegionEnd = 0x7fffffffffffffff;
MEMORY_BASIC_INFORMATION mBI;
for (DWORD64 addr = memoryRegionStart; addr < memoryRegionEnd; addr += 0x200000){//Big increment otherwise it takes ages to load
if (VirtualQuery((void*)addr, &mBI, sizeof(MEMORY_BASIC_INFORMATION))){
if (mBI.State == MEM_COMMIT) {
printf("Address at %p (%p)\n", addr, mBI.BaseAddress);
printf("Next region: %p\n", (DWORD64)mBI.BaseAddress + mBI.RegionSize);
Pattern::ScanC(addr, memoryRegionEnd, "XX XX XX ? XX");//ends up crashing while reading memory
break;
}
}
}
return 0;
}
Upvotes: 0
Reputation: 647
Process does not load its assets sequentially, different dlls and heaps are loaded where OS find it appropriate, address space is fragmented. You should not use any exact address because it can change from run to run.
Use VirtualQueryEx instead. I don't have appropriate code now, but you can find usage example here.
Upvotes: 1