У меня возникли проблемы с ReadProcessMemory
Мой код 64 бит
Я могу прочитать память любого 32-битного процесса, но ReadProcessMemory всегда завершается ошибкой с кодом ошибки 299 (частичное чтение), возвращающим 0 байтов чтения.
Закончил свое исследование, и большинство ответов были связаны с привилегиями, но у меня включен токен отладки, и я работаю от имени администратора. Адрес, который я прочитал, — ImageBase в необязательном заголовке PE.
Я попытался проверить состояние страницы с помощью 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);
Просто используя MEMORY_BASIC_INFORMATION
как это неправильно. Вы должны использовать либо использовать MEMORY_BASIC_INFORMATION32
или же MEMORY_BASIC_INFORMATION64
(как описано в раздел замечаний в MSDN) в зависимости от того, является ли удаленный процесс 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;
}
Так что после некоторой отладки и исследований выяснилось, что проблема была в ASLR, поэтому я читал не с той базы, спасибо за помощь 🙂