Read process memory of a process does not return everything

c++, memory, readprocessmemory, winapi, windows

Solution

At least in my opinion, if you have an `LPMODULEENTRY` involved, you're probably starting in the wrong direction. I'd walk through the blocks of memory in the target process with `VirtualQueryEx` instead. This will give you a `MEMORY_BASIC_INFORMATION` about each block in that process. You can then use `ReadProcessMemory` and scan through the blocks to find what you're looking for.

Here's some old code I wrote to do roughly the same thing, but looking for a string rather than a pointer:

#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
#include <algorithm>
#include <iterator>

template <class InIter1, class InIter2, class OutIter>
void find_all(unsigned char *base, InIter1 buf_start, InIter1 buf_end, InIter2 pat_start, InIter2 pat_end, OutIter res) {
    for (InIter1 pos = buf_start;
        buf_end!=(pos=std::search(pos, buf_end, pat_start, pat_end));
        ++pos)
    {
        *res++ = base+(pos-buf_start);
    }
}

template <class outIter>
void find_locs(HANDLE process, std::string const &pattern, outIter output) {

    unsigned char *p = NULL;
    MEMORY_BASIC_INFORMATION info;

    for ( p = NULL;
        VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info);
        p += info.RegionSize ) 
    {
        std::vector<char> buffer;

        if (info.State == MEM_COMMIT && 
            (info.Type == MEM_MAPPED || info.Type == MEM_PRIVATE)) 
        {
            SIZE_T bytes_read;
            buffer.resize(info.RegionSize);
            ReadProcessMemory(process, p, &buffer[0], info.RegionSize, &bytes_read);
            buffer.resize(bytes_read);
            find_all(p, buffer.begin(), buffer.end(), pattern.begin(), pattern.end(), output);
        }
    }
}

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <process ID> <pattern>", argv[0]);
        return 1;
    }

    int pid;
    sscanf(argv[1], "%i", &pid);

    std::string pattern(argv[2]);

    HANDLE process = OpenProcess( 
        PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 
        false,
        pid);

    find_locs(process, pattern, 
        std::ostream_iterator<void *>(std::cout, "\n"));

    return 0;
}

Problem

I am trying to scan memory of a 3rd party application. I have already found out the address; right now is at `0x0643FB78`. The thing is, I can never get up there since `LPMODULEENTRY32->modBaseAddr` is `0x00400000` and `LPMODULEENTRY32->modBaseSize` is merely `0x006FF000`, thus the max address I can scan for this module is `0x00AFF000`. Does that mean the address I seek does live inside another process/module/thread/something? I am quite confident the process I have does contain the address though. How should I access the memory then? Thank you.

Original source