【问题标题】:Scan entire process memory with ReadProcessMemory使用 ReadProcessMemory 扫描整个进程内存
【发布时间】:2012-05-12 22:08:18
【问题描述】:

我正在尝试扫描整个进程内存但没有成功...我正在做的是:对于测试我正在使用记事本,所以我在那里写 %B 和这个值十六进制为:25(%) 和 42(B)。所以代码是:

  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)) and (MemInfo.Protect = PAGE_READWRITE)) then
          begin
            SetLength(Buff, MemInfo.RegionSize);
              if (ReadProcessMemory(PIDHandle, MemInfo.BaseAddress, Buff,
                                        MemInfo.RegionSize, ReceivedBytes)) then
                begin
                for I := 0 to SizeOf(Buff) do
                 begin
   if (IntToHex(Buff[i], 1) = '25') and (IntToHex(Buff[i+2], 1) = '42') then
                  Form1.Memo1.Lines.Append(IntToHex(Buff[i], 1));
                 end;

                end;
          end;
      MemStart:= MemStart + MemInfo.RegionSize;
    end;
  CloseHandle(PIDHandle);
  end;

var 'Buff' 是 TBytes(我读过 TBytes 并认为它与字节数组相同)。所以我将字节转换为十六进制,并分别搜索值:25 和 42。代码如下:

if (IntToHex(Buff[i], 1) = '25') and (IntToHex(Buff[i+2], 1) = '42') then

因为十六进制值之间有 00。所以我需要添加'+2'。如何扫描整个内存以获取此值??

【问题讨论】:

    标签: delphi delphi-2010


    【解决方案1】:

    记事本使用 Unicode,因此您需要查找 UTF-16 编码数据,$0025$0042

    我不明白为什么您觉得需要在比较之前转换为十六进制字符串。十六进制没有什么特别需要使用字符串的。十六进制只是一个以 16 为基数的数字系统。因此,十进制 32 与十六进制 20 相同,即32=$20。直接与整数值进行比较:

    if (Buff[i]=$25) and (Buff[i+2]=$42) then
    

    也就是说,考虑到 $00 字节,您的测试实际上应该是这样的:

    var
      Target: string;
    ....
    Target := '%B';
    if CompareMem(@Buff[i], @Target[1], Length(Target)*SizeOf(Char)) then
      ....
    

    我不想深入了解您的其余代码,但是这一行

    for I := 0 to SizeOf(Buff) do
    

    在许多不同的层面上都是错误的。

    1. SizeOf(Buff) 返回指针的大小,因为动态数组变量本质上只是一个指针。需要记住的一件有用的事情是 SizeOf 在编译时进行评估。
    2. 如果您使用Length 而不是SizeOf,那么您将遍历列表的末尾。要遍历动态数组,请从 0 循环到 Length(...)-1
    3. 但在这种情况下,您正在循环内访问索引i+2,因此您应该从0 循环到Length(...)-3

    但实际上您需要与 4 个连续字节进行比较才能找到匹配项。可能是这样的:

    TargetByteLength = Length(Target)*SizeOf(Char);
    for i := 0 to Length(Buff)-TargetByteLength do
      if CompareMem(@Buff[i], @Target[1], TargetByteLength) then
        ....
    

    【讨论】:

    • 感谢您的回答和关注。但对我来说仍然是一个谜,为什么程序无法找到记事本内存中的值。如果我使用 ReadProcessMemory,例如:ReadProcessMemory(PIDHandle, Pointer($00367ED0), Buff,MemInfo.RegionSize, ReceivedBytes),并带有正确的地址指针,它会找到。但是扫描整个内存,什么都找不到。给您带来不便深表歉意...
    猜你喜欢
    • 1970-01-01
    • 2012-12-17
    • 2012-11-19
    • 2021-03-28
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多