Seltsame Dinge, die ich beim Schreiben eines x86-Emulators gelernt habe
- Erläutert verschiedene Trivia und Seltsamkeiten, die beim Schreiben von x86- und amd64-Emulatoren aufgefallen sind
- Beim Time Travel Debugging (TTD) wird ein CPU-Emulator verwendet, um die Ausführung eines Prozesses auf Instruktionsebene aufzuzeichnen
- Die erste Version von TTD hieß iDNA, war in Assembler geschrieben, schnell, aber schwer wartbar
- Die zweite Version wurde in C++ geschrieben und war dadurch besser wartbar
Nutzlose x86-Encoding-Trivia
- Das x86-Encoding-Schema erlaubt es, dieselbe Instruktion auf verschiedene Arten zu encodieren
- Die Instruktion
int 3 kann als CD 03 oder CC encodiert werden
- Das Register
EAX wird „Akkumulator-Register“ genannt und unterscheidet sich tatsächlich beim Encoding
- Das
REX-Präfix ermöglicht in 64-Bit-Code den Zugriff auf einen größeren Registerbereich
- Instruktionen können bis zu 15 Byte lang sein; bei Überschreitung wird eine Ausnahme ausgelöst
- Das Address-Override-Präfix ermöglicht es, im 64-Bit-Modus 32-Bit-Adressen zu referenzieren
Seltsame Eigenschaften von Flags
- Die Instruktion
INC aktualisiert im Gegensatz zu ADD nicht das Carry-Flag
- Die Instruktionen
CMPXCHG8B/CMPXCHG16B ändern nur das Zero-Flag
- Shift- und Rotate-Instruktionen lassen das Overflow-Flag undefiniert, wenn die Shift-Menge größer als 1 ist
Noch mehr Überraschungen bei Shift-Instruktionen
shr ax, 10h verschiebt das Register ax um 16 Bit und macht es zu 0
shr eax, 20h verschiebt das Register eax um 32 Bit, aber der Wert ändert sich nicht
- Die Shift-Menge wird mit
1FH maskiert
Segment-Overrides
- Segmente werden in 32-Bit- und 64-Bit-Code weiterhin verwendet, hauptsächlich für Thread Local Storage
- Unter Windows wird über die Register
FS oder GS auf den TEB (Thread Execution Block) verwiesen
- In 32-Bit-Prozessen wird
FS verwendet, in 64-Bit-Prozessen GS
- Im 64-Bit-Modus ist der Wert des Segmentregisters selbst nicht wichtig
Segment-Overrides: noch mehr Trivia
- Im 32-Bit-Modus verweist der tatsächliche Wert des Segmentregisters auf den Segment-Deskriptor
- Im 64-Bit-Modus wird die Basis durch das MSR gesteuert
- In WinDbg kann man die Segmentwerte eines 64-Bit-Prozesses nicht direkt auslesen
Fazit
- Dieser Beitrag liefert eine zufällige Liste von x86-Trivia
- Das Schreiben eines Emulators hilft dabei, ein tiefes Verständnis dafür zu entwickeln, wie eine CPU funktioniert
- Auf der Website von Agner Fog gibt es hervorragende Ressourcen
Zusammenfassung von GN⁺
- Erläutert verschiedene Trivia und Seltsamkeiten, die beim Schreiben von x86- und amd64-Emulatoren aufgefallen sind
- Das Schreiben eines Emulators hilft dabei, die Funktionsweise einer CPU tief zu verstehen
- Behandelt verschiedene Trivia wie unterschiedliche Encoding-Methoden für die Instruktion
int 3, das REX-Präfix und Segment-Overrides
- Weitere Ressourcen gibt es auf der Website von Agner Fog
1 Kommentare
Hacker-News-Kommentar