我注意到,如果我尝试使用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
答案 0 :(得分:0)
如果我尝试使用ReadProcessMemory读取整个过程,则会花费很长时间。
MiniDumpWriteDump速度很快,因为它是我自己编写的高度优化的函数。
通过使用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,我们也将丢弃该内存。这种简单的技术只会产生值得扫描的适当内存,从而实现快速扫描。将每个部分读入本地缓冲区后,您可以对此运行模式扫描代码。最后,只需解决目标进程中从区域开头到绝对地址的偏移量即可。