我可以使用 ReadProcessMemory 在 Windows 中读取进程的程序内存吗?

Posted

技术标签:

【中文标题】我可以使用 ReadProcessMemory 在 Windows 中读取进程的程序内存吗?【英文标题】:Can I use ReadProcessMemory to read program memory of a process in windows? 【发布时间】:2015-03-05 16:25:20 【问题描述】:

我有这个线程在我的程序进程中运行。该线程应该读取该进程的程序内存以检测是否发生了任何禁止的代码注入。现在如何访问进程的程序内存?我可以使用

ReadProcessMemory();

函数,如果我获得带有 ALL_ACCESS 标志的进程句柄,则读取程序内存? 还有一种方法可以搜索这个程序内存,我可以限制这个内存扫描到几个特定的​​感兴趣的方法或检测特定方法的基地址和长度?

【问题讨论】:

那是为了读取另一个进程。您不需要任何 API 来读取您自己的内存。当代码在 Windows 中已经是只读时,很难看出这一点。 @EJP 哦,你是对的。 @EJP 你知道如何在进程中定位程序内存吗?求好奇心。 您可以使用 VirtualQueryEx 枚举进程地址空间 - 在您的情况下,您将寻找可执行的部分。 你可以只使用函数地址。 【参考方案1】:

是的,如果您获得具有 READ 权限的进程句柄(包含在 PROCESS_ALL_ACCESS 中),您可以使用 ReadProcessMemory() 来读取目标进程的内存。

您要执行的操作称为模式扫描。首先,您将使用 VirtualQueryEx() 查找以 MEM_COMMIT 作为状态并且没有 PAGE_NOACCESS 或 PAGE_GUARD 作为保护类型的内存区域。

您使用模式扫描功能遍历这些内存区域以查找您想要列入黑名单的特定签名。

这是循环内存的基本思路

int main()

    DWORD procid = GetProcId("whatever.exe");

    MEMORY_BASIC_INFORMATION meminfo;
    unsigned char* addr = 0;

    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procid);

    MEMORY_BASIC_INFORMATION mbi;

    while (VirtualQueryEx(hProc, addr, &mbi, sizeof(mbi)))
    
        if (mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS)
        
            std::cout << "base : 0x" << std::hex << mbi.BaseAddress << " end : 0x" << std::hex << (uintptr_t)mbi.BaseAddress + mbi.RegionSize << "\n";
        
        addr += mbi.RegionSize;
    

    CloseHandle(hProc);

您可以从这里找到许多不同的图案扫描功能来完成这项工作。

【讨论】:

以上是关于我可以使用 ReadProcessMemory 在 Windows 中读取进程的程序内存吗?的主要内容,如果未能解决你的问题,请参考以下文章

ReadProcessMemory WriteProcessMemory iOS

ReadProcessMemory 在某些页面上失败 (GetLastError()=299)

使用 ReadProcessMemory 获取字符串值的访问冲突

如何使用 ReadProcessMemory 获取托盘按钮文本

ReadProcessMemory 总是读取 0

Win32 ReadProcessMemory API 的问题