Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Hookowanie procesu WOW64 z biblioteki dll x64
#1
Ostatnio się nudziłem i postanowiłem zrobić coś bezsensownego. I skończyło się na tym hocku EndScene z x86 z x64 dll. Wziąłem GFXTest.exe jako proces docelowy.   Nie widzę żadnych szczególnych zalet w porównaniu do tradycyjnego haka, więc to bardziej jak POC i fajne rzeczy. Chciałem tylko upewnić się, że to możliwe.   Kod dll:     Kod:   #include <stdint.h> #include <stdio.h> #include <windows.h> #include <d3d9.h> extern "C" void hookMain (); extern "C" uint64_t WOW64stdcall (void * pfn, uint64_t argc, uint64_t, uint64_t, ...); DWORD pEndScene = 0; void * pPrintStr = 0; / * * / void * GetProc (mod HMODULE, const char * proc) {if (mod == 0) return nullptr; uint8_t * modBase = (uint8_t *) mod; IMAGE_DOS_HEADER * pDos = (IMAGE_DOS_HEADER *) modBase; IMAGE_NT_HEADERS32 * pNtHdr = (IMAGE_NT_HEADERS32 *) (modBase + pDos -> e_lfanew); IMAGE_EXPORT_DIRECTORY * pExport = (IMAGE_EXPORT_DIRECTORY *) (modBase + pNtHdr -> OptionalHeader, DataDirectory [IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); DWORD * pAdresses = (DWORD *) (modBase + pExport -> AddressOfFunctions); DWORD * pNames = (DWORD *) (modBase + pExport -> AddressOfNames); WORD * pOrds = (WORD *) (modBase + pExport -> AddressOfNameOrdinals); for (DWORD i = 0; i <pExport -> NumberOfNames; i ++) {if (strcmp (proc, (const char *) mod + pNames [i]) == 0) return modBase + pAdresses [pOrds [i] ]; } Return nullptr; } / * * / HMODULE GetMod32 (const wchar_t * modName) {_TEB32 * pTeb32 = (_TEB32 *) ((uint8_t *) NtCurrentTeb () + 0x2000); _PEB_LDR_DATA232 * pLdr32 = (_PEB_LDR_DATA232 *) ((_PEB32 *) pTeb32 -> ProcessEnvironmentBlock) -> Ldr; LIST_ENTRY32 * pFirstEntry = (LIST_ENTRY32 *) & pLdr32 -> InLoadOrderModuleList; for (LIST_ENTRY32 * pEntry = (LIST_ENTRY32 *) pFirstEntry -> Flink; pEntry! = pFirstEntry; pEntry = (LIST_ENTRY32 *) pEntry -> Flink) {_LDR_DATA_TABLE_ENTRY_BASE32 * pImageEntry = (_LDR_DATA_TABLE_ENTRY_BASE32 *) pEntry; if (_wcsicmp ((const wchar_t *) pImageEntry -> BaseDllName, Buffer, modName) == 0) return (HMODULE) pImageEntry -> DllBase; } Return 0; } / * * / HRESULT hkEndScene (IDirect3DDevice9 * arg) {if (pPrintStr! = 0) {wchar_t buf [64]; wsprintf (buf, L "EndScene o nazwie .IDirect3DDevice9 = 0x% p \ n", arg); WOW64stdcall (pPrintStr, 1, 0, 0, buf); } Return (HRESULT) WOW64stdcall ((void *) pEndScene, 1, 0, 0, arg); } / * * / Void SetHook () {SIZE_T bytes = 0; DWORD flOld = 0; uint32_t pDxStorage = 0; uint32_t pDxDevice = 0; uint32_t hMain = (uint32_t) GetModuleHandle (NULL); pDxStorage = * (uint32_t *) (hMain + 0x4014); pDxDevice = * (uint32_t *) (* (uint32_t *) (pDxStorage + 0x20) + 4); pEndScene = * (uint32_t *) (* (uint32_t *) pDxDevice + 0xA8); VirtualProtect (& hookMain, 0x40, PAGE_EXECUTE_READWRITE, & FLOld); // Ustaw prawdziwy hook ptr dla (uint8_t * ptr = (uint8_t *) i hookMain; ptr <(uint8_t *) i hookMain + 0x40; ++ ptr) {if (* (uint64_t *) ptr == 0xDEADBEEFDEADBEEF) {* ( void **) ptr = & hkEndScene; złamać ; }} PPrintStr = GetProc (GetMod32 (L "kernel32.dll"), "OutputDebugStringW"); DWORD pHook = (DWORD) i hookMain; WriteProcessMemory (GetCurrentProcess (), (void *) (* (uint32_t *) pDxDevice + 0xA8), pHook, sizeof (pHook) i bajty); } BOOL APIENTRY DllMain (HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {switch (ul_reason_for_call) {case DLL_PROCESS_ATTACH: SetHook (); złamać ; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } Return TRUE; }   Rdzeń złożeniowy (dialekt masm):     Kod:   hookMain PROTO WOW64stdcall PROTO. kod ; Przełącz na tryb długi enter64 proc retf enter64 endp; Przełącz na tryb WOW64 enter32 proc mov dword ptr [rsp + 4], 23h retf enter32 endp; hookMain proc push push 33h call enter64; Call hook mov rax, 0DEADBEEFDEADBEEFh mov ecx, dword ptr [esp + 4]; Zapobiegaj zniszczeniu stosu przez shadow space sub rsp, 20h
Reply
#2
to całkiem zabawne. dlaczego niestandardowy GPA i GMH?
Reply
#3
Zacytować: dlaczego niestandardowy GPA i GMH? Ponieważ standardowe funkcje działają tylko dla modułów 64-bitowych. A moja niestandardowa implementacja jest przeznaczona dla modułów 32-bitowych.
Reply
#4
to ma sens
Reply
#5
Bardzo dobrze. Zacytować: Musisz rozrzucić trochę reputacji, zanim ponownie oddasz ją do DarthTon.
Reply
#6
teraz znajdź metodę przydzielania memu powyżej 4GB w procesie wow64 przy wygrywaniu 7 jestem zbyt leniwy, aby wydać 5 milionów na googelng. qq dzięki
Reply
#7
zauważysz jakiekolwiek negatywne skutki wydajności ze względu na przełączanie trybu za każdym razem, gdy funkcja jest wywoływana? 0.o mnie wydaje się, że byłoby bardziej wydajnie po prostu napisać hak w x86 i skopiować do pamięci <4gb ofc i haka w ten sposób .. czy się mylę?
Reply
#8
Uderzenie wydajnościowe będzie niezauważalne, chyba że hak zostanie wywołany kilkaset tysięcy razy na sekundę. I jak powiedziałem w pierwszym poście, jest to egzotyczne podejście do zaczepiania. Prosty hak x86 jest bardziej wydajny i łatwy w utrzymaniu.
Reply
#9
Świetny!! rozwiązałeś moje problemy
Reply




Users browsing this thread: 1 Guest(s)