Collecting Memory Usage Information For a Process To determine the efficiency of your application, you may want to examine its memory usage. The following sample code uses the GetProcessMemoryInfo function to obtain information about the memory usage of a process. #include <windows.h> #include <stdio.h> #include "psapi.h"void PrintMemoryInfo( DWORD processID ) { HANDLE hProcess; PROCESS_MEMORY_COUNTERS pmc; // Print the process identifier. printf( "\nProcess ID: %u\n", processID ); // Print information about the memory usage of the process. hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) { printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount ); printf( "\tPeakWorkingSetSize: 0x%08X\n", pmc.PeakWorkingSetSize ); printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize ); printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n", pmc.QuotaPeakPagedPoolUsage ); printf( "\tQuotaPagedPoolUsage: 0x%08X\n", pmc.QuotaPagedPoolUsage ); printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n", pmc.QuotaPeakNonPagedPoolUsage ); printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n", pmc.QuotaNonPagedPoolUsage ); printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage ); printf( "\tPeakPagefileUsage: 0x%08X\n", pmc.PeakPagefileUsage ); } CloseHandle( hProcess ); }void main( ) { // Get the list of process identifiers. DWORD aProcesses[1024], cbNeeded, cProcesses; unsigned int i; if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return; // Calculate how many process identifiers were returned. cProcesses = cbNeeded / sizeof(DWORD); // Print the memory usage for each process for ( i = 0; i < cProcesses; i++ ) PrintMemoryInfo( aProcesses[i] ); } The main function obtains a list of processes by using the EnumProcesses function. For each process, main calls the PrintMemoryInfo function, passing the process identifier. PrintMemoryInfo in turn calls the OpenProcess function to obtain the process handle. If OpenProcess fails, the output shows only the process identifier. For example, OpenProcess fails for the Idle and CSRSS processes because their access restrictions prevent user-level code from opening them. Finally, PrintMemoryInfo calls the GetProcessMemoryInfo function to obtain the memory usage information.
//你要是再不给分就对不住我了:) unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, te_controls, ComCtrls, dxtree, ImgList, Menus, psapi;type TForm1 = class(TForm) Button2: TButton; Memo1: TMemo; procedure Button2Click(Sender: TObject); private procedure PrintMemoryInfo(processID: DWORD); public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm} procedure TForm1.PrintMemoryInfo(processID: DWORD); var hProcess: THandle; pmc: PROCESS_MEMORY_COUNTERS; begin // Print the process identifier. Memo1.Lines.Add('Process ID: ' + IntToStr(processID )); // Print information about the memory usage of the process. hProcess := OpenProcess( PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, processID ); if ( GetProcessMemoryInfo( hProcess, @pmc, sizeof(pmc)) )then begin Memo1.Lines.Add(#9 + FloatToStr(pmc.PageFaultCount) ); Memo1.Lines.Add(#9 + FloatToStr(pmc.PeakWorkingSetSize) ); Memo1.Lines.Add(#9 + FloatToStr(pmc.QuotaPeakPagedPoolUsage) ); Memo1.Lines.Add(#9 + FloatToStr(pmc.QuotaPagedPoolUsage) ); Memo1.Lines.Add(#9 + FloatToStr(pmc.QuotaPeakNonPagedPoolUsage) ); Memo1.Lines.Add(#9 + FloatToStr(pmc.QuotaNonPagedPoolUsage) ); Memo1.Lines.Add(#9 + FloatToStr(pmc.PagefileUsage) ); Memo1.Lines.Add(#9 + FloatToStr(pmc.PeakPagefileUsage) ); end; CloseHandle( hProcess ); end;procedure TForm1.Button2Click(Sender: TObject); var cbNeeded, cProcesses: DWORD; aProcesses: array [0..1023] of DWORD; I: UINT; begin // Get the list of process identifiers. if not EnumProcesses(@aProcesses, sizeof(aProcesses), cbNeeded ) then Exit; // Calculate how many process identifiers were returned. cProcesses := cbNeeded div sizeof(DWORD); // Print the memory usage for each process for i := 0 to cProcesses - 1 do PrintMemoryInfo( aProcesses[i] );end;end.
那我就现丑了 ^_^是这样,很简单。我以前写了一个游戏修改工具,就是遍历内存地址空间,找到目标地址,然后写入数据。while longword(p)<$80000000)do begin //指针小于 2G if (x<>VirtualQueryEx(Handle_Share,p,mi,x)) then break; //调用VirtualQueryEx if (mi.State = MEM_COMMIT) and (mi.Protect = PAGE_READWRITE) then begin //在内存中的数据一定是提交的(MEM_COMMIT),PAGE_READWRITE是可读写 //因为是游戏修改器所以加了这个条件; GG := mi.RegionSize; lPbaseAddr := p; while GG > 0 do begin if ReadProcessMemory(Handle_Share,lPbaseAddr,@lpBuffer,4,j) then begin //ReadProcessMemory读相应地址内容 agm := @lpBuffer; if agm^ = ShareData then begin //判断是否等于目标数据; // showmessage(format('%x',[longword(lPbaseAddr)])+' '+inttostr(agm^)); New(op); op^.Data := LongWord(agm^); op^.Address := Longword(lpBaseAddr); LT.Add(op); //我把所有合适的地址都记录下来了(ListBox) end; end; //if ReadProcessMemory(GetCurrentProcess,lPbaseAddr,@lpBuffer,4,j) inc(longword(lpbaseaddr),4); Dec(GG,4); end; //while GG > 0 end; //if (mi.State = MEM_COMMIT) and (mi.Protect = PAGE_READWRITE) inc(longword(p),mi.RegionSize); // showmessage(format('%x',[longword(P)])); // end; //with ListView1.Items.Add do end; //while (true) and (longword(p)<$80000000)do
To determine the efficiency of your application, you may want to examine its memory usage. The following sample code uses the GetProcessMemoryInfo function to obtain information about the memory usage of a process. #include <windows.h>
#include <stdio.h>
#include "psapi.h"void PrintMemoryInfo( DWORD processID )
{
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc; // Print the process identifier. printf( "\nProcess ID: %u\n", processID ); // Print information about the memory usage of the process. hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID ); if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
printf( "\tPeakWorkingSetSize: 0x%08X\n",
pmc.PeakWorkingSetSize );
printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n",
pmc.QuotaPeakPagedPoolUsage );
printf( "\tQuotaPagedPoolUsage: 0x%08X\n",
pmc.QuotaPagedPoolUsage );
printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n",
pmc.QuotaPeakNonPagedPoolUsage );
printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n",
pmc.QuotaNonPagedPoolUsage );
printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage );
printf( "\tPeakPagefileUsage: 0x%08X\n",
pmc.PeakPagefileUsage );
} CloseHandle( hProcess );
}void main( )
{
// Get the list of process identifiers. DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i; if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return; // Calculate how many process identifiers were returned. cProcesses = cbNeeded / sizeof(DWORD); // Print the memory usage for each process for ( i = 0; i < cProcesses; i++ )
PrintMemoryInfo( aProcesses[i] );
}
The main function obtains a list of processes by using the EnumProcesses function. For each process, main calls the PrintMemoryInfo function, passing the process identifier. PrintMemoryInfo in turn calls the OpenProcess function to obtain the process handle. If OpenProcess fails, the output shows only the process identifier. For example, OpenProcess fails for the Idle and CSRSS processes because their access restrictions prevent user-level code from opening them. Finally, PrintMemoryInfo calls the GetProcessMemoryInfo function to obtain the memory usage information.
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, te_controls, ComCtrls, dxtree, ImgList, Menus, psapi;type
TForm1 = class(TForm)
Button2: TButton;
Memo1: TMemo;
procedure Button2Click(Sender: TObject);
private
procedure PrintMemoryInfo(processID: DWORD);
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}
procedure TForm1.PrintMemoryInfo(processID: DWORD);
var
hProcess: THandle;
pmc: PROCESS_MEMORY_COUNTERS;
begin // Print the process identifier. Memo1.Lines.Add('Process ID: ' + IntToStr(processID )); // Print information about the memory usage of the process. hProcess := OpenProcess( PROCESS_QUERY_INFORMATION or
PROCESS_VM_READ,
FALSE, processID ); if ( GetProcessMemoryInfo( hProcess, @pmc, sizeof(pmc)) )then
begin
Memo1.Lines.Add(#9 + FloatToStr(pmc.PageFaultCount) );
Memo1.Lines.Add(#9 + FloatToStr(pmc.PeakWorkingSetSize) );
Memo1.Lines.Add(#9 + FloatToStr(pmc.QuotaPeakPagedPoolUsage) );
Memo1.Lines.Add(#9 + FloatToStr(pmc.QuotaPagedPoolUsage) );
Memo1.Lines.Add(#9 + FloatToStr(pmc.QuotaPeakNonPagedPoolUsage) );
Memo1.Lines.Add(#9 + FloatToStr(pmc.QuotaNonPagedPoolUsage) );
Memo1.Lines.Add(#9 + FloatToStr(pmc.PagefileUsage) );
Memo1.Lines.Add(#9 + FloatToStr(pmc.PeakPagefileUsage) );
end; CloseHandle( hProcess );
end;procedure TForm1.Button2Click(Sender: TObject);
var
cbNeeded, cProcesses: DWORD;
aProcesses: array [0..1023] of DWORD;
I: UINT;
begin // Get the list of process identifiers.
if not EnumProcesses(@aProcesses, sizeof(aProcesses), cbNeeded ) then
Exit; // Calculate how many process identifiers were returned. cProcesses := cbNeeded div sizeof(DWORD); // Print the memory usage for each process for i := 0 to cProcesses - 1 do
PrintMemoryInfo( aProcesses[i] );end;end.
//指针小于 2G
if (x<>VirtualQueryEx(Handle_Share,p,mi,x)) then break;
//调用VirtualQueryEx
if (mi.State = MEM_COMMIT) and (mi.Protect = PAGE_READWRITE) then begin
//在内存中的数据一定是提交的(MEM_COMMIT),PAGE_READWRITE是可读写
//因为是游戏修改器所以加了这个条件;
GG := mi.RegionSize;
lPbaseAddr := p;
while GG > 0 do begin
if ReadProcessMemory(Handle_Share,lPbaseAddr,@lpBuffer,4,j) then begin
//ReadProcessMemory读相应地址内容
agm := @lpBuffer;
if agm^ = ShareData then begin //判断是否等于目标数据;
// showmessage(format('%x',[longword(lPbaseAddr)])+' '+inttostr(agm^));
New(op);
op^.Data := LongWord(agm^);
op^.Address := Longword(lpBaseAddr);
LT.Add(op);
//我把所有合适的地址都记录下来了(ListBox)
end;
end; //if ReadProcessMemory(GetCurrentProcess,lPbaseAddr,@lpBuffer,4,j) inc(longword(lpbaseaddr),4);
Dec(GG,4); end; //while GG > 0
end; //if (mi.State = MEM_COMMIT) and (mi.Protect = PAGE_READWRITE)
inc(longword(p),mi.RegionSize);
// showmessage(format('%x',[longword(P)]));
// end; //with ListView1.Items.Add do
end; //while (true) and (longword(p)<$80000000)do