Nachdem ich mich stundenlang mit der Windows-API (und der nicht dokumentierten API) sowie mit Zeigern und was nicht beschäftigt hatte, habe ich endlich herausgefunden, wie das geht. Es war ein bisschen schwierig, weil IsWow64Process () von Windows für jede ausführbare Datei aufgerufen wird, noch bevor das Programm seinen EntryPoint erreicht. Wenn Sie nur FALSE spiegeln, wird dies zum Absturz führen.
Ich habe jedoch festgestellt, dass die Aufrufe des Fensters von geladenen Modulen kommen. Auf diese Weise kann ich meinen Hook so einschränken, dass er nur dann FALSCH ist, wenn der Aufrufer eine ausführbare Datei ist.
Hier ist eine kleine Anleitung, wie es gemacht wurde:
Rufen Sie die Absenderadresse meines Hooks ab und finden Sie heraus, in welchem Modul meine Hook-Funktion aufgerufen wurde:
wchar_t RetAdr[256]; wsprintf(RetAdr, L"%p", _ReturnAddress()); HMODULE hModule; GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, RetAdr, &hModule);
Nehmen Sie den ModuleFileName, prüfen Sie, ob er ".exe" enthält, und setzen Sie die Variable "Wow64Process" auf FALSE, wenn es sich um eine ausführbare Datei handelt:
wchar_t mName[MAX_PATH]; GetModuleFileName(hModule, mName, sizeof(mName)); const wchar_t *shortName = L".exe"; BOOL res = TRUE; if(wcsstr(mName,shortName) == NULL) res = Orig_IsWow64Process(hProcess, Wow64Process); else *Wow64Process = FALSE; return res;
Hier ist jedoch ein weiteres Problem: IsWow64Process () existiert nur unter Windows 64-Bit-Betriebssystemen. Daher führen die meisten Programme, die tatsächlich prüfen, ob das Betriebssystem 64-Bit ist, diese Funktion nicht aus, sondern fragen, ob die Funktion verfügbar ist Stellen Sie fest, ob das System 32-Bit oder 64-Bit ist.
Sie tun dies, indem Sie GetProcAddress () aufrufen .
Leider GetProcAddress () wird in meinem Source - Code verwendet Funktionsadressen zu finden, und die Funktion wird natürlich zu unerwünschtem Verhalten Einhaken, so tauchen wir ein wenig tiefer in die nicht dokumentierte API und wir herausfinden, dass Kernel32.GetProcAddress () ruft ntdll .LdrGetProcedureAddress () .
Nach dem Lesen eines Abit im Internet bin ich jetzt sicher, dass es sicher ist, LdrGetProcedureAddress () zu haken .
In unserer Hooked LdrGetProcedureAddress () - Funktion überprüfen wir, ob der Aufrufer nach IsWow64Process fragt, und teilt dem Aufrufer mit, dass die Funktion NICHT vorhanden ist!
Jetzt müssen wir unseren Haken in jeden (neuen) Prozess einfügen. Ich entschied mich für die AppInit_DLLs- Methode, da ich sie bereits kenne und die Arbeit sehr gut macht.
Es gibt viele Informationen über AppInit_DLLs im Web, aber alle beziehen sich auf 32-Bit und ihre Lösung funktioniert auf meinem Windows 7-Betriebssystem mit 64-Bit nicht wirklich. Um es Ihnen einfacher zu machen, hier die richtigen Registrierungspfade für 32-Bit- und 64-Bit-AppInit_DLLs:
32-Bit : HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ CurrentVersion \ Windows
64-Bit : HKEY_LOCAL_MACHINE \ Software \ Wow6432Node \ Microsoft \ Windows NT \ CurrentVersion \ Windows
Wir setzen LoadAppInit_DLLs auf 0x1 und AppInit_DLLs auf unseren DLL-Pfad.
Hier ist der endgültige Quellcode, er verwendet die mhook-Bibliothek :
#include "stdafx.h" #include "mhook/mhook-lib/mhook.h" #include <intrin.h> #ifdef __cplusplus extern "C" #endif void * _ReturnAddress(void); #pragma intrinsic(_ReturnAddress) ////////////////////////////////////////////////////////////////////////// // Defines and typedefs typedef NTSTATUS (NTAPI* _ldrGPA)(IN HMODULE ModuleHandle, IN PANSI_STRING FunctionName OPTIONAL, IN WORD Oridinal OPTIONAL, OUT PVOID *FunctionAddress ); typedef BOOL (WINAPI *_IsWow64Process)( __in HANDLE hProcess, __out PBOOL Wow64Process ); ////////////////////////////////////////////////////////////////////////// // Original function PVOID HookWow, OrigWow; _IsWow64Process Orig_IsWow64Process = (_IsWow64Process) GetProcAddress(GetModuleHandle(L"Kernel32"), "IsWow64Process"); _ldrGPA Orig_ldrGPA = (_ldrGPA) GetProcAddress(GetModuleHandle(L"ntdll"), "LdrGetProcedureAddress"); ////////////////////////////////////////////////////////////////////////// // Hooked function NTSTATUS NTAPI Hooked_ldrGPA(IN HMODULE ModuleHandle, IN PANSI_STRING FunctionName OPTIONAL, IN WORD Oridinal OPTIONAL, OUT PVOID *FunctionAddress) { //16:00 check if FunctionName equals IsWow64Process then return NULL return Orig_ldrGPA(ModuleHandle,OPTIONAL FunctionName, OPTIONAL Oridinal, FunctionAddress); } BOOL WINAPI HookIsWow64Process( __in HANDLE hProcess, __out PBOOL Wow64Process ) { HMODULE hModule; wchar_t RetAdr[256]; wsprintf(RetAdr, L"%p", _ReturnAddress()); GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, RetAdr, &hModule); wchar_t mName[MAX_PATH]; GetModuleFileName(hModule, mName, sizeof(mName)); const wchar_t *shortName = L".exe"; BOOL res = TRUE; if(wcsstr(mName,shortName) == NULL) res = Orig_IsWow64Process(hProcess, Wow64Process); else *Wow64Process = FALSE; return res; } ////////////////////////////////////////////////////////////////////////// // Entry point BOOL WINAPI DllMain( __in HINSTANCE hInstance, __in DWORD Reason, __in LPVOID Reserved ) { switch (Reason) { case DLL_PROCESS_ATTACH: OrigWow = Orig_IsWow64Process; HookWow = HookIsWow64Process; Mhook_SetHook((PVOID*)&Orig_IsWow64Process, HookIsWow64Process); Mhook_SetHook((PVOID*)&Orig_ldrGPA, Hooked_ldrGPA); break; case DLL_PROCESS_DETACH: Mhook_Unhook((PVOID*)&Orig_IsWow64Process); Mhook_Unhook((PVOID*)&Orig_ldrGPA); break; } return TRUE; }