64-Bit-Windows-VMware-Erkennung

9

Ich versuche eine Anwendung zu entwickeln, die erkennt, ob das Programm in einer virtuellen Maschine läuft.

Für 32-Bit-Windows gibt es bereits Methoden, die im folgenden Link erklärt werden: Ссылка

Ich versuche, den Code bezüglich der Erkennung von virtuellen PCs und VMware in einem 64-Bit-Windows-Betriebssystem anzupassen. Für VMware kann der Code in einem Windows XP 64-Bit-Betriebssystem erfolgreich erkannt werden. Aber das Programm stürzt ab, wenn ich es in einem nativen System (Windows 7 64-Bit-Betriebssystem) ausführe.

Ich habe den Code in eine .asm-Datei geschrieben und einen benutzerdefinierten Build-Schritt mit der Datei ml64.exe definiert. Der Asm-Code für 64-Bit-Windows lautet:

%Vor%

Ich nenne diesen Teil in einer cpp-Datei wie:

%Vor%

Vielen Dank im Voraus.

    
bugra 10.04.2012, 12:03
quelle

2 Antworten

4

Die alte rote Pille aus Joanna funktioniert möglicherweise: Zufallssicherungsseite von invisiblethings.org blog :

  

Das Schlucken der roten Pille entspricht mehr oder weniger dem folgenden Code (gibt in der Matrix nicht null aus):

%Vor%      

Das Herz dieses Codes ist eigentlich der SIDT-Befehl (kodiert als 0F010D [addr]), der den Inhalt des Interruptdeskriptortabellenregisters (IDTR) im Zieloperanden speichert, der eigentlich ein Speicherort ist. Das Besondere und Interessante an der SIDT-Anweisung ist, dass sie im nicht privilegierten Modus (Ring3) ausgeführt werden kann, aber den Inhalt des sensiblen Registers zurückgibt, das intern vom Betriebssystem verwendet wird.

     

Da es nur ein IDTR-Register gibt, aber mindestens zwei Betriebssysteme gleichzeitig ausgeführt werden (dh der Host und das Gastbetriebssystem), muss VMM die IDTR des Gasts an einen sicheren Ort verschieben, damit es nicht mit a kollidiert des Gastgebers. Leider kann VMM nicht wissen, ob (und wann) der Prozess im Gastbetriebssystem den SIDT-Befehl ausführt, da er nicht privilegiert ist (und keine Ausnahme erzeugt). Somit erhält der Prozess die ausgelagerte Adresse der IDT-Tabelle. Es wurde beobachtet, dass die verschobene Adresse von IDT unter VMWare die Adresse 0xffXXXXXX hat, während sie auf Virtual PC 0xe8XXXXXX ist. Dies wurde auf VMWare Workstation 4 und Virtual PC 2004 getestet, beide unter Windows XP Host OS.

Hinweis: Ich habe es nicht selbst getestet, aber schau, dass es einen unprivilegierten Ansatz verwendet. Wenn es für x64 zunächst nicht funktioniert, können einige Optimierungen helfen.

Sie haben auch eine Frage mit Inhalten gefunden, die Ihnen helfen können: VMM unter Linux erkennen

    
pepper_chico 11.04.2012 01:22
quelle
0

Meine Vermutung ist, dass Ihre Funktion sich registrieren lässt.

Das Ausführen auf echter Hardware (Nicht-VM) sollte wahrscheinlich eine Ausnahme bei "in rax, dx" auslösen. Wenn dies geschieht, wird die Steuerung an Ihren Ausnahmebehandler übergeben, der das Ergebnis setzt, Register jedoch nicht wiederherstellt. Dieses Verhalten wird vom Aufrufer völlig unerwartet sein. Zum Beispiel kann es etwas in EBX / RBX-Register speichern, dann rufen Sie Ihren Asm-Code, Ihr Asm-Code macht "mov RBX, 0", es führt aus, fängt Ausnahme, setzt Ergebnis, zurück - und dann erkennt der Anrufer plötzlich, dass seine gespeicherten Daten ist nicht mehr in EBX / RBX! Wenn in EBX / RBX ein Zeiger gespeichert war, stürzt man schwer ab. Alles kann passieren.

Sicher, Ihr ASM-Code speichert / wiederherstellt Register, aber dies geschieht nur, wenn keine Ausnahme ausgelöst wird. I.e. wenn der Code auf der VM ausgeführt wird. Dann führt der Code seinen normalen Ausführungspfad aus, es werden keine Ausnahmen ausgelöst, die Register werden normal wiederhergestellt. Aber wenn es die Ausnahme gibt - Ihre POPs werden übersprungen, weil die Ausführung an den Ausnahmebehandler übergeben wird.

Der richtige Code sollte wahrscheinlich PUSH / POPs außerhalb von try / except Block, nicht innerhalb von.

    
Alex 22.05.2015 03:43
quelle