Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Disassembler: Länge der Instruction / Flags vorhanden? (https://www.delphipraxis.net/125218-disassembler-laenge-der-instruction-flags-vorhanden.html)

Zacherl 2. Dez 2008 16:35


Disassembler: Länge der Instruction / Flags vorhanden?
 
Hey,

ich versuche einen simplen Disassembler zu schreiben und habe hierfür nun schon eine Opcode Map angelegt. Nun ist mein Problem den Anfang einer Instruction zu finden. Anhand der Opcode Map kann ich zwar die Länge der Parameter, etc ermitteln, aber hiervor benötige ich erstmal den Opcode. Da vor dem Opcode aber noch die 1-4 Flagbytes stehen können, weiß ich nicht wo ich ansetzen soll, um den Opcode zu finden.

Gruß Zacherl

Apollonius 2. Dez 2008 16:43

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Die Präfixe sind eindeutig. In den Intel-Handbüchern sind alle möglichen Präfixe verzeichnet, danach kommt das erste Byte Opcode. Mit anderen Worten: Du überspringst zunächst alle Präfix-Bytes (F0, F2, F3, 2E, 36, 3E, 26, 64, 65, 66 und 67) und indizierst mit dem folgenden Byte die Opcode-Map. Bei einer Sache musst du allerdings aufpassen: Wenn auf bestimmte Präfix-Bytes das Byte 0F folgt, handelt es sich schon um den Anfang eines SIMD-Opcodes.

Zacherl 2. Dez 2008 17:05

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Soweit verstanden :) Kann es da keine Probleme geben wenn ich den Disassembler z.b. zwischen zwei Instructionen einsetzen lasse und der Opcode bei dem ich beginne zufällig gleich einem der Präfix Bytes ist?

Apollonius 2. Dez 2008 17:18

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Du brauchst einen gültigen Opcode-Anfang. Du kannst nicht mitten in den Anweisungs-Stream hineinfinden. Dies lässt sich auch am Delphi-Disassembler sehen: Wenn man in einer Assembler-Routine Direktiven wie dd verwendet, kommt erst einmal Nonsens raus, der auch weit über diese Definition hinausgehen kann, eben weil eine Anweisung "übergebunden" zu sein scheint. In der Praxis ist das allerdings selten ein Problem, da Calls und Jumps auf gültige Adressen verweisen und es außerdem innerhalb des Code-Segments häufig längere Blöcke von Nop oder Int 3 gibt (je nach Compiler): Dies sind Ein-Byte-Opcodes, sodass du am Ende eines solchen Blocks in jedem Fall eine neue Anweisung beginnt.

nicodex 2. Dez 2008 17:20

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Zitat:

Zitat von Zacherl
Kann es da keine Probleme geben wenn ich den Disassembler z.b. zwischen zwei Instructionen einsetzen lasse und der Opcode bei dem ich beginne zufällig gleich einem der Präfix Bytes ist?

Die Probleme wird es ohnehin geben, egal ob es nun ein Präfix ist, oder nicht. Du solltest vorher wissen, bei welchem Byte die Code-Bytes beginnen. Man kann das zwar ausprobieren, aber kurze Code-Sequenzen sind per Trial & Error kaum sicher zu erkennen.

Zacherl 2. Dez 2008 17:36

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Okay gut angenommen ich fange beim Anfang einer Instruction an. Nun ist der Opcode 3E und die Instruction hat keine Prefixe. Ich gehe hin, überspringe 3E brav, weil ich denke, dass es eine Prefix sein muss und lande bei den Suffixen oder der nächsten Instruction .. Was kann ich da machen?

Apollonius 2. Dez 2008 18:07

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Das kommt in gültigem Maschinencode nicht vor. Auf die Präfixe muss ein Opcode folgen.

Zacherl 2. Dez 2008 19:59

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Oki danke dir! Hab das ganze jetzt soweit fertig, dass bis zum ModR/M Byte geparst wird. Welche Werte sagen mir, dass ein SIB Byte folgen muss? Aus der Opcode Map war dies für mich nicht ersichtlich ..

Apollonius 2. Dez 2008 20:02

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Ein SIB-Byte gibt es, wenn R/M 4 und Mod 0, 1 oder 2 ist.

Zacherl 3. Dez 2008 13:09

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Perfekt. Eine Sache verwirrt noch .. es gibt ja ein paar wenige Befehle mit 3 Opcode Bytes. Das erste Byte ist dann entweder 2E oder 3E. Wie differenziere ich hier am besten zwischen Opcode Anfang und Prefix Byte?

Apollonius 3. Dez 2008 18:00

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Bist du dir sicher bezüglich 2E und 3E? Die Intel-Handbücher erwähnen nur folgende Formen für mehrbytige Opcodes:
0F - ein weiteres Byte
66/F2/F3 - 0F - ein weiteres Byte
0F - zwei weitere Bytes
66 - 0F - zwei weitere Bytes

Daher sind lediglich 66, F2 und F3 doppeldeutig, da sie als Flag-Präfix und als "mandatory prefix" für SIMD-Anweisungen auftauchen. Als Unterscheidungsmerkmal wird ausdrücklich das 0F-"escape opcode"-Byte genannt. F2 und F3 sind Repeat-Präfixe, die nur bei String-Anweisungen vorkommen, und 66 ist das Operandengröße-Präfix. Beides gibt bei SIMD-Anweisungen keinen Sinn.
Zu prüfen bleibt damit lediglich, wie viele Opcode-Bytes nach dem Escape Opcode Byte noch folgen. Hierfür solltest du dir eine Tabelle erstellen.

Zacherl 3. Dez 2008 18:34

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Ja meinte F2 und F3, oki also es klappt jetzt, dass ich 1-Byte Opcodes erkenne, 2-Byte Opcodes mit 0F am Anfang und 3-Byte Opcodes mit 66/F2/F3-F0-XX. Fehlt noch 66-0F-XX-XX, die ich dann per Tabelle prüfen werde. Bei F2, etc prüfe ich einfach, ob direkt danach 0F kommt.

Gibts die Intel Dokumentation für die Instructions irgendwo im PDF Format oder so? Habe das hier gefunden: http://gec.di.uminho.pt/Discip/Lesi/...4ISAformat.pdf Soweit ganz nett erklärt, wobei ich bei der 32 Bit Tabelle fürs ModRM Byte nicht weiterkomme.

Code:
add bl, [456]
add ebx, [456]
Erzeugen beispielsweise das selbe ModRM Byte (Mod 0, Reg 3, RM 5). Jetzt weiß ich nicht, welches Register effektiv verwendet wurde.

EDIT: Shiat :mrgreen: Nur verguckt .. Einmal ist Opcode 3 und einmal 2. Aber die Referenz wäre trotzdem cool :)

Apollonius 3. Dez 2008 18:55

Re: Disassembler: Länge der Instruction / Flags vorhanden?
 
Zitat:

Zitat von Zacherl
Gibts die Intel Dokumentation für die Instructions irgendwo im PDF Format oder so?

Ich habe mich schon gefragt, wann du dich danach erkundigen würdest. Hier wirst du fündig. Die anderen Handbücher wie z.B. der System Programming Guide sind als Lektüre übrigens auch recht interessant.

Das die beiden Anweisungen das selbe ModR/M-Byte haben, ist klar. Es wird nur zwischen verschiedenen Register-Kategorien unterschieden. ebx, bx und bl fallen beispielsweise in eine Kategorie. Die Operanden-Größe kennst du aus dem Opcode (dort kannst du zwischen 8 und 16/32 Bit unterscheiden), den Einstellungen des Code-Segments (16 oder 32 Bit, in Windows immer 32 Bit solange du keine speziellen Vorkehrungen für 16-Bit-Programme unternimmst) und dem Override Prefix, welches die Einstellung des Code-Segments umkehrt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:24 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz