VirtualQueryEx unable to read memory, so can’t dereference pointer (LPCVOID/uint8_t*)

  c++, memory, winapi

I have a function to read the memory of an application

template<class T>
std::unordered_map<uint8_t, T> find_byte(T find) {
    std::cout << "Searching for valuen";

    std::unordered_map<uint8_t, T> mapping;

    // Turn the T bytes to a vector to use nice C++ functions
    std::vector<uint8_t> byte_check;
    if constexpr (std::is_same_v<T, std::string>) {
        byte_check = std::vector<uint8_t>(find.begin(), find.end());
    }
    else {
        uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(&find));
        byte_check    = std::vector<uint8_t>(data, data + sizeof(find));
    }

    MEMORY_BASIC_INFORMATION info;
    for (uint8_t* addr = nullptr; VirtualQueryEx(m_proc, addr, &info, sizeof(info)) == sizeof(info); addr += info.RegionSize) {
        if (info.State == MEM_COMMIT && (info.Type == MEM_MAPPED || info.Type == MEM_PRIVATE)) {
            size_t read{};
            std::vector<uint8_t> mem_chunk;
            mem_chunk.resize(info.RegionSize);
            if (ReadProcessMemory(m_proc, addr, mem_chunk.data(), mem_chunk.size(), &read)) {
                mem_chunk.resize(read);
                for (auto pos = mem_chunk.begin();
                     mem_chunk.end() != (pos = std::search(pos, mem_chunk.end(), byte_check.begin(), byte_check.end()));
                     pos++) {
                    uint8_t* int_addr_ptr  = (addr + (pos - mem_chunk.begin()));
                    mapping[*int_addr_ptr] = find;
                }
            }
        }
    }
    return mapping;
}

It compiles just fine, however, it crashes it tries to dereference the int_addr_ptr pointer.
After stepping through with a debugger, I noticed that the addr returned from VirtualQueryEx was unable to be read.

I assume the issue lies in how I dereference, but I don’t know how to fix it.
I have tired:

auto lpcvoid       = (addr + (pos - mem_chunk.begin()));
auto int_addr_ptr = reinterpret_cast<const uint8_t*>(lpcvoid);

from here, but it yielded no results.

I want to note that if I return a map of <uint8_t, T> it works fine, but wanted to avoid the pointers

Source: Windows Questions C++

LEAVE A COMMENT