函数读取进程内存不断返回ERROR_PARTIAL_COPY

Function ReadProcessMemory keeps returning ERROR_PARTIAL_COPY

本文关键字:ERROR PARTIAL COPY 返回 读取 取进程 内存 函数      更新时间:2023-10-16

我知道还有其他人问过这个问题,但似乎他们都没有得出令人满意或可以理解的结论。我不能使用没有回答的内容。我不太确定问题是什么,我已经尝试了各种不同的解决方案但没有成功,所以这是我的代码:

#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_QUERY_INFORMATION, FALSE, (DWORD)7312);
    if(hProc == NULL)
    {
        cout << "Error: " << GetLastError() << endl;
    }
    HANDLE token;
    OpenProcessToken(hProc, TOKEN_ALL_ACCESS, &token);
    void *baseAddr = VirtualAllocEx(hProc, NULL, 500, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if(baseAddr == NULL)
    {
        cout << "VirtualAllocEx has failed" << endl;
    }
    else
    {
        cout << "Base Address: " << baseAddr << "n" << endl;
    }
    DWORD prevProt;
    if(VirtualProtectEx(hProc, &baseAddr, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &prevProt) == 0)
    {
        if(GetLastError() == 87)
        {
            cout << "ERROR_INVALID_PARAMETERn" << endl;
        }
        else if(GetLastError() == 487)
        {
            cout << "ERROR_INVALID_ADDRESSn" << endl;
        }
    }
    void *buffer;
    if(ReadProcessMemory(hProc, baseAddr, &buffer, sizeof(SIZE_T), NULL) == 0)
    {
        if(GetLastError() == 299)
        {
            cout << "ERROR_PARTIAL_COPY" << endl;
        }
    }
}
非常感谢

您提供的任何贡献和知识! :)

我看到你的代码存在一些问题。

    错误
  1. 处理错误。 如果发生错误,您可以记录它,但继续处理错误数据。 如果发生错误,请停止。 你滥用GetLastError().

  2. 您正在将错误的基础添加传递给VirtualProtectEx() . &baseAddr内德斯改为baseAddr。 此外,您正在分配和保护具有EXECUTE权限的内存,除非您打算在内存中存储可执行代码(此代码不这样做(,否则不应使用这些权限。

  3. 您正在使用sizeof(DWORD)在远程内存上设置保护标志,但您正在使用sizeof(SIZE_T)来读取内存。 DWORD 的大小固定为 32 位,但SIZE_T为 32 或 64 位,具体取决于要编译的平台。 将SIZE_T更改为DWORD以匹配代码的其余部分。

  4. 您没有在调用过程中为ReadProcessMemory()分配任何内存以供写入。 将void *buffer;更改为DWORD buffer;

试试这个:

#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
    DWORD dwError;
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_QUERY_INFORMATION, FALSE, (DWORD)7312);
    if (hProc == NULL)
    {
        dwError = GetLastError();
        cout << "OpenProcess has failed. Error: " << dwError << endl;
        return 0;
    }
    HANDLE token;
    if (!OpenProcessToken(hProc, TOKEN_ALL_ACCESS, &token))
    {
        dwError = GetLastError();
        cout << "OpenProcessToken has failed. Error: " << dwError << endl;
        return 0;
    }
    void *baseAddr = VirtualAllocEx(hProc, NULL, 500, MEM_RESERVE, PAGE_READWRITE);
    if (baseAddr == NULL)
    {
        dwError = GetLastError();
        cout << "VirtualAllocEx has failed. Error: " << dwError << endl;
        return 0;
    }
    cout << "Base Address: " << baseAddr << endl;
    DWORD prevProt;
    if (!VirtualProtectEx(hProc, baseAddr, sizeof(DWORD), PAGE_READWRITE, &prevProt))
    {
        dwError = GetLastError();
        cout << "VirtualAllocEx has failed. Error: ";
        if (dwError == ERROR_INVALID_PARAMETER)
        {
            cout << "ERROR_INVALID_PARAMETER";
        }
        else if (dwError == ERROR_INVALID_ADDRESS)
        {
            cout << "ERROR_INVALID_ADDRESS";
        }
        else
        {
            cout << dwError;
        }
        cout << endl;
        return 0;
    }
    DWORD buffer;
    if (ReadProcessMemory(hProc, baseAddr, &buffer, sizeof(DWORD), NULL))
    {
        dwError = GetLastError();
        cout << "ReadProcessMemory has failed. Error: ";
        if (dwError == ERROR_PARTIAL_COPY)
        {
            cout << "ERROR_PARTIAL_COPY";
        }
        else
        {
            cout << dwError;
        }
        cout << endl;
        return 0;
    }
    cout << "Value: " << buffer << endl;
    return 0;
}

还有一些问题:

  1. 您在远程进程中保留内存,但您没有为该内存提交物理存储,并且在从内存读取之前不会将任何内容写入内存。 读取保留的未提交内存不是很有用,并且可能是错误的罪魁祸首:

    https://stackoverflow.com/a/4457745/65863

    ReadProcessMemory将返回 FALSE,GetLastError将在副本遇到页面错误时返回ERROR_PARTIAL_COPY

    工作集

    当进程引用当前不在其工作集中的可分页内存时,会发生页面错误

  2. 您没有使用OpenProcessToken()返回的令牌,因此该调用是无用的。

  3. 您正在使用分配内存时指定的相同保护标志来保护远程内存VirtualProtectEx()。 所以这个电话也是没有用的。

表达式&buffer是错误的 - ReadProcessMemory不会为你分配缓冲区,它会写在你提供的缓冲区上。您需要分配内存,并将该缓冲区传递给 ReadProcessMemory 。可能的方法:

void *buffer = new BYTE[512];
ReadProcessMemory(hProc, baseAddr, buffer, sizeof(SIZE_T), NULL);
相关文章: