2013-02-15 13 views
13

Załóżmy chcę zrobić krótki skok stosując następujące opcodes:Jak zakodować względną krótkie JMP w x86

EBCB lub JMP rel8

„skok krótki, RIP = RIP + 8-bitowy znak przesunięcia rozszerzony do 64 bitów "

(gdzie CB to bajt wartość podpisana reprezentująca względem przesunięcia odnoszące się do kierunku, w EIP rejestr)

Może zawsze przesunięcie będzie przesunięcie + 2 ponieważ EIP w czasie wykonywania (kierunek odniesienia) w tym krótkim skoku jest podstawą instrukcja twobyte, ale składnik sumy occurs always

EB 30 = jmp 0x00000032 (+30)

EB e2 = jmp 0xffffffe4 (-30)

, a następnie EIP może być celowo w tym samym kierunku, ponieważ fe + 2 to lub EIP.

eb fe = jmp 0x00000000

Uważam to zaskakujące, że overoffset ocurred rozwidlone choć liczba jest ujemna. Ale w Intelu nie znajduję żadnej wzmianki (może z powodu 3000 stron).

Intel® 64 oraz IA-32 Instrukcja architektury oprogramowania Program: Cz. 2A 3-423

Sytuacja bliska skok gdzie skok zakres jest ograniczony do -128 do +127 od aktualnej wartości EIP.

Potem rozważać trzy możliwości:

  1. +2 ponieważ jest po/wartość przyszłej z EIP w czasie wykonywania
  2. Zakodowany wartość nie jest zakodowany składnik 2s podpisana numer.
  3. ten pojawia się w instrukcji, ale nie widziałem, bo jestem głupi

Odpowiedz

11

rel8 jest w stosunku do pamięci adres następnej instrukcji użytkownika, ponieważ może być łatwo potwierdzone przez utworzenie dwóch wykonywalne i ich demontażu:

@label: 
    jmp @label 
    nop 

ten rozkłada a (z NDISASM, to samo jest w 16-bitowym 32-bitowego i 64-bitowy kod)

EBFE jmp short 0x0 
90 nop 

Następnie kolejny wykonywalny:

jmp @label 
@label: 
    nop 

EB00 jmp short 0x2 
90 nop 

Zatem rel8 jest zakodowany zawsze w odniesieniu do następnej instrukcji po jmp. Dezasemblery (co najmniej ndisasm i udcli) pokazują jednak, że jest to związane z instrukcją jmp. Może to spowodować pewne zamieszanie.

14

Czy to krótki skok, czy nie, to zawsze destination - source + sizeof(opcode). W twoim przypadku (bezwarunkowy krótki skok), sizeof(opcode) jest 2. Powodem tego dodania jest fakt, że gdy procesor wykonał etap pobierania instrukcji, wskaźnik instrukcji wskaże instrukcję następującą po oddziale.

+0

Jestem zdezorientowany terminologią: czym jest "krótki skok"? Nie byłem w stanie znaleźć definicji tego w Internecie. –

+2

Skrócony skrót @AndersonGreen jest kodowany jako * jmp rel8 * (EB XX), gdzie względna odległość (dest-źródło) jest mniejsza niż 0x80. Drugi nazywa się długim skokiem, który jest zakodowany jako * jmp rel32 * (E9 XXXXXXXX). Zauważ, że można to zakodować za pomocą przedrostka 66H, który zmienia operand na * rel16 *. – JosephH

4

Skokowy skrót zajmuje EIP w stosunku do koniec instrukcji skoku (która ma długość dwóch bajtów) i przyjmuje operand jednobajtowy, który jest rozszerzony i dodany do EIP.