Еще одной полезной программой для исследования скомпилированных файлов является консольная утилита objdump, которая поставляется в рамках пакета компиляторов GNU GCC.
Про установку компиляторов GNU GCC (и вместе с ними утилиты objdump
) на Windows можно прочитать в статье
Компилятор GCC. Первая программа на Windows,
а про установку на Linux - в статье GCC. Первая программа на Linux
Общий формат вызова objdump
:
objdump options file
где file
- ранее скомпилированный файл, а options
- опции, которые указывают, какую именно информацию о файле надо вывести на консоль. Доступных опций, довольно много,
все их можно посмотреть либо в документации, либо вывести на консоль, применив опцию -H
(или --help
)
objdump -H
Перечислю только основные опции
-f
(--file-headers
): отобразить содержимое общего заголовка файла
-p
(--private-headers
): отобразить содержимое заголовка файла, специфичное для формата объекта
-h
(--[section-]headers
): отобразить содержимое заголовков разделов
-x
(--all-headers
): отобразить содержимое всех заголовков
-d
(--disassemble
): отобразить содержимое исполняемых секций на ассемблере
-D
(--disassemble-all
): отобразить ассемблерное содержимое всех секций
-S
(--source
): отобразить исходный код Intermix с дизассемблированием
-s
(--full-contents
): отобразить полное содержимое всех запрошенных разделов
-g
(--debugging
): отобразить отладочную информацию в объектном файле
-e
(--debugging-tags
): отобразить отладочную информацию в стиле ctags
-G
(--stabs
): отобразить (в необработанном виде) любую информацию STABS в файле
-t
(--syms
): отобразить содержимое таблицы (таблиц) символов
-T
(--dynamic-syms
): отобразить содержимое таблицы динамических символов
-r
(--reloc
): отобразить записи о перемещении в файле
-R
(--dynamic-reloc
): отобразить записи о динамических релокациях/перемещениях
-v
(--version
): отобразить номер версии этой программы
-i
(--info
): отобразить список поддерживаемых форматов и архитектур объектов
В качестве примера возьмем простейшую программу, которая применяет синтаксис ассемблера MASM:
.data num1 dword 22 num2 dword 32 num3 dword ? .code main proc mov rax, 20 mov rbx, 10 add rax, rbx ret main endp end
Пусть программа располагается в файле hello.asm, и при компиляции создается объектный файл hello.obj.
Используем опцию -S для вывода ассемблерного кода:
c:\asm>objdump hello.obj -S hello.obj: file format pe-x86-64 Disassembly of section .text$mn: 0000000000000000 <main>: 0: 48 c7 c0 14 00 00 00 mov $0x14,%rax 7: 48 c7 c3 0a 00 00 00 mov $0xa,%rbx e: 48 03 c3 add %rbx,%rax 11: c3 ret c:\asm>
Здесь мы видим ассемблерные инструкции, их код и по каким смещениям в файле они расположены. Единственное, что в отличие от исходного файла, который применяет синтаксис ассемблера MASM, для вывода objdump используется синтаксис ассемблера GAS.
Для вывода ассемблерного кода всех секций применяется опция -D. Например, в случае с выше скомпилированным файлов hello.obj
я получу следующий консольный вывод:
c:\asm>objdump hello.obj -D hello.obj: file format pe-x86-64 Disassembly of section .text$mn: 0000000000000000 <main>: 0: 48 c7 c0 14 00 00 00 mov $0x14,%rax 7: 48 c7 c3 0a 00 00 00 mov $0xa,%rbx e: 48 03 c3 add %rbx,%rax 11: c3 ret Disassembly of section .data: 0000000000000000 <.data>: 0: 16 (bad) 1: 00 00 add %al,(%rax) 3: 00 20 add %ah,(%rax) 5: 00 00 add %al,(%rax) 7: 00 00 add %al,(%rax) 9: 00 00 add %al,(%rax) ... Disassembly of section .debug$S: 0000000000000000 <.debug$S>: 0: 04 00 add $0x0,%al 2: 00 00 add %al,(%rax) 4: f1 int1 5: 00 00 add %al,(%rax) 7: 00 52 00 add %dl,0x0(%rdx) a: 00 00 add %al,(%rax) c: 17 (bad) d: 00 01 add %al,(%rcx) f: 11 00 adc %eax,(%rax) 11: 00 00 add %al,(%rax) 13: 00 63 3a add %ah,0x3a(%rbx) 16: 5c pop %rsp 17: 61 (bad) 18: 73 6d jae 87 <@feat.00+0x77> 1a: 5c pop %rsp 1b: 68 65 6c 6c 6f push $0x6f6c6c65 20: 2e 6f outsl %ds:(%rsi),(%dx) 22: 62 (bad) 23: 6a 00 push $0x0 25: 37 (bad) 26: 00 3c 11 add %bh,(%rcx,%rdx,1) 29: 03 02 add (%rdx),%eax 2b: 00 00 add %al,(%rax) 2d: d0 00 rolb (%rax) ... 37: 0e (bad) 38: 00 24 00 add %ah,(%rax,%rax,1) 3b: 14 7f adc $0x7f,%al 3d: 00 00 add %al,(%rax) 3f: 4d 69 63 72 6f 73 6f imul $0x666f736f,0x72(%r11),%r12 46: 66 47: 74 20 je 69 <@feat.00+0x59> 49: 28 52 29 sub %dl,0x29(%rdx) 4c: 20 4d 61 and %cl,0x61(%rbp) 4f: 63 72 6f movsxd 0x6f(%rdx),%esi 52: 20 41 73 and %al,0x73(%rcx) 55: 73 65 jae bc <@feat.00+0xac> 57: 6d insl (%dx),%es:(%rdi) 58: 62 (bad) 59: 6c insb (%dx),%es:(%rdi) 5a: 65 72 00 gs jb 5d <.debug$S+0x5d> 5d: 00 00 add %al,(%rax) ... c:\asm>