-1

我注意到,如果我尝试使用 ReadProcessMemory 读取整个过程,则需要很长时间。但是,在执行 MiniDumpWriteDump 时,它会在大约 1 秒内发生。

同样由于某种原因,在执行 ReadProcessMemory 而 MiniDumpWriteDump 没有尝试存储整个进程时,字节数组会损坏。

唯一的问题是,在执行 MiniDumpWriteDump 时,我无法匹配 Cheat Engine 之类的地址/值。例如,执行字节数组搜索会返回不同的地址。

MiniDumpWriteDump(pHandle, procID, fsToDump.SafeFileHandle.DangerousGetHandle(), 0x00000002, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

ReadProcessMemory(pHandle, (UIntPtr)0, test, (UIntPtr)procs.PrivateMemorySize, IntPtr.Zero);

ReadProcessMemory 长度 = 597577728

转储长度 = 372053153

4

1 回答 1

0

如果我尝试使用 ReadProcessMemory 读取整个过程,则需要很长时间。

MiniDumpWriteDump 速度很快,因为它是我自己的 Microsoft 编写的高度优化的函数。

通过使用带有有限数量通配符的 VirtualQueryEx() 检查页面保护类型和状态的正确模式扫描功能不会超过 10 秒,并且在大多数情况下会不到 2 秒。

这是 C++ 代码,但 C# 中的逻辑相同

#include <iostream>
#include <windows.h>

int main()
{
    MEMORY_BASIC_INFORMATION meminfo;
    char* addr = 0;

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

    MEMORY_BASIC_INFORMATION mbi;

    char buffer[0x1000];

    while (VirtualQueryEx(hProc, addr, &mbi, sizeof(mbi)))
    {
        if (mbi.State != MEM_COMMIT || mbi.Protect == PAGE_NOACCESS)
        {
            char* buffer = new char[mbi.RegionSize];

            ReadProcessMemory(hProc, addr, buffer, mbi.RegionSize, nullptr);
        }
        addr += mbi.RegionSize;
    }

    CloseHandle(hProc);
}

注意我们检查 MEM_COMMIT,如果内存没有被提交,那么它是无效的。同样,如果保护是 PAGE_NOACCESS,我们也会丢弃该内存。这种简单的技术将只产生值得扫描的适当内存,从而实现快速扫描。将每个部分读入本地缓冲区后,您可以针对它运行模式扫描代码。最后,只需解析从区域开头到目标进程中绝对地址的偏移量。

于 2020-04-18T03:27:20.403 回答