2012-05-02 41 views
-1

一週前,我開始製作一個項目來掃描另一個進程內存。首先,我只是想將DLL注入進程,然後訪問它的內存,但由於所有困難,我開始使用VirtualQueryEx/ReadProcessMemory API進行此操作。 有些疑惑浮現在我的腦海,下面是代碼:VirtualQueryEx/ReadProcessMemory

var 
    Form1: TForm1; 
    PIDHandle: THandle; 
    PID: dword; 
    MemInfo: MEMORY_BASIC_INFORMATION; 
    SysInfo: SYSTEM_INFO; 
    PageSize, MemStart, ReceivedBytes: cardinal; 
    Buff: PChar; 
    IsWow64Process: TIsWow64Process; 
    IsWow64: BOOL; 

    while (VirtualQueryEx(PIDHandle, Pointer(MemStart), MemInfo, SizeOf(MemInfo)) > 0) do 
     begin 
     if ((MemInfo.State = MEM_COMMIT) and (not (MemInfo.Protect = PAGE_GUARD) 
      or (MemInfo.Protect = PAGE_NOACCESS))) then 
      begin 
      if (0<>MemInfo.Protect and PAGE_READWRITE) then 
       begin 
       GetMem(Buff, MemInfo.RegionSize); 
       if (ReadProcessMemory(PIDHandle, Pointer($00636ED0), Buff, 
             MemInfo.RegionSize, ReceivedBytes)) then 
        begin 
        Memo1.Lines.Append(PAnsiChar(Buff)); 
        end; 
       FreeMem(Buff); 
       end; 
      end; 
     MemStart:= MemStart + MemInfo.RegionSize; 
    end; 
    CloseHandle(PIDHandle); 
    end; 

首先全部 - 該方法時:

while (VirtualQueryEx(PIDHandle, Pointer(MemStart), MemInfo, SizeOf(MemInfo)) > 0) do 
... 
MemStart:= MemStart + MemInfo.RegionSize; 

我是否掃描所有的內存地址?或者它只是「跳躍」地址而不讀取??! 第二個也是最重要的問題 - 我使用記事本進行測試,我的目標是讀取一些寫在那裏的字符串。如果我做這樣的:

 if (0<>MemInfo.Protect and PAGE_READWRITE) then 
       begin 
       GetMem(Buff, MemInfo.RegionSize); 
       if (ReadProcessMemory(PIDHandle, Pointer($00636ED0), Buff, 
             MemInfo.RegionSize, ReceivedBytes)) then 
        begin 
        Memo1.Lines.Append(PAnsiChar(Buff)); 
        end; 
       FreeMem(Buff); 
       end; 

直接傳遞的地址中進行ReadProcess,它的工作原理,並得到我的字符串的第一個字母(或第一個字節)。記住的Buff是PChar類型......但是,如果我做同樣的事情,但ReadProcessMemory是這樣的:

if (ReadProcessMemory(PIDHandle, MemInfo.BaseAddress, Buff, 
    MemInfo.RegionSize, ReceivedBytes)) then 
     begin 
      Memo1.Lines.Append(PAnsiChar(Buff)); 
     end; 
    FreeMem(Buff); 
    end; 

它添加在備註一幫中國和無效字符。我怎樣才能自動掃描每一個內存地址,並讓我的字符串寫在那裏?任何有關代碼的問題,只是問我...等待你的幫助

+2

試圖將此內存解釋爲文本是一個錯誤。這不是文字。您希望以與十六進制編輯器相同的方式顯示它。 –

+0

是的,或多或少像這樣。有一些十六進制編輯器有一個功能來搜索內存中的確切文本字符串。我想這樣做,在內存中搜索某種字符串... – HwTrap

回答

0

在Buff中分配一個額外的字符並用零初始化它。我猜Memo1.Lines.Append想要一個以null結尾的字符串,這個垃圾字符可能是在Buff之後發生在內存中的任何事情。

+0

我不知道我是否理解你說的,但是我可以在備忘錄中看到收到的所有buff,而且它只是垃圾。只有第一行是:RESCHIT 其他所有內容都是垃圾 – HwTrap

+0

當解釋爲文本時,進程中的大部分內存通常是垃圾。你正在閱讀記事本內存進行測試?記事本使用unicode字符(16位字符),因此大多數拉丁語言字符將具有零高位字節。如果ansi字符被解釋爲unicode,那麼你會得到大量的中文等垃圾(因爲每個字符的高字節是下一個字符)。我沒有完全遵循你想要達到的目標。將進程的內存轉儲到文本字段中? – doug65536

+0

不是所有的內存都進入文本字段。但是我想用Read/Write屬性來分析每個內存地址來搜索一個字符串。我正在搜索的這個字符串顯然是文本(ASCII或Unicode),但是如何獲取?這是我的問題。 – HwTrap

0

爲了得到第一個內存地址做到這一點:

var 
sysinfo : TSystemInfo; 
GetSystemInfo(sysinfo); 
start : DWORD; 
begin 
start := DWORD(sysinfo.lpMinimumApplicationAddress); 
end; 

你得到的垃圾,因爲0 occurss字符串中的所有存儲器之前被顯示,爲此,請使用

var 
    mybuffer : String; 
begin 
    SetLength(mybuffer,MemInfo.RegionSize); 
    CopyMemory(@mybuffer[1],Buff,MemInfo.RegionSize); 
    Memo1.Lines.Add(mybuffer); 

end; 
+0

仍然不能正常工作= \\ – HwTrap

+0

不工作,因爲記事本不使用ascii編碼在delphi 7中使用tmemo編碼自己的應用程序並測試它 – opc0de

+0

我在德爾福2010年...任何方式來轉換它? – HwTrap