windows - Er det muligt at læse proceshukommelsen af ​​en 64 bit proces fra en 32bit app?

Indlæg af Hanne Mølgaard Plasc

Problem



I Windows 64 bit har jeg en 32-bit proces, der læser minde om andre 32-bit-processer, og jeg kan godt lide at kunne læse 64 bit-processer også.


ReadProcessMemory bruges til at læse hukommelsen, men den har en 32-bit begrænsning. Er der nogen måde at gøre tilsvarende på en ReadProcessMemory på en 64 bit proces?


Jeg ved, at jeg kunne skrive en 64 bit proces og starte det fra min 32 bit proces til at udføre arbejdet, men jeg undrer mig over, om der er en anden mulighed, så jeg ikke behøver at skrive en 64 bit proces.


Tak.

Bedste reference


Der er ingen måde at komme rundt om. En løsning er at stoppe med at bruge WOW64-emulatoren og skrive en 64 bit-proces. En anden løsning er at bruge IPC i stedet for direkte hukommelse.

Andre referencer 1


Er det muligt.


For eksempel kan du henvise til den fremragende prøve i svaret på tofucoder .
For en yderligere prøve kan du referere til dette link. [20]


For at forklare hvorfor det rent faktisk fungerer, bedes du tjekke denne tråd.


En anden prøve kan findes her.


Hele tricket er at kalde 64-bit version af ReadProcessMemory-funktionen. Intuitivt er det ikke en mulighed fra 32-bit proces, men linket ovenfor forklarer: x64 version af ntdll.dll er også indlæst som en del af 32-bit proces i Windows WOW64 emulator. Den har en funktion kaldet NtReadVirtualMemory med samme prototype som ReadProcessMemory64:


\_\_declspec(SPEC)BOOL \_\_cdecl ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE\_T nSize, SIZE\_T *lpNumberOfBytesRead);


Adressen er 64-bit lang, og dermed kan hele det virtuelle adresserum på 64-bits proces henvises.


Du kan måske undre sig over, hvordan man får adressen til denne funktion. Det er når en anden funktion i ntdll.dll kommer til nytte: LdrGetProcedureAddress. Dens prototype er den samme som GetProcAddress:


\_\_declspec(SPEC)DWORD64 \_\_cdecl GetProcAddress64(DWORD64 hModule, char* funcName);


Vi skal undersøge eksportkatalogen på x64 ntdll.dll og manuelt fundet denne funktions indtastning. Derefter kan vi få adresse på enhver anden funktion.


Et andet spørgsmål er forelagt hidtil: hvordan man får startadresse til x64 ntdll.dll? Vi skal manuelt gå igennem x64 PEB struktur af vores proces og transverse loaded moduler 'liste - som en af ​​varianterne. Og hvordan man får PEB adresse? Se venligst linkene ovenfor, for ikke at overflyde dette indlæg med også mange detaljer.


Alt dette er dækket af prøve fra det første link.
Alternative varianter med brug af NtReadVirtualMemory & NtWow64ReadVirtualMemory64 funktioner leveres i anden & tredje links (samt alternative måder at få PEB-adresse på).


Sammendrag: Det er muligt at interagere med x64-processen fra x86 en. Det kan gøres enten med direkte opkald til x64-version af funktionen (fra x64 ntdll.dll, som er indlæst som en del af WOW64-processen) eller med opkaldet af specifik x86-funktion, som er beregnet til at arbejde med x64-processen (nemlig [[NtWow64ReadVirtualMemory64).


P. S. Man kan sige, at den er uokumenteret og mere som hack - men det er bare ikke officielt dokumenteret. Blot som Unlocker, ProcessHacker eller ProcessExplorer bruger f.eks. Disse uokumenterede funktioner (og mange flere), og det er selvfølgelig afgørende for dig selv.

Andre referencer 2


Biblioteket wow64ext synes at have løst dette problem og tilbyder en funktion ReadProcessMemory64 Visual Studio Extension VSDebugTool synes at bruge dette bibliotek og arbejder for mig med 64 bit processer. [23] [24]


Anyway, det burde ikke være impossibe, fordi den (32 bit) Visual Studio Debugger håndterer 64 bit Debuggees meget godt.

Andre referencer 3


Nej: http://blogs.msdn.com/b/oldnewthing/archive/2008/10/20/9006720.aspx[25]

Andre referencer 4


ReadProcessMemory kan læse alle størrelser af hukommelse, herunder fra x86-processer, der læser x64-processer.


Du kan uden et problem i et x86-program gøre følgende:


DWORD64 test = 0;
ReadProcessMemory(hProcess, (LPCVOID)lpBaseAddress, &test, sizeof(DWORD64), NULL);


Hvilket vil tillade dig at dereference en x64-peger fra en x86-proces.