进程的读取进程内存不会返回所有内容

Read process memory of a process does not return everything

本文关键字:返回 读取 取进程 内存 进程      更新时间:2023-10-16

我正在尝试扫描第三方应用程序的内存。我已经找到了地址;现在在0x0643FB78.问题是,我永远无法到达那里,因为LPMODULEENTRY32->modBaseAddr0x00400000LPMODULEENTRY32->modBaseSize只是0x006FF000,因此我可以扫描此模块的最大地址是0x00AFF000

这是否意味着我寻找的地址确实存在于另一个进程/模块/线程/某物中?不过,我很有信心我拥有的过程确实包含地址。那么我应该如何访问内存呢?谢谢。

至少在我看来

,如果你涉及LPMODULEENTRY,你可能开始了错误的方向。我会用VirtualQueryEx遍历目标进程中的内存块。这将为您提供有关该过程中的每个块的MEMORY_BASIC_INFORMATION。然后,您可以使用ReadProcessMemory并扫描块以查找所需的内容。

以下是我编写的一些旧代码,用于执行大致相同的操作,但要查找字符串而不是指针:

#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;
}

进程由内存页组成,这些内存页映射了某些保护。这些页面封装在模块中。每个模块都有一个基础和一个大小。但是,ReadProcessMemory完全将其从您抽象出来。您应该能够读取内存,无论它位于哪个模块中。

在这种情况下,内存不在您正在查看的模块中。如果你确实需要找到它所属的位置,你可以使用CreateToolHelp32Snapshot,Module32First和Module32Next循环访问模块,检查基础和大小。

发布一些代码,我们可以帮助您找出出错的地方。为什么你这么确定你要找的地址就是你说的地址?由于 ASLR,地址通常使用基本模块 + 偏移量指定。您如何获取目标进程句柄?您需要具有某些访问权限才能使用 ReadProcessMemory。