我想在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
.
答案 0 :(得分:3)
您通过VirtualQueryEx
的{{1}}的第一次通话失败。您没有执行错误检查。该文档指出nil
失败时返回0。这就是发生的事情。
在这种情况下,从对VirtualQueryEx
的调用中检索到的Win32错误代码为GetLastError
。不足为奇。
现在,当发生这种情况时,ERROR_ACCESS_DENIED
中的值定义不明确。碰巧,Mbi
为RegionSize
,因此您进入无限循环。
没有必要将0
增加任何小于单个页面大小的内容。所以我建议当Addr
失败时,你就是这样做的。
现在,另一个主要问题是您没有仔细阅读文档。它告诉您进程句柄必须包含VirtualQueryEx
。你没有提供那面旗帜。显然你需要这样做。
并且您还需要注意具有区域大小的页面,这些页面意味着它们超出了地址空间的末尾。我不是专家,但我认为这些标志着地址空间的顶端。当你遇到这些时,你需要摆脱循环。
最后,我想指出,只需在调试器下运行程序就可以轻松找到所有这些。你有一个无限循环。因此,研究调试器下的程序,找出循环没有终止的原因。它将为您学习如何使用调试工具带来好处。哦,阅读文档,并在调用Win32 API函数时始终检查错误也很重要!
这个版本的程序更好,但我甚至没有远程调试它。你需要对它进行改进:
PROCESS_QUERY_INFORMATION