【问题标题】:ReadProcessMemory() Returning 0 ERROR_PARTIAL_COPYReadProcessMemory() 返回 0 ERROR_PARTIAL_COPY
【发布时间】:2021-01-15 22:46:21
【问题描述】:
#include <Windows.h>
#include <iostream>
#include <vector>
#include <TlHelp32.h>
#include <tchar.h>

using namespace std;

DWORD GetModuleBase(LPSTR lpModuleName, DWORD dwProcessId)
{
   MODULEENTRY32 lpModuleEntry = {0};
   HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );

   if(!hSnapShot)
      return NULL;
   lpModuleEntry.dwSize = sizeof(lpModuleEntry);
   BOOL bModule = Module32First( hSnapShot, &lpModuleEntry );
   while(bModule)
   {
      if(!strcmp( lpModuleEntry.szModule, lpModuleName ) )
      {
         CloseHandle( hSnapShot );
         return (DWORDLONG)lpModuleEntry.modBaseAddr;
      }
      bModule = Module32Next( hSnapShot, &lpModuleEntry );
   }
   CloseHandle( hSnapShot );
   return NULL;
}


int main() {
    DWORD pID;
    DWORDLONG off1, off2;
    DWORDLONG baseAddress;
    char moduleName[] = _T("AoE2DE_s.exe");
    HWND hGameWindow;
    HANDLE pHandle;

    //Get Handles
    hGameWindow = FindWindow(NULL, "Age of Empires II: Definitive Edition");
    cout << "Game Window: " << hGameWindow << std::endl;
    GetWindowThreadProcessId(hGameWindow, &pID);
    cout << "Process ID: " << pID << std::endl;
    pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);

    cout << "Process Handle: " << std::hex << pHandle << std::endl;

    //Get Client Base Addy
    DWORDLONG clientBase = GetModuleBase(moduleName, pID);
    cout << "Client Base: " << clientBase << std::endl;
    ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x2BFCA18), &baseAddress, sizeof(DWORDLONG), NULL);
    DWORD lastError = GetLastError();
    cout << "Error: " << lastError << std::endl;
    cout << "Base Address: " << std::hex << baseAddress << std::endl;
    ReadProcessMemory(pHandle, (LPCVOID)(baseAddress + 0x18), &off1, sizeof(DWORDLONG), NULL);
    cout << "After Offset 1: " << std::hex << off1 << std::endl;
    ReadProcessMemory(pHandle, (LPCVOID)(off1 + 0x9230), &off2, sizeof(DWORDLONG), NULL);
    cout << "After Final Offset: " << off2 << std::endl;
    cin.get();
}

错误发生在这一行: ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x2BFCA18), &amp;baseAddress, sizeof(DWORDLONG), NULL);

用于调试目的的应用程序输出:

Game Window: 0x1307c2
Process ID: 11988
Process Handle: 0xec
Client Base: cc640000
Error: 12b
Base Address: 0
After Offset 1: 401519
After Final Offset: 8

不确定它是如何失败的,我对此有些陌生。如果有人可以帮助解决这个问题,我将不胜感激。

【问题讨论】:

  • 这能回答你的问题吗? Error 299 on ReadProcessMemory
  • 我查看了一下,似乎仍然收到同样的错误。
  • 在代码中你没有检查ReadProcessMemory的返回值。只有当它返回 0 时,你才应该使用 GetLastError
  • Windows 的错误报告有 2 个简单的规则:1 总是检查返回值。 2 仅在返回有意义值的记录条件下调用 GetLastError。你违反了两者。
  • 我不是在打印下一行的结果时检查返回值吗?如果那不是返回值,那么我不确定我是否理解。

标签: c++ winapi memory process


【解决方案1】:

ReadProcessMemory 是这样定义的:

BOOL ReadProcessMemory(
  HANDLE  hProcess,
  LPCVOID lpBaseAddress,
  LPVOID  lpBuffer,
  SIZE_T  nSize,
  SIZE_T  *lpNumberOfBytesRead
);

如果它返回零,则说明有错误,只有在这种情况下,GetLastError 才会返回一个有意义的错误号。

所以正确的用法是:

SIZE_T readBytes;
if (!ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x2BFCA18), &baseAddress, sizeof(DWORDLONG), &readBytes)) {
  DWORD lastError = GetLastError();
  cout << "ReadProcessMemory failed: Error: " << lastError << " read " << readBytes << std::endl;
}
else
{
  cout << "ReadProcessMemory succeeded"; << std::endl;
  cout << "Base Address: " << std::hex << baseAddress << std::endl;
}

【讨论】:

  • 我完全按照你的说法运行它,它输出 ReadProcessMemory failed with error 12b (ERROR_PARTIAL_COPY) 行
  • 读取的字节数应该不同于 sizeof(DWORDLONG)
猜你喜欢
  • 2016-11-09
  • 2012-09-08
  • 2011-10-21
  • 1970-01-01
  • 2021-01-30
  • 1970-01-01
  • 2023-04-06
相关资源
最近更新 更多