objdump的选项-S、-l十分方便。如果二进制文件中带有调试信息,可以将源代码、文件名和行号与汇编代码对应显示。
在OSX上,对应的工具是otool。与“objdump -Sl”能力接近的命令是otool -tV。
看一看insert sort算法的反编译。插入排序的一种实现:
#include <stdio.h>
void insert_sort(int* L, int size) {
int tmp, i, j;
for (i = 1; i < size; ++i) {
tmp = L[i];
for (j = i-1; j >= 0 && L[j] > tmp; --j) {
L[j+1] = L[j];
}
L[j+1] = tmp;
}
}
void print_array(int* L, int size) {
printf("array: ");
for (int i = 0; i < size; ++i) {
printf("%d ", L[i]);
}
printf("\n");
}
int main (int argc, char** argv) {
int L[] = {18, 7, 5, 8, 99};
int size = sizeof(L) / sizeof(int);
insert_sort(L, size);
print_array(L, size);
return 0;
}
这个实现中没有全局变量,数据段(Data Section)应该没有内容。我们用"otool -dV insertsort"这个命令,只显示Data Section, 验证一下:
- oliverluan@localhost:~/Documents/Opt/insertsort$ otool -dV insertsort
- insertsort:
如果把L数据和size变量改写成全局变量:
- oliverluan@localhost:~/Documents/Opt/insertsort$ gcc -g insertsort_global.c -o insertsort_global
- oliverluan@localhost:~/Documents/Opt/insertsort$ otool -dV insertsort_global
- insertsort_global:
- (__DATA,__data) section
- 0000000100001020 12 00 00 00 07 00 00 00 05 00 00 00 08 00 00 00
- 0000000100001030 63 00 00 00 05 00 00 00
看一看Text Section: otool -tV insertsort:
- oliverluan@localhost:~/Documents/Opt/insertsort$ otool -tV insertsort
- insertsort:
- (__TEXT,__text) section
- _insert_sort:
- 0000000100000dd0 pushq %rbp
- 0000000100000dd1 movq %rsp, %rbp
- 0000000100000dd4 movq %rdi, 0xfffffffffffffff8(%rbp)
- 0000000100000dd8 movl %esi, 0xfffffffffffffff4(%rbp)
- 0000000100000ddb movl $0x1, 0xffffffffffffffec(%rbp)
- 0000000100000de2 movl 0xffffffffffffffec(%rbp), %eax
- 0000000100000de5 cmpl 0xfffffffffffffff4(%rbp), %eax
- 0000000100000de8 jge 0x100000e94
- 0000000100000dee movslq 0xffffffffffffffec(%rbp), %rax
- 0000000100000df2 movq 0xfffffffffffffff8(%rbp), %rcx
- 0000000100000df6 movl (%rcx,%rax,4), %edx
- 0000000100000df9 movl %edx, 0xfffffffffffffff0(%rbp)
- 0000000100000dfc movl 0xffffffffffffffec(%rbp), %edx
- 0000000100000dff subl $0x1, %edx
- 0000000100000e05 movl %edx, 0xffffffffffffffe8(%rbp)
- 0000000100000e08 movb $0x0, %al
- 0000000100000e0a cmpl $0x0, 0xffffffffffffffe8(%rbp)
- 0000000100000e11 movb %al, 0xffffffffffffffe7(%rbp)
- 0000000100000e14 jl 0x100000e30
- 0000000100000e1a movslq 0xffffffffffffffe8(%rbp), %rax
- 0000000100000e1e movq 0xfffffffffffffff8(%rbp), %rcx
- 0000000100000e22 movl (%rcx,%rax,4), %edx
- 0000000100000e25 cmpl 0xfffffffffffffff0(%rbp), %edx
- 0000000100000e28 setg %sil
- 0000000100000e2c movb %sil, 0xffffffffffffffe7(%rbp)
- 0000000100000e30 movb 0xffffffffffffffe7(%rbp), %al
- 0000000100000e33 testb $0x1, %al
- 0000000100000e35 jne 0x100000e40
- 0000000100000e3b jmpq 0x100000e6e
- 0000000100000e40 movslq 0xffffffffffffffe8(%rbp), %rax
- 0000000100000e44 movq 0xfffffffffffffff8(%rbp), %rcx
- 0000000100000e48 movl (%rcx,%rax,4), %edx
- 0000000100000e4b movl 0xffffffffffffffe8(%rbp), %esi
- 0000000100000e4e addl $0x1, %esi
- 0000000100000e54 movslq %esi, %rax
- 0000000100000e57 movq 0xfffffffffffffff8(%rbp), %rcx
- 0000000100000e5b movl %edx, (%rcx,%rax,4)
- 0000000100000e5e movl 0xffffffffffffffe8(%rbp), %eax
- 0000000100000e61 addl $0xffffffff, %eax
- 0000000100000e66 movl %eax, 0xffffffffffffffe8(%rbp)
- 0000000100000e69 jmpq 0x100000e08
- 0000000100000e6e movl 0xfffffffffffffff0(%rbp), %eax
- 0000000100000e71 movl 0xffffffffffffffe8(%rbp), %ecx
- 0000000100000e74 addl $0x1, %ecx
- 0000000100000e7a movslq %ecx, %rdx
- 0000000100000e7d movq 0xfffffffffffffff8(%rbp), %rsi
- 0000000100000e81 movl %eax, (%rsi,%rdx,4)
- 0000000100000e84 movl 0xffffffffffffffec(%rbp), %eax
- 0000000100000e87 addl $0x1, %eax
- 0000000100000e8c movl %eax, 0xffffffffffffffec(%rbp)
- 0000000100000e8f jmpq 0x100000de2
- 0000000100000e94 popq %rbp
- 0000000100000e95 ret
- 0000000100000e96 nopw %cs:(%rax,%rax)
- _print_array:
- 0000000100000ea0 pushq %rbp
- 0000000100000ea1 movq %rsp, %rbp
- 0000000100000ea4 subq $0x20, %rsp
- 0000000100000ea8 leaq 0xdb(%rip), %rax ## literal pool for: array:
- 0000000100000eaf movq %rdi, 0xfffffffffffffff8(%rbp)
- 0000000100000eb3 movl %esi, 0xfffffffffffffff4(%rbp)
- 0000000100000eb6 movq %rax, %rdi
- 0000000100000eb9 movb $0x0, %al
- 0000000100000ebb callq 0x100000f68 ## symbol stub for: _printf
- 0000000100000ec0 movl $0x0, 0xfffffffffffffff0(%rbp)
- 0000000100000ec7 movl %eax, 0xffffffffffffffec(%rbp)
- 0000000100000eca movl 0xfffffffffffffff0(%rbp), %eax
- 0000000100000ecd cmpl 0xfffffffffffffff4(%rbp), %eax
- 0000000100000ed0 jge 0x100000f02
- 0000000100000ed6 leaq 0xb5(%rip), %rdi ## literal pool for: %d
- 0000000100000edd movslq 0xfffffffffffffff0(%rbp), %rax
- 0000000100000ee1 movq 0xfffffffffffffff8(%rbp), %rcx
- 0000000100000ee5 movl (%rcx,%rax,4), %esi
- 0000000100000ee8 movb $0x0, %al
- 0000000100000eea callq 0x100000f68 ## symbol stub for: _printf
- 0000000100000eef movl %eax, 0xffffffffffffffe8(%rbp)
- 0000000100000ef2 movl 0xfffffffffffffff0(%rbp), %eax
- 0000000100000ef5 addl $0x1, %eax
- 0000000100000efa movl %eax, 0xfffffffffffffff0(%rbp)
- 0000000100000efd jmpq 0x100000eca
- 0000000100000f02 leaq 0x8d(%rip), %rdi ## literal pool for:
- 0000000100000f09 movb $0x0, %al
- 0000000100000f0b callq 0x100000f68 ## symbol stub for: _printf
- 0000000100000f10 movl %eax, 0xffffffffffffffe4(%rbp)
- 0000000100000f13 addq $0x20, %rsp
- 0000000100000f17 popq %rbp
- 0000000100000f18 ret
- 0000000100000f19 nopl (%rax)
- _main:
- 0000000100000f20 pushq %rbp
- 0000000100000f21 movq %rsp, %rbp
- 0000000100000f24 subq $0x10, %rsp
- 0000000100000f28 leaq _L(%rip), %rax
- 0000000100000f2f movl $0x0, 0xfffffffffffffffc(%rbp)
- 0000000100000f36 movl %edi, 0xfffffffffffffff8(%rbp)
- 0000000100000f39 movq %rsi, 0xfffffffffffffff0(%rbp)
- 0000000100000f3d movl _size(%rip), %esi
- 0000000100000f43 movq %rax, %rdi
- 0000000100000f46 callq _insert_sort
- 0000000100000f4b leaq _L(%rip), %rdi
- 0000000100000f52 movl _size(%rip), %esi
- 0000000100000f58 callq _print_array
- 0000000100000f5d movl $0x0, %eax
- 0000000100000f62 addq $0x10, %rsp
- 0000000100000f66 popq %rbp
- 0000000100000f67 ret
另外,可以用-l选项查看load commands:
- oliverluan@localhost:~/Documents/Opt/insertsort$ otool -l insertsort_global
- insertsort_global:
- Load command 0
- cmd LC_SEGMENT_64
- cmdsize 72
- segname __PAGEZERO
- vmaddr 0x0000000000000000
- vmsize 0x0000000100000000
- fileoff 0
- filesize 0
- maxprot 0x00000000
- initprot 0x00000000
- nsects 0
- flags 0x0
- Load command 1
- cmd LC_SEGMENT_64
- cmdsize 632
- segname __TEXT
- vmaddr 0x0000000100000000
- vmsize 0x0000000000001000
- fileoff 0
- filesize 4096
- maxprot 0x00000007
- initprot 0x00000005
- nsects 7
- flags 0x0
- Section
- sectname __text
- segname __TEXT
- addr 0x0000000100000d60
- size 0x00000000000001d9
- offset 3424
- align 2^4 (16)
- reloff 0
- nreloc 0
- flags 0x80000400
- reserved1 0
- reserved2 0
- Section
- sectname __stubs
- segname __TEXT
- addr 0x0000000100000f3a
- size 0x000000000000000c
- offset 3898
- align 2^1 (2)
- reloff 0
- nreloc 0
- flags 0x80000408
- reserved1 0 (index into indirect symbol table)
- reserved2 6 (size of stubs)
- Section
- sectname __stub_helper
- segname __TEXT
- addr 0x0000000100000f48
- size 0x0000000000000024
- offset 3912
- align 2^2 (4)
- reloff 0
- nreloc 0
- flags 0x80000400
- reserved1 0
- reserved2 0
- Section
- sectname __cstring
- segname __TEXT
- addr 0x0000000100000f6c
- size 0x000000000000000e
- offset 3948
- align 2^0 (1)
- reloff 0
- nreloc 0
- flags 0x00000002
- reserved1 0
- reserved2 0
- Section
- sectname __const
- segname __TEXT
- addr 0x0000000100000f80
- size 0x0000000000000014
- offset 3968
- align 2^4 (16)
- reloff 0
- nreloc 0
- flags 0x00000000
- reserved1 0
- reserved2 0
- Section
- sectname __unwind_info
- segname __TEXT
- addr 0x0000000100000f94
- size 0x0000000000000048
- offset 3988
- align 2^0 (1)
- reloff 0
- nreloc 0
- flags 0x00000000
- reserved1 0
- reserved2 0
- Section
- sectname __eh_frame
- segname __TEXT
- addr 0x0000000100000fe0
- size 0x0000000000000018
- offset 4064
- align 2^3 (8)
- reloff 0
- nreloc 0
- flags 0x00000000
- reserved1 0
- reserved2 0
- Load command 2
- cmd LC_SEGMENT_64
- cmdsize 312
- segname __DATA
- vmaddr 0x0000000100001000
- vmsize 0x0000000000001000
- fileoff 4096
- filesize 4096
- maxprot 0x00000007
- initprot 0x00000003
- nsects 3
- flags 0x0
- Section
- sectname __nl_symbol_ptr
- segname __DATA
- addr 0x0000000100001000
- size 0x0000000000000010
- offset 4096
- align 2^3 (8)
- reloff 0
- nreloc 0
- flags 0x00000006
- reserved1 2 (index into indirect symbol table)
- reserved2 0
- Section
- sectname __got
- segname __DATA
- addr 0x0000000100001010
- size 0x0000000000000008
- offset 4112
- align 2^3 (8)
- reloff 0
- nreloc 0
- flags 0x00000006
- reserved1 4 (index into indirect symbol table)
- reserved2 0
- Section
- sectname __la_symbol_ptr
- segname __DATA
- addr 0x0000000100001018
- size 0x0000000000000010
- offset 4120
- align 2^3 (8)
- reloff 0
- nreloc 0
- flags 0x00000007
- reserved1 5 (index into indirect symbol table)
- reserved2 0
- Load command 3
- cmd LC_SEGMENT_64
- cmdsize 72
- segname __LINKEDIT
- vmaddr 0x0000000100002000
- vmsize 0x0000000000001000
- fileoff 8192
- filesize 916
- maxprot 0x00000007
- initprot 0x00000001
- nsects 0
- flags 0x0
- Load command 4
- cmd LC_DYLD_INFO_ONLY
- cmdsize 48
- rebase_off 8192
- rebase_size 8
- bind_off 8200
- bind_size 56
- weak_bind_off 0
- weak_bind_size 0
- lazy_bind_off 8256
- lazy_bind_size 40
- export_off 8296
- export_size 80
- Load command 5
- cmd LC_SYMTAB
- cmdsize 24
- symoff 8408
- nsyms 24
- stroff 8820
- strsize 288
- Load command 6
- cmd LC_DYSYMTAB
- cmdsize 80
- ilocalsym 0
- nlocalsym 16
- iextdefsym 16
- nextdefsym 4
- iundefsym 20
- nundefsym 4
- tocoff 0
- ntoc 0
- modtaboff 0
- nmodtab 0
- extrefsymoff 0
- nextrefsyms 0
- indirectsymoff 8792
- nindirectsyms 7
- extreloff 0
- nextrel 0
- locreloff 0
- nlocrel 0
- Load command 7
- cmd LC_LOAD_DYLINKER
- cmdsize 32
- name /usr/lib/dyld (offset 12)
- Load command 8
- cmd LC_UUID
- cmdsize 24
- uuid F88FCA7D-3FE0-3556-96A4-4F29B7812D93
- Load command 9
- cmd LC_VERSION_MIN_MACOSX
- cmdsize 16
- version 10.9
- sdk 10.9
- Load command 10
- cmd LC_SOURCE_VERSION
- cmdsize 16
- version 0.0
- Load command 11
- cmd LC_MAIN
- cmdsize 24
- entryoff 3760
- stacksize 0
- Load command 12
- cmd LC_LOAD_DYLIB
- cmdsize 56
- name /usr/lib/libSystem.B.dylib (offset 24)
- time stamp 2 Thu Jan 1 08:30:02 1970
- current version 1197.1.1
- compatibility version 1.0.0
- Load command 13
- cmd LC_FUNCTION_STARTS
- cmdsize 16
- dataoff 8376
- datasize 8
- Load command 14
- cmd LC_DATA_IN_CODE
- cmdsize 16
- dataoff 8384
- datasize 0
- Load command 15
- cmd LC_DYLIB_CODE_SIGN_DRS
- cmdsize 16
- dataoff 8384
- datasize 24
符号表的查看使用nm -px insertsort。-p 原始顺序,不做symbol字母或者数字排序。-x 16进制表示
- oliverluan@localhost:~/Documents/Opt/insertsort$ nm -px insertsort
- 0000000100001020 0f 09 0000 00000000000000a9 _L
- 0000000100000000 0f 01 0010 00000000000000ac __mh_execute_header
- 0000000100000dd0 0f 01 0000 00000000000000c0 _insert_sort
- 0000000100000f20 0f 01 0000 00000000000000cd _main
- 0000000100000ea0 0f 01 0000 00000000000000d3 _print_array
- 0000000100001034 0f 09 0000 00000000000000e0 _size
- 0000000000000000 01 00 0100 00000000000000e6 _printf
- 0000000000000000 01 00 0100 00000000000000ee dyld_stub_binder