TR3M4
TR3M4

Reputation: 3

Scan memory (C++)

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

Answers (2)

TR3M4
TR3M4

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

light_keeper
light_keeper

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

Related Questions