web-dev-qa-db-fra.com

Comment désassembler un exécutable binaire sous Linux pour obtenir le code d'assemblage?

On m'a dit d'utiliser un désassembleur. Est-ce que gcc a quelque chose d'intégré? Quelle est la manière la plus simple de faire ça?

52
Syntax_Error

Je ne pense pas que gcc ait un drapeau pour cela, puisqu'il s'agit principalement d'un compilateur, mais un autre outil de développement GNU en a. objdump prend un drapeau -d/--disassemble:

$ objdump -d /path/to/binary

Le démontage ressemble à ceci:

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

Une alternative intéressante à objdump est gdb. Vous n'avez pas besoin d'exécuter le binaire ou d'avoir 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  __libc_start_main@plt
0x00000000004003f0  __gmon_start__@plt
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)

Avec des informations de débogage complètes, c'est encore mieux.

(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 a une option similaire (-S)

25
Miroslav Franc

Le désassembleur d’Agner Fog , objconv, est plutôt agréable. Il ajoutera des commentaires à la sortie de désassemblage pour les problèmes de performances (comme le décrochage redouté de LCP à partir d'instructions avec des constantes immédiates 16 bits, par exemple).

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

(Il ne reconnaît pas - comme raccourci pour stdout et génère par défaut une sortie dans un fichier de nom similaire au fichier d'entrée, avec .asm ajouté.)

Il ajoute également des cibles de branche au code. Les autres désassembleurs désassemblent généralement les instructions de saut avec uniquement une destination numérique et ne mettent aucun marqueur sur une cible de branche pour vous aider à trouver le haut des boucles, etc.

Il indique également les NOP plus clairement que les autres désassembleurs (ce qui permet d’indiquer clairement s’il ya remplissage, plutôt que de le désassembler comme une autre instruction.)

Il est open source et facile à compiler pour Linux. Il peut être désassemblé en syntaxe NASM, YASM, MASM ou GNU (AT & T).

Exemple de sortie:

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

Notez que cette sortie est prête à être réassemblée dans un fichier objet. Vous pouvez donc ajuster le code au niveau source asm plutôt qu'avec un éditeur hexadécimal sur le code machine. (Donc, vous n'êtes pas limité à garder les choses de la même taille.) Sans changement, le résultat devrait être presque identique. Ce n’est peut-être pas le cas, car le démontage de choses comme

  (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

n’a rien dans le code source pour s’assurer qu’il s’assemble au codage plus long qui laisse de la place aux relocalisations pour le réécrire avec un décalage de 32 bits.


Si vous ne voulez pas l'installer objconv, GNU binutils objdump -Mintel -d est très utilisable et sera déjà installé si vous avez une configuration gcc Linux normale.

9
Peter Cordes

il y a aussi ndisasm, qui a quelques bizarreries, mais peut être plus utile si vous utilisez nasm. Je suis d'accord avec Michael Mrozek pour dire que l'objdump est probablement le meilleur.

[plus tard] vous voudrez peut-être aussi consulter les liens ci-dessous d'Albert van der Horst: http://home.hccnet.nl/a.w.m.van.der.horst/forthassembler.html . cela peut être difficile à comprendre, mais présente des fonctionnalités intéressantes que vous ne trouverez probablement nulle part ailleurs.

4
jcomeau_ictx

Utilisez IDA Pro et le Decompiler .

3
ta.speot.is

Vous pourriez trouver l'APD utile. C'est un désassembleur basé sur le Web qui prend en charge de nombreuses architectures.

http://onlinedisassembler.com/

3
Anthony DeRosa

ht editor peut désassembler les fichiers binaires dans de nombreux formats. C'est similaire à Hiew, mais open source.

Pour le désassembler, ouvrez un fichier binaire, puis appuyez sur F6, puis sélectionnez elf/image.

0
arboreal84