0

一周前,我开始制作一个项目来扫描另一个进程的内存。首先,我想将一个 DLL 注入进程,然后访问它的内存,但由于种种困难,我开始使用 VirtualQueryEx / ReadProcessMemory API 进行此操作。我的脑海中出现了一些疑问,下面是代码:

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方法:

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;

直接在 ReadProcessMemory 中传递地址,它可以工作并获取我的字符串的第一个字母(或第一个字节)。记住 Buff 是 PChar ......但如果我做同样的事情,但 ReadProcessMemory 是这样的:

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

它在备忘录上添加了一堆中文和无效字符。如何自动扫描每个内存地址并将我的字符串写入那里?有关代码的任何问题,只要问我...等待您的帮助

4

3 回答 3

0

如果您正在寻找 dll 注入(和其他有趣的技术),也许您应该看看这里? https://sites.google.com/site/delphibasics/system/app/pages/search?scope=search-site&q=dll+injection

于 2012-05-02T06:45:38.983 回答
0

在 Buff 中分配一个额外的字符并将其初始化为零。我猜 Memo1.Lines.Append 想要一个以空结尾的字符串,垃圾字符可能是 Buff 之后发生在内存中的任何内容。

于 2012-05-02T02:32:22.117 回答
0

To get the first memory address do this :

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

You are getting garbage because an 0 occurss in the string before all memory is shown so do this use

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

end;
于 2012-05-02T06:27:16.663 回答