如何得到程序(进程)在内存中的首地址和内存占用大小???

Description of your first forum.

如何得到程序(进程)在内存中的首地址和内存占用大小???

帖子llingyi » 星期三, 2005年2月23日 23:07


如何得到程序(进程)在内存中的首地址和内存占用大小???
已经拿到进程的句柄,用什么函数?可以得到程序在内存中的首地址和它占用的内存空间大小呢???
 
 
 

如何得到程序(进程)在内存中的首地址和内存占用大小???

帖子jianguobu » 星期三, 2005年2月23日 23:26


下面是个用NtQueryInformationProcess的例子 :  [ NT ,2K,XP ]
// 参考: Windows NT/2000 本机API (Gary Nebbett)
// Tested using Delphi 6.0, 7.0 On WinXP
type
 PVM_Counters=^TVM_Counters;
 TVM_Counters=record
       PeakVirtualSize:ULONG;
       VirtualSize:ULONG;
       PagedFaultCount:ULONG;
       PeakWorkingSetSize:ULONG;
       WorkingSetSize:ULONG;
       QuotaPeakPagedPoolUsage:ULONG;
       QuotaPagedPoolUsage:ULONG;
       QuotaPeakNonPagedPoolUsage:ULONG;
       QuotaNonPagedPoolUsage:ULONG;
       PagefileUsage:ULONG;
       PeakPagefileUsage:ULONG;
 end;
const ProcessVMCounters =3;
...
function NtQueryInformationProcess
             (
               ProcessHandle: Thandle;
               PrcInfoClass:DWORD ;
               PrcInfo:Pointer ;
               PrcInfoLength:ULONG;
               returnlength: TPDword
             ):
               DWORD; stdcall ;external 'ntdll.dll' name 'NtQueryInformationProcess';
// 可以用动态调用(隐式装入)
....
// Our Function here:
function GetPrcVMCounters(PID:DWORD):TStringList;
var
status:DWORD;
retlen:DWORD;
VM_Info:TVM_Counters;
hProcess:THandle;
begin
result:=TStringList.Create;
hProcess :=OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,PID);
status:=NtQueryInformationProcess
       (
         hProcess,
         ProcessVMCounters,
         @VM_Info,
         sizeof(TVM_Counters),
         @retlen
       );
if(status<>0) then
begin
  ShowMessage('NtQueryInformationProcess 失败');
  exit;
end;
with result do
begin
Add('进程虚拟地址空间的最大数值 :  '+IntToStr(VM_Info.PeakVirtualSize)+'  Byte');
Add('进程的虚拟地址空间的大小 :  '+IntToStr(VM_Info.VirtualSize)+'  Byte');
Add('进程分页错误数目 :  '+IntToStr(VM_Info.PagedFaultCount)+'  Byte');
Add('进程的工作集列表的最大值 :  '+IntToStr(VM_Info.PeakWorkingSetSize)+'  Byte');
Add('进程的工作集列表的大小 :  '+IntToStr(VM_Info.WorkingSetSize)+'  Byte');  // <--- 就是这个 [:D]
Add('填充到进程的分页池的峰值的最大值 :  '+IntToStr(VM_Info.QuotaPeakPagedPoolUsage)+'  Byte');
Add('填充到进程的分页池的峰值大小 :  '+IntToStr(VM_Info.QuotaPagedPoolUsage)+'  Byte');
Add('填充到进程的非分页池的峰值的最大值 :  '+IntToStr(VM_Info.QuotaNonPagedPoolUsage)+'  Byte');
Add('填充到进程的分页池的峰值大小 :  '+IntToStr(VM_Info.QuotaNonPagedPoolUsage)+'  Byte');
Add('进程多使用的页文件页的最大值 :  '+IntToStr(VM_Info.PeakPagefileUsage)+'  Byte');
end;
end;
// ----
procedure TForm1.Button2Click(Sender: TObject);
begin
 Memo1.Lines:=GetPrcVMCounters(256);
end;

你再看看PE文件结构方面的书。
如:
Windows核心编程
 
 
 

如何得到程序(进程)在内存中的首地址和内存占用大小???

帖子llingyi » 星期四, 2005年2月24日 19:12


我还是不太清楚,虚拟内存等同于物理内存吗?
还有程序的内存首地址没找到啊!
 
 
 

如何得到程序(进程)在内存中的首地址和内存占用大小???

帖子jianguobu » 星期四, 2005年2月24日 21:51


哎,我发个程序给你吧
 
 
 

如何得到程序(进程)在内存中的首地址和内存占用大小???

帖子llingyi » 星期六, 2005年2月26日 11:19


llingyi@163.com
谢谢
还想问一下,一个程序的某个数据在内存中的地址相对程序基地址的偏移量是不是固定的?
如果是,数据地址和程序基地址的偏移量是用减法算出来的吗?
有人说用GetModuleInformation,一个问题是找不到这个函数,二是得到模块的信息和程序的内存信息是一样的吗?
 
 
 

如何得到程序(进程)在内存中的首地址和内存占用大小???

帖子abookdog » 星期六, 2005年2月26日 11:50


问:虚拟内存等同于物理内存吗?
答:虚拟内存跟物理内存是不相同的。

问:程序内地址是怎么处理的?
答:在windows中程序内的地址均使用逻辑地址,即实际在内存中的地址与逻辑地址是不同的,而逻辑地址向实际地址的转换由操作系统完成。

问:数据运算的偏址是否固定?
答:偏址是固定的。

问:是不是所有数据其地址都是固定的?
答:不一定。全局数据是固定的;
   非全局数据并不固定,一种在堆内动态生成,另一种在栈中动态生成。