函数ReadProcessMemory不断返回ERROR_PARTIAL_COPY

时间:2016-01-07 05:39:04

标签: c++ winapi dll-injection

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

#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_PARAMETER\n" << endl;
        }
        else if(GetLastError() == 487)
        {
            cout << "ERROR_INVALID_ADDRESS\n" << endl;
        }
    }

    void *buffer;

    if(ReadProcessMemory(hProc, baseAddr, &buffer, sizeof(SIZE_T), NULL) == 0)
    {
        if(GetLastError() == 299)
        {
            cout << "ERROR_PARTIAL_COPY" << endl;
        }
    }
}

您可以提供的任何贡献和知识深表感谢! :)

2 个答案:

答案 0 :(得分:3)

我发现您的代码存在一些问题。

  1. 错误处理错误。如果发生错误,请记录它,但继续使用错误数据。如果发生错误,请停止。你误导了VirtualProtectEx()

  2. 您将错误的基础广告传递给&baseAddrbaseAddr取而代之的是EXECUTE。此外,您正在使用sizeof(DWORD)权限分配和保护内存,除非您打算将可执行代码存储在内存中(此代码未执行此操作),否则您不应使用这些权限。

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

  4. 您没有在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; }

  5. 试试这个:

    ReadProcessMemory

    更多问题:

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

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

        

      GetLastError将返回FALSE,ERROR_PARTIAL_COPY会在副本发生网页错误时返回OpenProcessToken()

      Working Set

        

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

    2. 您没有使用VirtualProtectEx()返回的令牌,因此该通话无效。

    3. 使用您在分配内存时指定的相同保护标志,使用Selector保护远程内存。所以这个电话也没用。

答案 1 :(得分:1)

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

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