我知道还有其他人问过这个问题,但似乎他们都没有得出令人满意或可以理解的结论。我不能使用没有回答的内容。我不太确定问题是什么,我已经尝试了各种不同的解决方案但没有成功,所以这是我的代码:
#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;
}
}
}
非常感谢您提供的任何贡献和知识! :)
我看到你的代码存在一些问题。
- 错误
处理错误。 如果发生错误,您可以记录它,但继续处理错误数据。 如果发生错误,请停止。 你滥用
GetLastError()
.您正在将错误的基础添加传递给
VirtualProtectEx()
.&baseAddr
内德斯改为baseAddr
。 此外,您正在分配和保护具有EXECUTE
权限的内存,除非您打算在内存中存储可执行代码(此代码不这样做(,否则不应使用这些权限。您正在使用
sizeof(DWORD)
在远程内存上设置保护标志,但您正在使用sizeof(SIZE_T)
来读取内存。DWORD
的大小固定为 32 位,但SIZE_T
为 32 或 64 位,具体取决于要编译的平台。 将SIZE_T
更改为DWORD
以匹配代码的其余部分。您没有在调用过程中为
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;
}
还有一些问题:
您在远程进程中保留内存,但您没有为该内存提交物理存储,并且在从内存读取之前不会将任何内容写入内存。 读取保留的未提交内存不是很有用,并且可能是错误的罪魁祸首:
https://stackoverflow.com/a/4457745/65863
ReadProcessMemory
将返回 FALSE,GetLastError
将在副本遇到页面错误时返回ERROR_PARTIAL_COPY
。工作集
当进程引用当前不在其工作集中的可分页内存时,会发生页面错误。
您没有使用
OpenProcessToken()
返回的令牌,因此该调用是无用的。您正在使用分配内存时指定的相同保护标志来保护远程内存
VirtualProtectEx()
。 所以这个电话也是没有用的。
表达式&buffer
是错误的 - ReadProcessMemory
不会为你分配缓冲区,它会写在你提供的缓冲区上。您需要分配内存,并将该缓冲区传递给 ReadProcessMemory
。可能的方法:
void *buffer = new BYTE[512];
ReadProcessMemory(hProc, baseAddr, buffer, sizeof(SIZE_T), NULL);