Nachdem ich mich stundenlang mit der Windows-API (und der undokumentierten API) sowie den Zeigern und was nicht beschäftigt hatte, fand ich endlich heraus, wie es geht. Es war etwas knifflig, da IsWow64Process () von Windows auf jeder ausführbaren Datei aufgerufen wird, noch bevor das Programm seinen EntryPoint erreicht. Wenn Sie nur FALSE widerspiegeln, wird es abstürzen.
Ich habe jedoch festgestellt, dass die Aufrufe des Fensters von geladenen Modulen stammen. Auf diese Weise kann ich meinen Hook so einschränken, dass er nur FALSE widerspiegelt, wenn der Aufrufer eine ausführbare Datei ist.
Hier ist eine kleine Anleitung, wie es gemacht wurde:
Holen Sie sich die Absenderadresse meines Hooks und finden Sie heraus, welches Modul meine Hook-Funktion aufgerufen hat:
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, überprü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;
Aber hier ist 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 und damit Stellen Sie fest, ob das System 32-Bit oder 64-Bit ist.
Sie rufen dazu GetProcAddress () auf .
Leider GetProcAddress () wird in meinem Source - Code verwendet Funktionsadressen zu finden, und die Funktion wird natürlich zu unerwünschtem Verhalten Einhaken, so dass wir ein wenig tiefer in die nicht dokumentierte API vertiefen und wir herausfinden, dass Kernel32.GetProcAddress () ruft ntdll .LdrGetProcedureAddress () .
Nachdem ich abit im Internet gelesen habe, bin ich mir jetzt sicher, dass es sicher ist, LdrGetProcedureAddress () zu verknüpfen .
In unserer verknüpften Funktion LdrGetProcedureAddress () prüfen wir, ob der Aufrufer nach IsWow64Process fragt, und teilen dem Aufrufer mit, dass die Funktion NICHT vorhanden ist!
Jetzt müssen wir unseren Hook in jeden (neuen) Prozess einfügen. Ich habe mich für die AppInit_DLLs- Methode entschieden, da ich bereits damit vertraut bin und sie sehr gut funktioniert.
Es gibt viele Informationen über AppInit_DLLs im Web, aber alle beziehen sich auf 32-Bit und ihre Lösung funktioniert unter meinem Windows 7 64-Bit-Betriebssystem nicht wirklich. Um es Ihnen einfacher zu machen, finden Sie 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, der die mhook-Bibliothek verwendet :
#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;
}