Как разобрать двоичный исполняемый файл в Linux, чтобы получить код сборки? - PullRequest
59 голосов
/ 26 февраля 2011

Мне сказали использовать дизассемблер.gcc имеет что-нибудь встроенное?Какой самый простой способ сделать это?

Ответы [ 7 ]

96 голосов
/ 26 февраля 2011

Я не думаю, что gcc имеет флаг для него, так как это в первую очередь компилятор, но другой инструмент разработки GNU делает. objdump принимает флаг -d / --disassemble:

$ objdump -d /path/to/binary

Разборка выглядит так:

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
28 голосов
/ 02 июля 2014

Интересной альтернативой objdump является gdb.Вам не нужно запускать бинарный файл или иметь 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)

С полной информацией отладки это даже лучше.

(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 имеет аналогичную опцию (-S)

9 голосов
/ 29 ноября 2015

дизассемблер Агнера Фога , objconv, это довольно мило. Он добавит комментарии к выводу разборки для проблем с производительностью (например, например, из-за страшного зависания LCP из инструкций с 16-битными непосредственными константами).

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

(Он не распознает - как сокращение для stdout и по умолчанию выводит в файл с именем, аналогичным имени входного файла, с прикрепленным .asm.)

Это также добавляет цели кода в код. Другие дизассемблеры обычно разбирают инструкции перехода только с числовым назначением и не ставят никаких маркеров на цель ветвления, чтобы помочь вам найти вершину циклов и т. Д.

Он также указывает NOP более четко, чем другие дизассемблеры (проясняя это при заполнении, вместо того, чтобы разбирать его как просто другую инструкцию.)

Это открытый исходный код, и его легко компилировать для Linux. Он может быть разобран на синтаксис NASM, YASM, MASM или GNU (AT & T).

Пример вывода:

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

Обратите внимание, что этот вывод готов для сборки обратно в объектный файл, так что вы можете настроить код на уровне исходного кода asm, а не с помощью hex-редактора машинного кода. (Таким образом, вы не ограничены тем, чтобы держать вещи одинакового размера.) Без изменений результат должен быть почти одинаковым. Это может быть не так, потому что разборка таких вещей, как

  (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

не имеет ничего в источнике, чтобы убедиться, что он собирается в более длинную кодировку, что оставляет место для перемещений, чтобы переписать его с 32-битным смещением.


Если вы не хотите устанавливать objconv, GNU binutils objdump -Mintel -d очень удобен в использовании и уже будет установлен, если у вас обычная настройка Linux gcc.

5 голосов
/ 26 февраля 2011

есть также ndisasm, который имеет некоторые причуды, но может быть более полезным, если вы используете nasm.Я согласен с Майклом Мрозеком в том, что objdump, вероятно, лучше.

[позже] вы также можете проверить ciasdis Альберта ван дер Хорста: http://home.hccnet.nl/a.w.m.van.der.horst/forthassembler.html. это может быть трудно понять, но имеет некоторые интересныефункции, которые вы вряд ли найдете где-либо еще.

3 голосов
/ 28 марта 2014

Возможно, вам понадобится ОПР.Это веб-дизассемблер, который поддерживает множество архитектур.

http://onlinedisassembler.com/

3 голосов
/ 26 февраля 2011

Используйте IDA Pro и Декомпилятор .

1 голос
/ 28 мая 2017

ht editor может разбирать двоичные файлы во многих форматах.Это похоже на Hiew, но с открытым исходным кодом.

Чтобы разобрать, откройте двоичный файл, затем нажмите F6 и затем выберите elf / image.

...