国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

如何訪問一個進程的內存空間

2019-11-18 18:46:40
字體:
來源:轉載
供稿:網友
   在WIN32中,每個應用程序都可“看見”4GB的線性地址空間,其中最開始的
4MB和最后的2GB由操作系統保留,剩下不足2GB的空間用于應用程序私有空間。
具體分配如下:0xFFFFFFFF-0xC0000000的1GB用于VxD、存儲器管理和文件系統;
0xBFFFFFFF-0x80000000的1GB用于共享的WIN32 DLL、存儲器映射文件和共享存
儲區;0x7FFFFFFF-0x00400000為每個進程的WIN32專用地址;0x003FFFFF-
0x00001000為MS-DOS 和 WIN16應用程序;0x00000FFF-0x00000000為防止使用
空指針的4,096字節。以上都是指邏輯地址,也就是虛擬內存。
    虛擬內存通常是由固定大小的塊來實現的,在WIN32中這些塊稱為“頁”,
每頁大小為4,096字節。在Intel CPU結構中,通過在一個控制寄存器中設置一位
來啟用分頁。啟用分頁時CPU并不能直接訪問內存,對每個地址要經過一個映射
進程,通過一系列稱作“頁表”的查找表把虛擬內存地址映射成實際內存地址。
通過使用硬件地址映射和頁表WIN32可使虛擬內存即有好的性能而且還提供保護。
利用處理器的頁映射能力,操作系統為每個進程提供獨立的從邏輯地址到物理地
址的映射,使每個進程的地址空間對另一個進程完全不可見。WIN32中也提供了
一些訪問進程內存空間的函數,但使用時要謹慎,一不小心就有可能破壞被訪問
的進程。本文介紹如何讀另一個進程的內存,寫內存與之相似,完善一下你也可
以做個 FPE 之類的內存修改工具。好吧,先準備好編程利器Delphi 和 參考手
冊 MSDN ,開始了!
  ReadPRocessMemory 讀另一個進程的內存,原形如下:
    BOOL ReadProcessMemory(
    HANDLE hProcess,         // 被讀取進程的句柄;
    LPCVOID lpBaseAddress,      // 讀的起始地址;
    LPVOID lpBuffer,         // 存放讀取數據緩沖區;
    DWord nSize,         // 一次讀取的字節數;
    LPDWORD lpNumberOfBytesRead // 實際讀取的字節數;
  );
hProcess 進程句柄可由OpenProcess 函數得到,原形如下:
  HANDLE OpenProcess(
    DWORD dwDesiredaccess, // 訪問標志;
    BOOL bInheritHandle,   // 繼承標志;
    DWORD dwProcessId      // 進程ID;
  );
當然,用完別忘了用 CloseHandle 關閉打開的句柄。
讀另一個進程的內存 dwDesiredAccess 須指定為 PROCESS_VM_READ ,
寫另一個進程的內存 dwDesiredAccess 須指定為 PROCESS_VM_WRITE ,
繼承標志無所謂,進程ID可由 Process32First 和 Process32Next 得到,
這兩個函數可以枚舉出所有開啟的進程,這樣進程的信息也就得到了。
Process32First 和 Process32Next是由 TLHelp32 單元提供的,需在
uses 里加上TLHelp32。ToolsHelp32 封裝了一些訪問堆、線程、進程等
的函數,只適用于Win9x,原形如下:
  BOOL WINAPI Process32First(
    HANDLE hSnapshot      // 由 CreateToolhelp32Snapshot 返回
                             的系統快照句柄;
    LPPROCESSENTRY32 lppe // 指向一個 PROCESSENTRY32 結構;
  );
  BOOL WINAPI Process32Next(
    HANDLE hSnapshot      // 由 CreateToolhelp32Snapshot 返回
                             的系統快照句柄;
    LPPROCESSENTRY32 lppe // 指向一個 PROCESSENTRY32 結構;
  );
hSnapshot 由 CreateToolhelp32Snapshot 返回的系統快照句柄;
CreateToolhelp32Snapshot 原形如下:
  HANDLE WINAPI CreateToolhelp32Snapshot(
    DWORD dwFlags,      // 快照標志;
    DWORD th32ProcessID // 進程ID;
  );
現在需要的是進程的信息,所以將 dwFlags 指定為 TH32CS_SNAPPROCESS,
th32ProcessID 忽略;PROCESSENTRY32 結構如下:
  typedef struct tagPROCESSENTRY32 {
    DWORD dwSize;             // 結構大小;
    DWORD cntUsage;           // 此進程的引用計數;
    DWORD th32ProcessID;      // 進程ID;
    DWORD th32DefaultHeapID;  // 進程默認堆ID;
    DWORD th32ModuleID;       // 進程模塊ID;
    DWORD cntThreads;         // 此進程開啟的線程計數;
    DWORD th32ParentProcessID;// 父進程ID;
    LONG  pcPriClassBase;     // 線程優先權;
    DWORD dwFlags;            // 保留;
    char szExeFile[MAX_PATH]; // 進程全名;
  } PROCESSENTRY32;
至此,所用到的主要函數已介紹完,實現讀內存只要從下到上依次調用
上述函數即可,具體參見原代碼:

procedure TForm1.Button1Click(Sender: TObject);
var
  FSnapshotHandle:THandle;
  FProcessEntry32:TProcessEntry32;
  Ret : BOOL;
  ProcessID : integer;
  ProcessHndle : THandle;
  lpBuffer:pByte;
  nSize: DWORD;
  lpNumberOfBytesRead: DWORD;
  i:integer;
  s:string;
begin
  FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    //創建系統快照
  FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
    //先初始化 FProcessEntry32 的大小
  Ret:=Process32First(FSnapshotHandle,FProcessEntry32);
  while Ret do
  begin
    s:=ExtractFileName(FProcessEntry32.szExeFile);
    if s='KERNEL32.DLL' then
    begin
      ProcessID:=FProcessEntry32.th32ProcessID;
      s:=';
      break;
    end;
    Ret:=Process32Next(FSnapshotHandle,FProcessEntry32);
  end;
   //循環枚舉出系統開啟的所有進程,找出“Kernel32.dll”
  CloseHandle(FSnapshotHandle);
  Memo1.Lines.Clear ;
  memo1.lines.add('Process ID '+IntToHex(FProcessEntry32.th32ProcessID,8));
  memo1.lines.Add('File name '+FProcessEntry32.szExeFile);
    ////輸出進程的一些信息
  nSize:=4;
  lpBuffer:=AllocMem(nSize);
  ProcessHndle:=OpenProcess(PROCESS_VM_READ,false,ProcessID);
  memo1.Lines.Add ('Process Handle '+intTohex(ProcessHndle,8));
  for i:=$00800001 to $0080005f do
  begin
    ReadProcessMemory(
                     ProcessHndle,
                     Pointer(i),
                     lpBuffer,
                     nSize,
                     lpNumberOfBytesRead
                     );
    s:=s+intTohex(lpBuffer^,2)+' ';
      //讀取內容
    if (i mod 16) =0 then
    begin
      Memo1.Lines.Add(s);
      s:=';
    end;
      //格式化輸出
  end;
  FreeMem(lpBuffer,nSize);
  CloseHandle(ProcessHndle);
   //關閉句柄,釋放內存
end;
以上程序在 Delphi4 中文Win98 下調試通過。

(ypy@yeah.net)


上一篇:可以左右居中對齊并可設置DisplayFormat的Edit控件

下一篇:截獲與管理Windows的消息

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 花莲县| 达拉特旗| 吉木萨尔县| 成都市| 博湖县| 旬阳县| 教育| 云阳县| 潜山县| 乌苏市| 弋阳县| 霍城县| 庄浪县| 大洼县| 孙吴县| 含山县| 米脂县| 定边县| 陵川县| 乌拉特后旗| 琼中| 文成县| 雅江县| 应用必备| 光泽县| 辽阳县| 寿宁县| 台安县| 金寨县| 博客| 喜德县| 栖霞市| 靖宇县| 台湾省| 昌都县| 沅陵县| 翁牛特旗| 海安县| 深圳市| 永靖县| 巴塘县|