Wie kann man Programme dazu verleiten, zu glauben, dass sie unter 32-Bit laufen?

7

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

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

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

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

Wenn Loader.exe beginnt sie bestimmt , ob das System 32-Bit oder 64-Bit und lädt die entsprechende Datei (entweder x86.exe oder x64.exe ), da ich das ein 64-Bit - Betriebssystem renne x64.exe wird Start.

Ich möchte wissen, wie Loader.exe feststellt, ob mein System 32 oder 64? Welches ist am wahrscheinlichsten über den API-Aufruf Kernel32.IsWow64Process ()

Jetzt muss ich dafür sorgen, dass diese Funktion immer FALSE zurückgibt , auf globaler Ebene und nicht nur für Loader.exe . Ich hatte also gehofft, dass etwas wie ein "globaler API-Hook" funktioniert, wodurch die Funktion immer FALSE zurückgibt.

Aber ich weiß nicht, wie ich das machen soll. Das letzte Mal, dass ich etwas angeschlossen habe, war Windows 98, und seitdem haben sich die Dinge geändert.

Wissen Sie also zufällig, wie Sie IsWow64Process () einbinden und damit den Prozess glauben lassen, dass er in einer 32-Bit-Umgebung ausgeführt wird?

Æless Norm
quelle
Dies hängt vom Betriebssystem ab. Die meisten Programme verteilen nur eine separate Binärdatei für 32/64-Bit-Systeme, wobei die Verteilungsmethode entscheidet, welche verwendet werden soll (was wiederum je nach Betriebssystem variiert)
Bob
Es tut mir leid, dass ich vergessen habe zu erwähnen, dass es Windows 7 ist. Und es gibt eine ausführbare "Loader"
-Datei,
Ich denke, damit Antworten Sinn machen, müssen Sie erklären, warum Sie "Programme zum Denken verleiten wollen ... 32bit"
Martin
4
Können Sie bitte Ihre Frage bearbeiten und die Antwort in den Antwortbereich verschieben?
Sathyajith Bhat
1
@ ÆlessNorm Wenn Sie jemals zurückkehren, hinterlassen Sie hier einen Kommentar und wir können die Antwort Ihrem Benutzerkonto erneut zuordnen.
nhinkle

Antworten:

7

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:

  1. 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);
    
  2. 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;
}
Æless Norm
quelle
0

Sie können niemals erzwingen, dass ein 64-Bit-Programm als 32-Bit ausgeführt wird. Da 64-Bit-Programme gleichzeitig als 64-Bit-Anweisungen zusammengestellt werden. Wenn Sie jedoch ein 32-Bit-Programm auf einem 64-Bit-Prozessor ausführen, konvertiert das Betriebssystem 32-Bit-Systemaufrufe in das 64-Bit-Format. Die gleiche Frage wurde hier beantwortet. Erzwingen Sie die Ausführung der Anwendung im 32-Bit-Prozess unter 64-Bit-Windows

Arundevma
quelle
1
Genau, wenn nicht emuliert, aber das würde es extrem langsam machen ...
Tamara Wijsman
7
Bitte kennzeichnen Sie doppelte Fragen als solche, anstatt sie zu beantworten. Vielen Dank.
ChrisF
1
Verstehen Sie mich richtig, ich zwinge ein kompiliertes 64-Bit-Programm nicht dazu, in einer 32-Bit-Umgebung ausgeführt zu werden. Ich zwinge eine loader.exe zu der Annahme, dass das System 32-Bit ist, und lade daher die 32-Bit-Version des Programms anstelle der 64-Bit-Version.
Ohne Norm
4
@ ÆlessNorm Ich dachte du hast dich ziemlich gut erklärt. Sie versuchen NICHT , x64.exe als 32-Bit auszuführen. Sie versuchen Loader.exe zu zwingen, das ist ein 32 - Bit - Programm , um immer das x86.exe 32 - Bit - Programm zu laden zu wählen, während sie in einer 64 - Bit - Umgebung ... ich besonders verstehe nicht , warum diese Antwort gewählt wurde oben, wenn Es enthielt einen Link zu derselben Frage, auf die SIE hingewiesen haben, dass Ihre Frage ausdrücklich KEIN Duplikat von war.
Bon Gart
@ ÆlessNorm Lassen Sie mich eine Frage stellen: Wenn Sie immer ein 32-Bit-Programm ausführen möchten, warum entfernen Sie x64.exe nicht und verwenden Sie x32.exe allein.
Arundevma