2012-03-22 19 views
12

Masz wątpliwości dotyczące konwersji kodu heksadecymalnego instrukcji maszyny JMP. Mam absolutny adres, na który chcę skoczyć, na przykład "JMP 0x400835". Po pierwsze, czy to dozwolone? Jeśli tak, jaki byłby odpowiedni kod szesnastkowy? Jeśli nie, czy mogę najpierw zapisać adres w jakimś rejestrze, na przykład EAX, a następnie umieścić "JMP EAX"? Pracuję nad architekturą x86 (64b).Instrukcja JMP - kod heksadecymalny

Próbowałem wydrukować kod szesnastkowy z wyjścia diassem w gdb, ale nie ma spójności, tzn. Nie widzę adresu docelowego w kodzie szesnastkowym.

Jestem nowy w kodzie szesnastkowym i instrukcji maszynowych, więc wybacz moją niewiedzę.

Odpowiedz

23

Brak skoku w postaci JMP absaddr do bezwzględnego adresu w trybie 64-bitowym. Operandem skoku jest zawsze 32-bitowe względne przesunięcie do rip, które zostaje rozszerzone do 64-bitowego znaku.

Przyczyną, dla której nie widać spójności, jest prawdopodobnie to, że przesunięcie zależy od bieżącego wskaźnika instrukcji i użytkownik tego nie rozpoznał.

jmp eax jest niedozwolone, ponieważ adresy mają zawsze 64-bitową szerokość w architekturze 64-bitowej. Sekwencja mov rax, addr + jmp rax jest to możliwe, to będzie wyglądać

48 c7 c0 35 08 40 00   mov rax, 0x00400835 
ff e0       jmp rax 

lub

48 b8 35 08 40 00 00 00 00 00 mov rax, 0x0000000000400835 
ff e0       jmp rax 

Skąd wiem, że te kody hex? Cóż, zapytałem mojego kompilatora. Kompilowałem z gcc -c i zdemontowałem z objdump. Nie zawracałem sobie głowy używaniem składni Intela, ponieważ nie potrzebuję tego. Tak jest w AT & T składni.

echo 'asm("mov $400835, %rax\n jmp *%rax\n");' > test.c 
gcc -c test.c 
objdump -d test.o 
+0

Dziękuję za odpowiedź. To naprawdę mi pomogło. objdump jest naprawdę dobrym narzędziem! –

+0

Hej ... zaznaczyłem twoją pocztę jako "użyteczną" ... to jest to, co potrzebne, tak myślę, prawda? –

+0

@DeepanjanMazumdar Musisz kliknąć na znacznik wyboru – hirschhornsalz