【问题标题】:Error 299 on ReadProcessMemoryReadProcessMemory 上的错误 299
【发布时间】:2017-01-09 03:00:43
【问题描述】:

尝试从游戏内存中读取实体名称,指针 100% 正确,因为使用 ce 进行检查。

读取/写入浮点/整数值没有问题

32 位进程,以及游戏 - 尝试在 x64 中编译代码,但没有帮助。

GetLastError()

返回 nr 299

ERROR_PARTIAL_COPY

299 (0x12B)

Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

任何想法可能是什么原因? 代码如下

#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <string>
#include <time.h>
#include <tchar.h>



using namespace std;

DWORD dwGetModuleBaseAddress(DWORD dwProcessIdentifier, TCHAR *lpszModuleName);
string readName(HANDLE handlez, DWORD base, DWORD bp, DWORD ofset1, DWORD ofset2, DWORD ofsetInc);


int main()
{
    DWORD baseOfset = 0x60DE90;
    DWORD ofset1 = 0x4c4;
    DWORD ofset2 = 0x6a0;
    DWORD ofset3 = 0x18;


    HWND window = NULL;//FindWindow(0, _TEXT("Gothic II - 2.6 (pol)"));
    DWORD pID = 0;
    DWORD dwBP = NULL;
    HANDLE handle = NULL;// OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    string gameStatus;
    int refresher = clock();
    gameStatus = "Waiting for game";




    window = FindWindow(0, _TEXT("Gothic II - 2.6 (pol)")); // window title
    if (window)
    {
        GetWindowThreadProcessId(window, &pID);
        if (pID != 0)
        {
            handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
            dwBP = dwGetModuleBaseAddress(pID, _T("Gothic2.exe"));  // proc name

            if (handle == INVALID_HANDLE_VALUE || handle == NULL || dwBP == NULL)
            {
                gameStatus = "No handle";
            }
            else
            {
                gameStatus = "OK";
            }
        }
        else
        {
            gameStatus = "No access";
        }
    }
    else
    {
        gameStatus = "No window";

    }




    while (!GetAsyncKeyState(VK_DELETE))
    {
        if (clock() - refresher > 1000)
        {
            refresher = clock();


            cout << gameStatus << endl;
            string elo="a";


                elo = readName(handle,  dwBP, baseOfset, ofset1, ofset2, ofset3);
                if (elo == "a")
                {
                    cout << ":(\n";
                }

                cout << "Name: " <<  elo <<".\n";

                cout << "Name: " << &elo << ".\n" << endl;
                system("pause");

                        }
    }


    CloseHandle(handle);
}

string readName(HANDLE handlez, DWORD base, DWORD bp, DWORD ofset1, DWORD ofset2, DWORD ofsetInc)
{

    DWORD adresik;

    ReadProcessMemory(handlez, (LPCVOID)(base + bp), &adresik, sizeof(DWORD), NULL); // base adress + base pointer
    adresik += ofset1;          //1st lvl pointer
    ReadProcessMemory(handlez, (LPCVOID)adresik, &adresik, sizeof(DWORD), NULL); 
    adresik += ofset2;          // 2nd lvl pointer
    ReadProcessMemory(handlez, (LPCVOID)adresik, &adresik, sizeof(DWORD), NULL); 
    adresik += ofsetInc;            // 3rd lvl pointer this goes up +=20
    ReadProcessMemory(handlez, (LPCVOID)adresik, &adresik, sizeof(DWORD), NULL); 
    adresik += 0x12c;                   // 4th static pointer
    ReadProcessMemory(handlez, (LPCVOID)adresik, &adresik, sizeof(DWORD), NULL); 
    adresik += 0x0;                     // 5th static pointer
    ReadProcessMemory(handlez, (LPCVOID)adresik, &adresik, sizeof(DWORD), NULL); 


    string papa;

    ReadProcessMemory(handlez, (LPCVOID)adresik, &papa, sizeof(string), NULL); // get name
    DWORD ero = GetLastError();
    cout << ero << endl;
    return papa;  // return name


}


DWORD dwGetModuleBaseAddress(DWORD dwProcessIdentifier, TCHAR *lpszModuleName)
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessIdentifier);
    DWORD dwModuleBaseAddress = 0;
    if (hSnapshot != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 ModuleEntry32 = { 0 };
        ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
        if (Module32First(hSnapshot, &ModuleEntry32))
        {
            do
            {
                if (_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0)
                {
                    dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr;
                    break;
                }
            } while (Module32Next(hSnapshot, &ModuleEntry32));
        }
        CloseHandle(hSnapshot);
    }
    return dwModuleBaseAddress;
}

【问题讨论】:

    标签: c++ windows


    【解决方案1】:

    您不能只将 c 字符串复制到 std::string 的内存位置。

    您想要的大概是这样的(假设这实际上是您正在阅读的以空字符结尾的字符串):

    const int MAX_SIZE = 512;
    const char buffer[MAX_SIZE];
    string papa;
    
    ReadProcessMemory(handlez, (LPCVOID)adresik, buffer, MAX_SIZE, NULL); // get name
    
    papa = buffer;    
    

    此外,如果字符串正好在页面边界附近,您可能需要逐字节或小块读取它,直到找到终止的空字符。因此,如果您可以找到存储在任何地方的字符串长度,我建议您阅读并使用它。

    【讨论】:

      【解决方案2】:

      干杯哥们,这帮助了我!

      她的固定 readName 代码,以防万一;)

      将最大尺寸更改为 15,因为游戏中没有 NPC/怪物的名称超过 15 个符号。

      string readName(HANDLE handlez, DWORD base, DWORD bp, DWORD ofset1, DWORD ofset2, DWORD ofsetInc)
      {
      
          DWORD adresik;
          
          ReadProcessMemory(handlez, (LPCVOID)(base + bp), &adresik, sizeof(DWORD), NULL); // base adress + base pointer
          adresik += ofset1;          //1st lvl pointer
          ReadProcessMemory(handlez, (LPCVOID)adresik, &adresik, sizeof(DWORD), NULL); 
          adresik += ofset2;          // 2nd lvl pointer
          ReadProcessMemory(handlez, (LPCVOID)adresik, &adresik, sizeof(DWORD), NULL); 
          adresik += ofsetInc;            // 3rd lvl pointer this goes up +=20
          ReadProcessMemory(handlez, (LPCVOID)adresik, &adresik, sizeof(DWORD), NULL); 
          adresik += 0x12c;                   // 4th static pointer
          ReadProcessMemory(handlez, (LPCVOID)adresik, &adresik, sizeof(DWORD), NULL); 
          adresik += 0x0;                     // 5th static pointer
          
      
          string papa;
          const int max_size = 15;
          const char buffer[max_size] = { 'b' };
          
      
          ReadProcessMemory(handlez, (LPCVOID)adresik, (void*)&buffer, sizeof(buffer), NULL); // get name
      
          papa = buffer;
          
          DWORD ero = GetLastError();
          cout << ero << endl;
          return papa;  // return name
      
      
      }
      

      【讨论】:

      • 您的错误检查是错误的。你需要检查ReadProcessMemory的返回值,如果且仅当为假,那么你调用GetLastError()。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-21
      • 1970-01-01
      相关资源
      最近更新 更多