Feage zu Jumps im Virtual Address Space
-
Festplatte schrieb:
Hat das was mit dem RVA(Relative Virtual Address) zu tun?
nein.
Hier ist gemeint, dass der immediate operand des JMP-Befehls ein relatives Offset ist. Die tatsächliche Sprungadresse muss als noch berechnet werden.Festplatte schrieb:
Die Werte die dort stehen nennt man doch Offset oder? Ich hab mal irgendwo gelesen das dass Adresse heisst und nicht Offset.
ein Offset bezieht sich immer auf Irgendetwas: in diesem Fall wäre 0x401000 ein Offset relativ zur Basis des Code Segments - da aber das flat model vorliegt, und die Basisadresse immer Null ist, handelt es sich um eine Adresse im (virtuellen) Adressraum.
-
Man sieht ja direkt am hexwert, wohin der Jump geht. In diesem Fall 12d vorwärts. Wenn es nach hinten geht, wird von 100h abgezogen, auch wieder ausgehend vom Ende des Jumpbefehls.
-
Wie das mit den short jumps funktioniert habe ich ja jetzt verstanden. Aber wie läuft das beim long Jump?
z.b.
JMP LONG 840000
Erstellt folgendes:
00401012 -E9 E9EF4300 JMP 00840000 00401017 90 NOP 00401018 90 NOP
Ich hab schon versucht es so zu berechnen wie ich es beim short jump machen würde aber das funktioniert leider beim
JUMP LONG
nicht.
-
Du must bedenken das alle diese Übersetzerprogramme versuchen den kürzesten Code zu erstellen.
Wenn es also nicht notwendig ist einen Long Jmp zu machen so wird er zugunsten eines anderen ersetzt.
-
Aber irgendwie muss man das doch berechnen können ...
-
Festplatte schrieb:
Aber irgendwie muss man das doch berechnen können ...
Zieladresse - (Adresse JMP + 5)
-
Bei long jump ist es ganz einfach so, dass das übliche Byte für die Addressenangabe nicht mehr ausreicht. Wenn man früher Far-Jumps gemacht hatte, dann ging es über mehrere Segmente, d.h. das Code-Segment musste mit verändert werden.
in Windows gibt es keine Segmente, alles flat.
(in debugx.com
-rx 386 regs on -a 900 1B1F:0900 jmp 100 1B1F:0903 -d 900 910 1B1F:0900 E9 FD F7 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 1B1F:0910 00 - . -u 900 910 1B1F:0900 E9FDF7 JMP 0100 1B1F:0903 0000 ADD [BX+SI],AL 1B1F:0905 0000 ADD [BX+SI],AL 1B1F:0907 0000 ADD [BX+SI],AL 1B1F:0909 0000 ADD [BX+SI],AL 1B1F:090B 0000 ADD [BX+SI],AL 1B1F:090D 0000 ADD [BX+SI],AL 1B1F:090F 0000 ADD [BX+SI],AL -
Die Adresse da oben muss man jetzt so lesen:
E9 F7 (800 rückwärts, F8) FD (3 rückwärts) (gesamt F7FD)
-
nachtfeuer schrieb:
Bei long jump ist es ganz einfach so, dass das übliche Byte für die Addressenangabe nicht mehr ausreicht. Wenn man früher Far-Jumps gemacht hatte, dann ging es über mehrere Segmente, d.h. das Code-Segment musste mit verändert werden.
in Windows gibt es keine Segmente, alles flat.
Natürlich gibt es nach wie vor Segmente, nur das die meisten die Basis 0 haben. Far jumps oder calls sind auch möglich, aber nicht nutzbar, da windows segment discriptors nicht dokumentiert sind.
nachtfeuer schrieb:
Die Adresse da oben muss man jetzt so lesen:
E9 F7 (800 rückwärts, F8) FD (3 rückwärts) (gesamt F7FD)viel einfacher: (Adr. des nächsten Befehls) + Operand = 0x903 + 0xf7fd = 0x100
-
Danke.
00840000 - ( 00401012 + 5 ) = 43EFE9Btw. stimmt das was ich hier schreibe mit den Endians ?
43EFE9 Big Endian
E9EF43 Little Endian00401012 -E9 E9EF4300 JMP 00840000 E9EF4300 <-- Opcodes im Little Endian Format stimmte das?
-
die Zahl ist : unsinged long x = 0x0043EFE9 Little Endian: unsigned char x[4] = {0xE9,0xEF,0x43,0x00}; Big Endian : unsigned char x[4] = {0x00,0x43,0xEF,0xE9};