Come disassemblare un eseguibile binario in Linux per ottenere il codice assembly?

Mi è stato detto di usare un disassemblatore. gcc ha qualcosa di integrato? Qual è il modo più semplice per farlo?

Non credo che gcc abbia un flag per questo, dato che è principalmente un compilatore, ma un altro degli strumenti di sviluppo GNU lo fa. objdump accetta un flag -d / --disassemble :

 $ objdump -d /path/to/binary 

Lo sassembly è simile a questo:

 080483b4 
: 80483b4: 8d 4c 24 04 lea 0x4(%esp),%ecx 80483b8: 83 e4 f0 and $0xfffffff0,%esp 80483bb: ff 71 fc pushl -0x4(%ecx) 80483be: 55 push %ebp 80483bf: 89 e5 mov %esp,%ebp 80483c1: 51 push %ecx 80483c2: b8 00 00 00 00 mov $0x0,%eax 80483c7: 59 pop %ecx 80483c8: 5d pop %ebp 80483c9: 8d 61 fc lea -0x4(%ecx),%esp 80483cc: c3 ret 80483cd: 90 nop 80483ce: 90 nop 80483cf: 90 nop

Un’alternativa interessante a objdump è gdb. Non è necessario eseguire il binario o avere il debuginfo.

 $ gdb -q ./a.out Reading symbols from ./a.out...(no debugging symbols found)...done. (gdb) info functions All defined functions: Non-debugging symbols: 0x00000000004003a8 _init 0x00000000004003e0 [email protected] 0x00000000004003f0 [email protected] 0x0000000000400400 _start 0x0000000000400430 deregister_tm_clones 0x0000000000400460 register_tm_clones 0x00000000004004a0 __do_global_dtors_aux 0x00000000004004c0 frame_dummy 0x00000000004004f0 fce 0x00000000004004fb main 0x0000000000400510 __libc_csu_init 0x0000000000400580 __libc_csu_fini 0x0000000000400584 _fini (gdb) disassemble main Dump of assembler code for function main: 0x00000000004004fb <+0>: push %rbp 0x00000000004004fc <+1>: mov %rsp,%rbp 0x00000000004004ff <+4>: sub $0x10,%rsp 0x0000000000400503 <+8>: callq 0x4004f0  0x0000000000400508 <+13>: mov %eax,-0x4(%rbp) 0x000000000040050b <+16>: mov -0x4(%rbp),%eax 0x000000000040050e <+19>: leaveq 0x000000000040050f <+20>: retq End of assembler dump. (gdb) disassemble fce Dump of assembler code for function fce: 0x00000000004004f0 <+0>: push %rbp 0x00000000004004f1 <+1>: mov %rsp,%rbp 0x00000000004004f4 <+4>: mov $0x2a,%eax 0x00000000004004f9 <+9>: pop %rbp 0x00000000004004fa <+10>: retq End of assembler dump. (gdb) 

Con le informazioni di debug complete è ancora meglio.

 (gdb) disassemble /m main Dump of assembler code for function main: 9 { 0x00000000004004fb <+0>: push %rbp 0x00000000004004fc <+1>: mov %rsp,%rbp 0x00000000004004ff <+4>: sub $0x10,%rsp 10 int x = fce (); 0x0000000000400503 <+8>: callq 0x4004f0  0x0000000000400508 <+13>: mov %eax,-0x4(%rbp) 11 return x; 0x000000000040050b <+16>: mov -0x4(%rbp),%eax 12 } 0x000000000040050e <+19>: leaveq 0x000000000040050f <+20>: retq End of assembler dump. (gdb) 

objdump ha un’opzione simile (-S)

Il disassemblatore di Agner Fog , objconv , è abbastanza carino. Aggiungerà commenti all’output di disassemblaggio per problemi di prestazioni (come il temuto stallo LCP da istruzioni con costanti immediate a 16 bit, per esempio).

 objconv -fyasm a.out /dev/stdout | less 

(Non riconosce - come abbreviazione di stdout, e ha come valore predefinito l’output in un file di nome simile al file di input, con .asm applicato su.)

Aggiunge anche gli obiettivi di ramo al codice. Gli altri disassemblatori di solito smontano le istruzioni di salto con una sola destinazione numerica e non mettono nessun segnalino sul bersaglio di un ramo per aiutarti a trovare la cima dei loop e così via.

Indica anche i NOP in modo più chiaro rispetto ad altri disassemblatori (chiarendo quando c’è il padding, invece di smontarlo come solo un’altra istruzione).

È open source e facile da compilare per Linux. Può essere smontato in syntax NASM, YASM, MASM o GNU (AT & T).

Uscita di esempio:

 ; Filling space: 0FH ; Filler type: Multi-byte NOP ; db 0FH, 1FH, 44H, 00H, 00H, 66H, 2EH, 0FH ; db 1FH, 84H, 00H, 00H, 00H, 00H, 00H ALIGN 16 foo: ; Function begin cmp rdi, 1 ; 00400620 _ 48: 83. FF, 01 jbe ?_026 ; 00400624 _ 0F 86, 00000084 mov r11d, 1 ; 0040062A _ 41: BB, 00000001 ?_020: mov r8, r11 ; 00400630 _ 4D: 89. D8 imul r8, r11 ; 00400633 _ 4D: 0F AF. C3 add r8, rdi ; 00400637 _ 49: 01. F8 cmp r8, 3 ; 0040063A _ 49: 83. F8, 03 jbe ?_029 ; 0040063E _ 0F 86, 00000097 mov esi, 1 ; 00400644 _ BE, 00000001 ; Filling space: 7H ; Filler type: Multi-byte NOP ; db 0FH, 1FH, 80H, 00H, 00H, 00H, 00H ALIGN 8 ?_021: add rsi, rsi ; 00400650 _ 48: 01. F6 mov rax, rsi ; 00400653 _ 48: 89. F0 imul rax, rsi ; 00400656 _ 48: 0F AF. C6 shl rax, 2 ; 0040065A _ 48: C1. E0, 02 cmp r8, rax ; 0040065E _ 49: 39. C0 jnc ?_021 ; 00400661 _ 73, ED lea rcx, [rsi+rsi] ; 00400663 _ 48: 8D. 0C 36 ... 

Nota che questo output è pronto per essere riassemblato in un file object, quindi puoi modificare il codice a livello di origine ASM piuttosto che con un editor esadecimale sul codice macchina. (Quindi non sei limitato a mantenere le stesse dimensioni.) Senza modifiche, il risultato dovrebbe essere quasi identico. Potrebbe non essere, però, dal momento che lo sassembly di cose come

  (from /lib/x86_64-linux-gnu/libc.so.6) SECTION .plt align=16 execute ; section number 11, code ?_00001:; Local function push qword [rel ?_37996] ; 0001F420 _ FF. 35, 003A4BE2(rel) jmp near [rel ?_37997] ; 0001F426 _ FF. 25, 003A4BE4(rel) ... ALIGN 8 ?_00002:jmp near [rel ?_37998] ; 0001F430 _ FF. 25, 003A4BE2(rel) ; Note: Immediate operand could be made smaller by sign extension push 11 ; 0001F436 _ 68, 0000000B ; Note: Immediate operand could be made smaller by sign extension jmp ?_00001 ; 0001F43B _ E9, FFFFFFE0 

non ha nulla nel sorgente per assicurarsi che si assembli alla codifica più lunga che lascia spazio per le rilocazioni per riscriverlo con un offset a 32 bit.


Se non vuoi installarlo objconv, GNU binutils objdump -Mintel -d è molto usabile e sarà già installato se hai una normale configurazione di Linux gcc.

Usa IDA Pro e il Decompilatore .

c’è anche ndisasm, che ha qualche stranezza, ma può essere più utile se usi il nasmo. Sono d’accordo con Michael Mrozek che objdump è probabilmente il migliore.

[più tardi] potresti anche voler controllare i ciasdis di Albert van der Horst: http://home.hccnet.nl/awmvan.der.horst/forthassembler.html . può essere difficile da capire, ma ha alcune caratteristiche interessanti che probabilmente non troverai da nessun’altra parte.

Potresti trovare utile ODA. È un disassemblatore basato sul web che supporta tonnellate di architetture.

http://onlinedisassembler.com/

l’ht editor può smontare i binari in molti formati. È simile a Hiew, ma open source.

Per smontare, aprire un binario, quindi premere F6 e quindi selezionare elf / image.