Wie können Sie Programme dazu bringen, zu denken, dass sie unter 32-Bit laufen?

16422
Æless Norm

Grundsätzlich habe ich 3 ausführbare Dateien in meinem Windows 7 64-Bit.

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

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

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

Beim Start von Loader.exe wird festgestellt, ob es sich um ein 32-Bit- oder 64-Bit-System handelt, und die entsprechende Datei (entweder x86.exe oder x64.exe ) wird geladen, da x64.exe auf einem 64-Bit-Betriebssystem ausgeführt wird Start.

Ich würde gerne wissen, wie Loader.exe ermittelt, ob mein System 32 oder 64 ist? Welches ist am wahrscheinlichsten durch den API-Aufruf Kernel32.IsWow64Process ()

Jetzt muss ich dafür sorgen, dass diese Funktion immer FALSCH zurückgegeben wird, und zwar nicht nur für Loader.exe, sondern auf globaler Ebene. Also hoffte ich etwas in der Art eines "globalen API-Hooks", wodurch die Funktion immer FALSCH zurückgibt .

Aber ich weiß nicht, wie ich das machen soll, das letzte Mal, dass ich etwas in Windows 98 süchtig gemacht habe, hat sich seitdem geändert.

Wissen Sie also, wie Sie IsWow64Process () anhängen und dadurch den Prozess glauben machen, dass es in einer 32-Bit-Umgebung läuft?

7
Dies variiert je nach Betriebssystem. Die meisten Programme verteilen lediglich eine separate Binärdatei für 32/64-Bit-Systeme, wobei die Verteilungsmethode entscheidet, welche Methode sie verwenden soll (die wiederum je nach Betriebssystem variiert). Bob vor 12 Jahren 0
Entschuldigung, ich habe vergessen zu erwähnen, dass es Windows 7 ist. Und es gibt eine ausführbare "loader" -Datei, die entscheidet, welche Version ausgeführt wird Æless Norm vor 12 Jahren 0
Ich denke, für Antworten, die sinnvoll sind, müssen Sie erklären, warum Sie "Programme zum Nachdenken anregen wollen ... 32bit". Martin vor 12 Jahren 0
Können Sie Ihre Frage bitte bearbeiten und die Antwort in den Antwortbereich verschieben? Sathya vor 12 Jahren 4
*> Ich würde gerne wissen, wie [Kernel32.IsWow64Process ()] erstellt wird ... immer auf globaler Ebene FALSE zurückgeben. * Das ist unmöglich; Das System würde furchtbar abstürzen (wenn es überhaupt booten kann) und möglicherweise sogar explodieren oder Sie mit Ebola infizieren. Synetech vor 12 Jahren 0
@ ÆlessNorm Wenn Sie jemals zurückkehren, hinterlassen Sie hier einen Kommentar, und wir können die Antwort Ihrem Benutzerkonto erneut zuordnen. nhinkle vor 12 Jahren 1

2 Antworten auf die Frage

7
Æless Norm

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:

  1. 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); 
  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; 

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; } 
0
arundevma

Sie können niemals ein 64-Bit-Programm als 32-Bit-Programm ausführen. Weil 64-Bit-Programme zu einem Zeitpunkt als 64-Bit-Anweisungen zusammengestellt werden. Wenn Sie jedoch ein 32-Bit-Programm auf einem 64-Bit-Prozessor ausführen, konvertiert das System 32-Bit-Systemaufrufe in das 64-Bit-Format. Die gleiche Frage wurde hier beantwortet. Erzwingen Sie die Ausführung der Anwendung in einem 32-Bit-Prozess unter 64-Bit-Windows

Genau, wenn nicht nachgebildet, aber das würde es extrem langsam machen ... Tom Wijsman vor 12 Jahren 1
Bitte kennzeichnen Sie doppelte Fragen als solche, anstatt sie zu beantworten. Vielen Dank. ChrisF vor 12 Jahren 7
Verstehen Sie mich richtig, ich zwinge ein kompiliertes 64-Bit-Programm nicht zur Ausführung in einer 32-Bit-Umgebung. Ich zwinge eine loader.exe zu glauben, dass das System 32-Bit ist, und lade daher die 32-Bit-Version des Programms anstelle der 64-Bit-Version. Æless Norm vor 12 Jahren 1
@ ÆlessNorm Ich dachte, du würdest dich ziemlich gut erklären. Sie versuchen ** NICHT **, x64.exe als 32-Bit-Ausführung auszuführen. Sie versuchen, Loader.exe zu erzwingen, das ein 32-Bit-Programm ist, um das 32-Bit-Programm x86.exe in einer 64-Bit-Umgebung zu laden. Ich verstehe insbesondere nicht, warum diese Antwort gewählt wurde Wenn Sie einen Link zu derselben Frage bereitstellten, wiesen Sie darauf hin, dass Ihre Frage ausdrücklich NICHT ein Duplikat war. Bon Gart vor 12 Jahren 4
@ ÆlessNorm Lassen Sie mich eine Frage stellen, wenn Sie ein 32-Bit-Programm ausführen möchten, warum Sie x64.exe nicht entfernen und x32.exe alleine verwenden. arundevma vor 12 Jahren 0
@ gladiator2345 Stellen Sie sich vor, als würde Loader.exe diese Dateien zur Laufzeit erstellen. Es gibt keine Möglichkeit für mich, einfach auf x32.exe zu doppelklicken und sie zu starten. Wie auch immer, ich habe herausgefunden, wie man 32-Bit nach Stunden des Kopfens um Zeiger erzwingen kann, aber ich werde mich nicht darum kümmern, meine eigene Frage zu beantworten, da dieses Thema jetzt ohne Grund geschlossen ist. Æless Norm vor 12 Jahren 0
@less Norm Sie sollten es in stackoverflow und nicht in superuser fragen, da es mit der Programmierung zusammenhängt. Deshalb wurde Ihre Frage von den meisten von uns falsch interpretiert. Wenn Sie im Stack-Überlauf gefragt hätten, hätte es gute Antworten gegeben. arundevma vor 12 Jahren 0