2012-05-02 40 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