内存扫描程序始终返回相同的结果

pau*_*ohr 1 memory delphi

使用此代码,我猜扫描更快,但扫描始终返回SAME地址.

例如:

00123456
00124567
00135478
00145893
00123456 //start repeat 
00124567
00135478
00145893
00123456 //start repeat 
00124567
00135478
00145893
Run Code Online (Sandbox Code Playgroud)

这是我的程序:

procedure SCANBYTE(value: integer);
var
 lpflOldProtect: dword;
 s: size_t;
 mbi: MEMORY_BASIC_INFORMATION;
 SI: SYSTEM_INFO;
 lpStartAddress, lpStopAddress: dword;
 addr: dword;
 i: dword;
begin
 GetSystemInfo(si);
 lpStartAddress := dword(SI.lpMinimumApplicationAddress);
 lpStopAddress := dword(SI.lpMaximumApplicationAddress);
 for addr := lpStartAddress to lpStopAddress do begin
  S:= VirtualQuery(Pointer(addr), MBI, SizeOf(MEMORY_BASIC_INFORMATION));
  if (S=SizeOf(MEMORY_BASIC_INFORMATION)) and (MBI.State = MEM_COMMIT) and (MBI.Type_9 = MEM_PRIVATE) and (MBI.RegionSize>0) and (MBI.Protect = PAGE_READWRITE) then begin
   for i := dword(MBI.BaseAddress) to (dword(MBI.BaseAddress) + dword(MBI.RegionSize)) - 4096 do begin
     if value = PBYTE(i)^ then ListBox1.Items.Add(IntToHex(i,8));
   end;
  end;
 end;
end;
Run Code Online (Sandbox Code Playgroud)

我猜问题是在最后一个FOR循环:

(...)
for i := dword(MBI.BaseAddress) to (dword(MBI.BaseAddress) + dword(MBI.RegionSize)) - 4096 do begin
(...)
Run Code Online (Sandbox Code Playgroud)

但我真的不知道..我怎么解决这个问题?

Rob*_*edy 8

您可以在从起始地址到结束地址的循环中运行代码.循环周围的地址每次addr增加1.VirtualQuery为您提供有关整个页面的信息.页面中的所有地址都具有相同的基址.文档告诉您,"此值向下舍入到下一页边界."

仔细观察,您应该看到mbi.BaseAddress外循环的4096次迭代保持不变(假设页面大小为4096).因此,您将一遍又一遍地重新扫描同一块内存.(这也可能解释了为什么你的代码很慢.)