it-swarm.com.de

Wie kann man eine binäre ausführbare Datei in Linux zerlegen, um den Assemblycode zu erhalten?

Mir wurde gesagt, ich soll einen Disassembler benutzen. Hat gcc etwas eingebaut? Was ist der einfachste Weg, dies zu tun?

52
Syntax_Error

Ich glaube nicht, dass gcc ein Flag dafür hat, da es in erster Linie ein Compiler ist, aber ein anderes der GNU Entwicklungswerkzeuge. objdump nimmt ein -d/--disassemble-Flag:

$ objdump -d /path/to/binary

Die Demontage sieht folgendermaßen aus:

080483b4 <main>:
 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
84
Michael Mrozek

Eine interessante Alternative zu objdump ist gdb. Sie müssen die Binärdatei nicht ausführen oder haben keine 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 <fce>
   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)

Mit den vollständigen Debugging-Informationen ist es sogar noch besser.

(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 <fce>
   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 hat eine ähnliche Option (-S)

25
Miroslav Franc

Agner Fog's Disassembler , objconv, ist ganz nett. Sie fügt der Disassembly-Ausgabe Kommentare zu Leistungsproblemen hinzu (z. B. das gefürchtete LCP-Blockieren von Anweisungen mit 16-Bit-Direktkonstanten).

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

(Er erkennt - nicht als Abkürzung für stdout und gibt standardmäßig die Ausgabe in eine Datei mit ähnlichem Namen wie die Eingabedatei aus, wobei .asm aktiviert ist.)

Außerdem werden dem Code Zweigziele hinzugefügt. Andere Disassembler zerlegen normalerweise Sprunganweisungen mit einem numerischen Ziel und setzen keine Markierung auf ein Verzweigungsziel, um die Spitze von Schleifen usw. zu finden.

Es zeigt auch NOPs deutlicher an als andere Disassembler (macht es klar, wenn es aufgefüllt ist, anstatt es als bloße Anweisung zu zerlegen).

Es ist Open Source und für Linux leicht zu kompilieren. Es kann in NASM, YASM, MASM oder GNU (AT & T) -Syntax zerlegt werden.

Beispielausgabe:

; 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
...

Beachten Sie, dass diese Ausgabe bereit ist, um sie wieder in eine Objektdatei zusammenzusetzen, sodass Sie den Code auf der asm-Quellebene anpassen können, anstatt einen Hex-Editor für den Maschinencode zu verwenden. (Sie müssen also nicht nur die gleiche Größe beibehalten.) Ohne Änderungen sollte das Ergebnis nahezu identisch sein. Es könnte jedoch nicht sein, seit dem Zerlegen von Dingen wie

  (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

es gibt nichts in der Quelle, um sicherzustellen, dass es sich an die längere Codierung anschließt, die Raum für Verschiebungen gibt, um sie mit einem 32-Bit-Offset neu zu schreiben.


Wenn Sie objconv nicht installieren möchten, ist GNU binutils objdump -Mintel -d sehr brauchbar und wird bereits installiert, wenn Sie ein normales Linux-gcc-Setup haben.

9
Peter Cordes

es gibt auch Ndisasm, die einige Macken hat, aber nützlicher sein kann, wenn Sie Nasm verwenden. Ich stimme Michael Mrozek zu, dass objdump wahrscheinlich am besten ist.

[später] Sie können auch Albert van der Horsts ciasdis besuchen: http://home.hccnet.nl/a.w.m.van.der.horst/forthassembler.html . Es ist schwer zu verstehen, hat aber einige interessante Funktionen, die Sie sonst nirgends finden werden.

4
jcomeau_ictx

Verwenden Sie IDA Pro und den Decompiler .

3
ta.speot.is

ODA könnte nützlich sein. Es ist ein webbasierter Disassembler, der eine Vielzahl von Architekturen unterstützt.

http://onlinedisassembler.com/

3
Anthony DeRosa

ht Editor kann Binärdateien in vielen Formaten zerlegen. Es ist ähnlich wie Hiew, aber Open Source.

Öffnen Sie zum Zerlegen eine Binärdatei, drücken Sie dann F6 und wählen Sie elf/image aus.

0
arboreal84