Read process memory of a process does not return everything
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;
}
A process consists of pages of memory which are mapped with certain protections. These pages are encapsulated in modules. Each module has a base and a size. However, ReadProcessMemory abstracts this from you completely. You should be able to read memory regardless of what module it is in.
In this case, the memory is not in the module you are looking at. If you do need to find where it belongs, you can iterate through the modules checking base and size with CreateToolHelp32Snapshot, Module32First and Module32Next.
Post some code and we can help you find out where you've gone wrong. Why are you so sure the address of what you are looking for is the address you state? Addresses are often specified with a base module + offset because of ASLR. How are you getting the target process handle? You need to have certain access rights to use ReadProcessMemory.