Examples Delphi

How to list all memory pages allocated by all accesible processes
Create a form with a button and a treeview, name the treeview tvwProcessList. Name the button btnProcessList.
uses Windows;
procedure TForm1.btnProcessListClick(Sender: TObject);
var i,l:integer;
pid:THandle;
meminfo:MEMORY_BASIC_INFORMATION;
memstart:pointer;
memsize:Integer;
s,attr:String;
totuse:Integer;
lpMsgBuf : PCHAR;
pn, pidn, ln:TTreeNode;
begin
btnProcessList.Enabled := false;
tvwProcessList.Items.Clear;
pn:=tvwProcessList.Items.AddFirst (nil, 'This computer');
for i:=0 to 2000 do //
begin //PROCESS_QUERY_INFORMATION
pid:=OpenProcess (PROCESS_ALL_ACCESS{PROCESS_VM_OPERATION or PROCESS_QUERY_INFORMATION or PROCESS_VM_WRITE}, false, i*4);
if pid<>0 then
begin
//add treenode:
pidn := tvwProcessList.Items.AddChild (pn, IntToStr(i*4{pid}));
memstart := 0;
totuse := 0;
l:=VirtualQueryEx (pid,
memstart,
MemInfo,
SizeOf(MEMORY_BASIC_INFORMATION));
while (l=SizeOf(MEMORY_BASIC_INFORMATION)) do
begin
if Application.Terminated then
exit;
if meminfo.State=MEM_COMMIT then
begin
totuse := totuse+meminfo.RegionSize;
attr := '';
if (0<>meminfo.Protect and PAGE_NOACCESS) then
attr := attr+'NO ACCESS ';
if (0<>meminfo.Protect and PAGE_READONLY) then
attr := attr+'READONLY ';
if (0<>meminfo.Protect and PAGE_READWRITE) then
attr := attr+'READWRITE ';
if (0<>meminfo.Protect and PAGE_WRITECOPY) then
attr := attr+'WRITECOPY ';
if (0<>meminfo.Protect and PAGE_EXECUTE) then
attr := attr+'EXECUTE ';
if (0<>meminfo.Protect and PAGE_EXECUTE_READ) then
attr := attr+'EXECUTE_READ ';
if (0<>meminfo.Protect and PAGE_EXECUTE_READWRITE) then
attr := attr+'EXECUTE_READWRITE ';
if (0<>meminfo.Protect and PAGE_EXECUTE_WRITECOPY) then
attr := attr+'EXECUTE_WRITECOPY ';
if (0<>meminfo.Protect and PAGE_GUARD) then
attr := attr+'GUARD ';
if (0<>meminfo.Protect and PAGE_NOCACHE) then
attr := attr+'NOCACHE ';
ln := tvwProcessList.Items.AddChild (pidn,
Format ('Attr: %d: %s, Base: %d, size: %d',
[meminfo.protect, attr, integer(meminfo.BaseAddress), meminfo.RegionSize]));
Application.ProcessMessages;
end;
integer(memstart) := integer(meminfo.BaseAddress)+meminfo.regionsize;
integer(memstart):=integer(memstart)+memsize;
l:=VirtualQueryEx (pid,
memstart,
MemInfo,
SizeOf(MEMORY_BASIC_INFORMATION));
end;
pidn.Text := Format ('pid: %d, allocated: %d', [i*4, totuse]);
end;
CloseHandle(pid);
end;
btnProcessList.Enabled := true;
end;
Explanetion:
The windows process ID is always a multiply of 4. SO, accessing process nr. 8 will access the same process as handle 9,10 and 11.
We simply loop a list of possible ID's. There are better ways to do this, but that is outside the scope of this article, and this method works just fine.
IF we have openened a process, we list the first page. We add the size of this page to the start address of the next page to retrieve.
Not all pages are allocated, we can verify this with the MEM_COMMIT tag.
If a page is commited, we examine the attributes, and add a tree node.
This can take a while (especially adding all those tree nodes).
After we are finished, we close the processhandle with CloseHandle. Be very sure to do this!!! Not closing the handle will lead to funny results, and if you do this several times you may well end in having to reboot your system sincew everything gets slow.