ReadProcessMemory返回错误的值

时间:2014-06-30 04:13:44

标签: delphi winapi

对我来说,代码看起来没问题,也许地址读错了。我确实得到了返回的值,但肯定是错误的值。尝试了VirtualProtectEx,但仍然获得了相同的值。

procedure TForm1.Button1Click(Sender: TObject);
var
  hProc, Read, hwnd: THandle;
  Pid, Addr1, Addr2, Addr3: Cardinal;
  First,Middle,Last: DWORD;
  //oldprot, tmp: DWORD;
begin
  Addr1:=$FD3325ACA8; //10 value at address
  Addr2:=$FD33258CEC; //100 value at address
  Addr3:=$FD3325DA00; //1000 value at address
  hwnd:=FindWindow('notepad',nil);
  GetWindowThreadProcessId(hwnd, Pid);
  hProc := OpenProcess(PROCESS_VM_READ, False, Pid);
  if hProc > 0 then
  begin
    //VirtualProtectEx(hProc, pointer(addr1), 4, PAGE_EXECUTE_READWRITE, @oldprot);
    ReadProcessMemory(hProc, pointer(addr1), @First, SizeOf(First), Read);
    Edit1.Text := IntToStr(First); //2059264 value returned
    //VirtualProtectEx(hProc, pointer(addr1), 4, oldprot, @tmp);
    ReadProcessMemory(hProc, pointer(addr2), @Middle, SizeOf(Middle), Read);
    Edit2.Text := IntToStr(Middle); //1900544 value returned
    ReadProcessMemory(hProc, pointer(addr3), @Last, SizeOf(Last), Read);
    Edit3.Text := IntToStr(Last); //9899526 value returned
  end;
end;

1 个答案:

答案 0 :(得分:3)

要认识到的第一件事是ReadProcessMemory正常工作。成功时,它返回正确的值。

以下是您观察到的行为的可能解释;

  1. 其中一个API调用失败。你无法知道这一点,因为你没有检查。由于API调用失败,因此永远不会初始化三个DWORD变量的值。
  2. API调用成功,ReadProcessMemory返回的值确实是这些内存位置的内容。
  3. 下一步是检查错误。为每个API调用添加错误检查。请参阅文档以了解如何执行此操作。

    请注意,您此刻执行的唯一错误检查在语义上是不正确的。 OpenProcess失败时,会返回0。因此,通过进程句柄的条件不等于0来测试成功。使用大于此处意味着符号很重要。

    对于调用SetLastError的任何功能,您可以充分利用Win32Check

    hProc := OpenProcess(...);
    Win32Check(hProc <> 0);
    

    如果条件评估为false,这将引发带有描述性文本的操作系统错误。