我在使用ReadProcessMemory时遇到了一些麻烦 我的代码是64位 我可以读取任何32位进程的内存,但ReadProcessMemory总是失败,错误代码299(部分读取)返回0字节读取。
完成我的研究并且大多数答案都与特权有关,但我启用了调试令牌并以管理员身份运行,地址我在PE可选标题中读取了ImageBase
我尝试使用VirtualQueryEx检查页面状态并拒绝访问!
注意:代码在任何32位进程上都能完美运行。
任何想法可能导致这个?
HANDLE hProcess;
DWORD pid;
EnableDebugPriv();
pid=GetProcessByName("winmine.exe"); //32 bit apps work
//pid=GetProcessByName("notepad.exe"); //64 bit apps dont
hProcess = OpenProcess(PROCESS_ALL_ACCESS ,0, pid);
if(!hProcess)
{
printf("failed to acquire handle , Error %d \n" , GetLastError());
return FAILED;
}
//DEBUGGING
//DWORD address = 0x100000000; //64 notepad
DWORD address = 0x1000000; // 32 bit minsweeper
DWORD oldProtect=0;
printf("DEBUG pid %d - last err :%d \n" , GetProcessId(hProcess) , GetLastError() );
if(VirtualProtectEx(hProcess , (LPVOID)address,4096 /*pagesize for test*/ , PAGE_EXECUTE_READWRITE , &oldProtect))
{
cout <<"vp done \n";
}
else cout << " vp err :" << GetLastError() << endl;
PMEMORY_BASIC_INFORMATION pmbi = new MEMORY_BASIC_INFORMATION;
if(VirtualQueryEx(hProcess,(LPVOID)address,pmbi,sizeof(MEMORY_BASIC_INFORMATION)))
{
cout << "protection :" << pmbi->AllocationProtect << endl;
}
char value = 0;
SIZE_T * pbytes = new SIZE_T ;
ReadProcessMemory(hProcess,(LPCVOID)address ,&value,sizeof(value),pbytes);
cout << value << endl;
printf("Read status : %d ; bytes read %d \n",GetLastError() , *pbytes );
CloseHandle(hProcess);
答案 0 :(得分:3)
仅仅使用MEMORY_BASIC_INFORMATION
这样做是不正确的。您应该使用MEMORY_BASIC_INFORMATION32
或MEMORY_BASIC_INFORMATION64
(如MSDN中remarks section中所述),具体取决于远程进程是32位还是64位。
结构的大小和布局将根据是32位还是64位进程而有所不同。只需使用MEMORY_BASIC_INFORMATION
,您就可以期望远程进程使用当前进程使用的任何布局。
为了测试远程进程是32位还是64位,你可以像这样使用IsWow64Process
函数:
bool is64BitProcess(HANDLE hProcess)
{
const bool is64BitOS = sizeof(void *) == 8 || IsWow64Process(GetCurrentProcess());
return is64BitOS ? IsWow64Process(hProcess)
: false;
}
答案 1 :(得分:1)
所以经过一些调试和研究后发现问题出在ASLR上,所以我在错误的基础上阅读,谢谢你的帮助:)