Delphi获取进程内存范围

时间:2013-12-12 17:30:20

标签: delphi memory process range

我想在delphi中获取所有内存,但它不起作用。 程序进入无限循环,并始终显示“00000000 - 00000000”。 我希望程序输出基地址和区域zise。 这是代码:

program dtest;
{$APPTYPE CONSOLE}


uses
  Windows,
  TLHelp32,
  SysUtils;

var
Snap: dword;
sysinfo : TSystemInfo;
Process: TPROCESSENTRY32;
Handle: THandle;
Mbi: TMemoryBasicInformation;
Addr: DWORD;
begin
   GetSystemInfo(sysinfo);
   Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   if Snap <> INVALID_HANDLE_VALUE then
   begin
   Process.dwSize := SizeOf(TPROCESSENTRY32);
   if Process32First(Snap, Process) then
   repeat
      Handle:=OpenProcess(PROCESS_VM_READ,false,Process.th32ProcessID);
      if Handle <> 0 then
      begin
         writeln(Process.szExeFile);
         Addr := DWORD(sysinfo.lpMinimumApplicationAddress);
         while (Addr < $80000000) do
         begin
             VirtualQueryEx(Handle, Ptr(Addr), Mbi, SizeOf(Mbi));
             write(inttohex(Integer(Mbi.BaseAddress), 8));
             write(Output,' - ');
             writeln(inttohex(Integer(Mbi.RegionSize), 8));
             Addr := Addr + Mbi.RegionSize;
         end;
         CloseHandle(Handle)
      end
   until not Process32Next(Snap, Process);
   CloseHandle(Snap);
   end;
   Sleep(9999);
end
.

1 个答案:

答案 0 :(得分:3)

您通过VirtualQueryEx的{​​{1}}的第一次通话失败。您没有执行错误检查。该文档指出nil失败时返回0。这就是发生的事情。

在这种情况下,从对VirtualQueryEx的调用中检索到的Win32错误代码为GetLastError。不足为奇。

现在,当发生这种情况时,ERROR_ACCESS_DENIED中的值定义不明确。碰巧,MbiRegionSize,因此您进入无限循环。

没有必要将0增加任何小于单个页面大小的内容。所以我建议当Addr失败时,你就是这样做的。

现在,另一个主要问题是您没有仔细阅读文档。它告诉您进程句柄必须包含VirtualQueryEx。你没有提供那面旗帜。显然你需要这样做。

并且您还需要注意具有区域大小的页面,这些页面意味着它们超出了地址空间的末尾。我不是专家,但我认为这些标志着地址空间的顶端。当你遇到这些时,你需要摆脱循环。

最后,我想指出,只需在调试器下运行程序就可以轻松找到所有这些。你有一个无限循环。因此,研究调试器下的程序,找出循环没有终止的原因。它将为您学习如何使用调试工具带来好处。哦,阅读文档,并在调用Win32 API函数时始终检查错误也很重要!

这个版本的程序更好,但我甚至没有远程调试它。你需要对它进行改进:

PROCESS_QUERY_INFORMATION