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 ) = 43EFE9

    Btw. stimmt das was ich hier schreibe mit den Endians ?

    43EFE9 Big Endian
    E9EF43 Little Endian

    00401012    -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};
    

Anmelden zum Antworten