1. 程式人生 > >Mac的反編譯工具一:otool (objdump工具的OSX對應工具)。

Mac的反編譯工具一:otool (objdump工具的OSX對應工具)。

objdump的選項-S、-l十分方便。如果二進位制檔案中帶有除錯資訊,可以將原始碼、檔名和行號與彙編程式碼對應顯示。

在OSX上,對應的工具是otool。與“objdump -Sl”能力接近的命令是otool -tV。

看一看insert sort演算法的反編譯。插入排序的一種實現:

#include 

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, 驗證一下:

[email protected]:~/Documents/Opt/insertsort$ otool -dV insertsort
insertsort:

如果把L資料和size變數改寫成全域性變數:

[email protected]:~/Documents/Opt/insertsort$ gcc -g insertsort_global.c -o insertsort_global
[email protected]
:~/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:

[email protected]:~/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:

[email protected]:~/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進製表示 

[email protected]:~/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