Wie kann man Programme dazu bringen zu glauben, sie würden unter 32-Bit laufen?

Wie kann man Programme dazu bringen zu glauben, sie würden unter 32-Bit laufen?

Grundsätzlich habe ich 3 ausführbare Dateien in meinem Windows 7 64-Bit, und zwar:

Loader.exe-> Dies ist eine 32-Bit-Exe 

x86.exe-> Dies ist eine 32-Bit-Exe

x64.exe-> Dies ist eine 64-Bit-Exe

WannLoader.exeBeim Start wird festgestellt, ob das System 32-Bit oder 64-Bit ist und die entsprechende Datei wird geladen (entwederx86.exeoderx64.exe), da ich ein 64-Bit-Betriebssystem verwende,x64.exewird beginnen.

Ich möchte wissen, wieLoader.exebestimmt, ob mein System 32 oder 64 ist? Das ist höchstwahrscheinlich durch den API-AufrufKernel32.IsWow64Process()

Jetzt muss ich dafür sorgen, dass die Funktion immer FALSE zurückgibt, und zwar global und nicht nur fürLoader.exe, Ich hatte also auf etwas in der Art eines „globalen API-Hooks“ gehofft, der dafür sorgt, dass die Funktion immer FALSE zurückgibt.

Ich weiß aber nicht, wie das geht. Das letzte Mal, dass ich etwas angeschlossen habe, war unter Windows 98, und seitdem hat sich einiges geändert.

Wissen Sie zufällig, wie man HookIsWow64Process()und dem Prozess dadurch vorgaukeln, dass er in einer 32-Bit-Umgebung ausgeführt wird?

Antwort1

Nachdem ich mich stundenlang mit der Windows-API (und der nicht dokumentierten API) sowie Zeigern und vielem mehr beschäftigt hatte, fand ich endlich heraus, wie es geht. Es war ziemlich knifflig, dennIsWow64Process()wird von Windows für jede ausführbare Datei aufgerufen, noch bevor das Programm seinen Einstiegspunkt erreicht. Wenn Sie einfach FALSE anzeigen, stürzt es ab.

Mir ist jedoch aufgefallen, dass die Aufrufe von Windows von geladenen Modulen stammen. Auf diese Weise kann ich meinen Hook so einschränken, dass er nur dann FALSE ausgibt, wenn der Anrufer eine ausführbare Datei ist.

Hier ist eine kleine Anleitung, wie es gemacht wurde:

  1. Holen Sie sich die Rücksprungadresse 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);
    
  2. 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;
    

Aber hier ist ein weiteres Problem,IsWow64Process()existiert nur auf 64-Bit-Betriebssystemen von Windows, daher führen die meisten Programme, die tatsächlich prüfen, ob es sich bei dem Betriebssystem um ein 64-Bit-System handelt, diese Funktion nicht aus, sondern fragen stattdessen, ob die Funktion verfügbar ist und ermitteln so, ob es sich bei dem System um ein 32-Bit- oder ein 64-Bit-System handelt.

Dies geschieht durch den AnrufGetProcAddress().

Bedauerlicherweise,GetProcAddress()wird in meinem Quellcode verwendet, um Funktionsadressen zu finden, und das Einhängen der Funktion führt natürlich zu unerwünschtem Verhalten, also tauchen wir etwas tiefer in die undokumentierte API ein und finden heraus, dassKernel32.GetProcAddress()Anrufentdll.LdrGetProcedureAddress().

Nachdem ich ein bisschen im Internet gelesen habe, bin ich jetzt sicher, dass es sicher ist,LdrGetProcedureAddress().

In unserem süchtigLdrGetProcedureAddress()Funktion prüfen wir, ob der Anrufer anfordertIsWow64Processund teilen Sie dem Anrufer mit, dass die FunktionNICHTexistieren!

Nun müssen wir unseren Hook in jeden (neuen) Prozess einfügen. Ich habe mich für denAppInit_DLLsMethode, weil ich damit bereits vertraut bin und sie sehr gut funktioniert.

Es gibt viele Informationen überAppInit_DLLsim Internet, aber alle beziehen sich auf 32-Bit und ihre Lösung funktioniert nicht wirklich auf meinem 64-Bit-Betriebssystem Windows 7. Um es Ihnen einfacher zu machen, sind 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

Legen wir festLoadAppInit_DLLsauf 0x1 undAppInit_DLLszu unserem DLL-Pfad.

Hier ist der endgültige Quellcode, er verwendetmhook-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;
}

Antwort2

Sie können ein 64-Bit-Programm niemals zwingen, als 32-Bit-Programm zu laufen. Denn 64-Bit-Programme werden als 64-Bit-Anweisungen auf einmal zusammengestellt. Aber wenn Sie ein 32-Bit-Programm auf einem 64-Bit-Prozessor laufen lassen, konvertiert das Betriebssystem 32-Bit-Systemaufrufe in das 64-Bit-Format. Die gleiche Frage wurde hier beantwortet. Sehen Sie sich das an. Erzwingen Sie die Ausführung der Anwendung in einem 32-Bit-Prozess unter 64-Bit-Windows

verwandte Informationen