分析Mach-O檔案

ZhongXi發表於2018-07-21

OSX系統自帶的otool可以分析Mach-O可執行檔案

類似命令列工具:jtool

常用命令如下:

  • 檢視fat headers資訊

otool -f xxx.app/xxx

$ otool -f xxx.app/xxx
Fat headers
fat_magic 0xcafebabe
nfat_arch 2
architecture 0
    cputype 12
    cpusubtype 9
    capabilities 0x0
    offset 16384
    size 69642576
    align 2^14 (16384)
architecture 1
    cputype 16777228
    cpusubtype 0
    capabilities 0x0
    offset 69664768
    size 80306624
    align 2^14 (16384)
複製程式碼
  • 檢視archive header資訊

otool -a xxx.app/xxx

$ otool -a xxx.app/xxx
複製程式碼
  • 檢視Mach-O頭結構

otool -h xxx.app/xxx

$ otool -h xxx.app/xxx
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedface      12          9  0x00           2    52       5452 0x00218085
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           2    52       6128 0x00218085
複製程式碼
  • 檢視load commands

otool -l xxx.app/xxx

$ otool -l xxx.app/xxx
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedface      12          9  0x00           2    52       5452 0x00218085
Load command 0
      cmd LC_SEGMENT
  cmdsize 56
  segname __PAGEZERO
   vmaddr 0x00000000
   vmsize 0x00004000
  fileoff 0
 filesize 0
  maxprot 0x00000000
 initprot 0x00000000
   nsects 0
    flags 0x0
Load command 1
      cmd LC_SEGMENT
  cmdsize 736
  segname __TEXT
   vmaddr 0x00004000
   vmsize 0x03b44000
  fileoff 0
 filesize 62144512
  maxprot 0x00000005
 initprot 0x00000005
   nsects 10
    flags 0x0
Section
  sectname __text
   segname __TEXT
      addr 0x000092c0
      size 0x01f49bcc
    offset 21184
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
複製程式碼
  • 檢視依賴的動態庫,包括動態庫名稱、當前版本號、相容版本號

otool -L xxx.app/xxx

$ otool -L xxx.app/xxx
xxx.app/xxx (architecture armv7):
    /System/Library/Frameworks/CoreMotion.framework/CoreMotion (compatibility version 1.0.0, current version 2236.0.11)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
	/System/Library/Frameworks/CoreText.framework/CoreText (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox (compatibility version 1.0.0, current version 492.0.0)
	/System/Library/Frameworks/AVFoundation.framework/AVFoundation (compatibility version 1.0.0, current version 2.0.0)
xxx.app/xxx (architecture arm64):
    /System/Library/Frameworks/CoreMotion.framework/CoreMotion (compatibility version 1.0.0, current version 2236.0.11)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
	/System/Library/Frameworks/CoreText.framework/CoreText (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox (compatibility version 1.0.0, current version 492.0.0)
	/System/Library/Frameworks/AVFoundation.framework/AVFoundation (compatibility version 1.0.0, current version 2.0.0)
複製程式碼
  • 檢視支援的框架

otool -D xxx.app/xxx

$ otool -D xxx.app/xxx
xxx.app/xxx (architecture armv7):
xxx.app/xxx (architecture arm64):
複製程式碼
  • 檢視text section otool -t -v xxx.app/xxx
$ otool -t -v xxx.app/xxx
xxx.app/xxx (architecture armv7):
(__TEXT,__text) section
000092c0	f0 b5 	push	{r4, r5, r6, r7, lr}
000092c2	03 af 	add	r7, sp, #0xc
000092c4	2d e9 00 0d 	push.w	{r8, r10, r11}
000092c8	ad f5 78 6d 	sub.w	sp, sp, #0xf80
000092cc	82 b0 	sub	sp, #0x8
000092ce	4c f2 2e 20 	movw	r0, #0xc22e
000092d2	c0 f2 fc 30 	movt	r0, #0x3fc
000092d6	78 44 	add	r0, pc
000092d8	d0 f8 00 80 	ldr.w	r8, [r0]
000092dc	42 f2 b8 20 	movw	r0, #0x22b8
000092e0	c0 f2 c9 30 	movt	r0, #0x3c9
000092e4	78 44 	add	r0, pc
000092e6	41 46 	mov	r1, r8
000092e8	02 46 	mov	r2, r0
...
xxx.app/xxx (architecture arm64):
(__TEXT,__text) section
000092c0	f0 b5 	push	{r4, r5, r6, r7, lr}
000092c2	03 af 	add	r7, sp, #0xc
000092c4	2d e9 00 0d 	push.w	{r8, r10, r11}
000092c8	ad f5 78 6d 	sub.w	sp, sp, #0xf80
000092cc	82 b0 	sub	sp, #0x8
000092ce	4c f2 2e 20 	movw	r0, #0xc22e
000092d2	c0 f2 fc 30 	movt	r0, #0x3fc
000092d6	78 44 	add	r0, pc
000092d8	d0 f8 00 80 	ldr.w	r8, [r0]
000092dc	42 f2 b8 20 	movw	r0, #0x22b8
000092e0	c0 f2 c9 30 	movt	r0, #0x3c9
000092e4	78 44 	add	r0, pc
000092e6	41 46 	mov	r1, r8
000092e8	02 46 	mov	r2, r0
...
複製程式碼
  • 檢視data section

otool -d xxx.app/xxx

$ otool -d xxx.app/xxx
xxx.app/xxx (architecture armv7):
Contents of (__DATA,__data) section
03fdf2d0	01f94e98 01fef35b 01fef376 00000000 
03fdf2e0	037b0c7d 00000000 03fb44bc 00000000 
03fdf2f0	03fb45a8 00000000 03fb45bc 00000034 
03fdf300	00000000 03fb45e4 00000000 00000000 
03fdf310	00000000 037b0c65 03fb4634 00000000 
xxx.app/xxx (architecture arm64):
Contents of (__DATA,__data) section
0000000104a01100	02435948 00000001 0248fe0b 00000001 
0000000104a01110	0248fe26 00000001 00000000 00000000 
0000000104a01120	03c5113a 00000001 00000000 00000000 
0000000104a01130	049b2700 00000001 00000000 00000000 
0000000104a01140	049b28d0 00000001 00000000 00000000
複製程式碼
  • 檢視Objective-C segment

otool -o xxx.app/xxx

$ otool -o xxx.app/xxx
xxx.app/xxx (architecture armv7):
Contents of (__DATA,__objc_classlist) section
03fb3690 0x3fda424
           isa 0x3fda410
    superclass 0x0
         cache 0x0
        vtable 0x0
          data 0x3fb4304 (struct class_ro_t *)
                    flags 0x90
            instanceStart 4
             instanceSize 4
               ivarLayout 0x0
                     name 0x37b0c31 GICQgdiSTB
              baseMethods 0x0 (struct method_list_t *)
            baseProtocols 0x0
                    ivars 0x0
           weakIvarLayout 0x0
           baseProperties 0x0
Meta Class
           isa 0x0
    superclass 0x0
         cache 0x0
        vtable 0x0
          data 0x3fb42dc (struct class_ro_t *)
                    flags 0x91 RO_META
            instanceStart 20
             instanceSize 20
               ivarLayout 0x0
                     name 0x37b0c31 GICQgdiSTB
              baseMethods 0x3fb42c8 (struct method_list_t *)
		   entsize 12
		     count 1
		      name 0x3799743 load
		     types 0x37b3155 v8@0:4
		       imp 0x92c1
            baseProtocols 0x0
                    ivars 0x0
           weakIvarLayout 0x0
           baseProperties 0x0
...
xxx.app/xxx (architecture arm64):
Contents of (__DATA,__objc_classlist) section
00000001049b0b38 0x1049f73a8
           isa 0x1049f7380
    superclass 0x0 _OBJC_CLASS_$_NSObject
         cache 0x0
        vtable 0x0
          data 0x1049b23f8 (struct class_ro_t *)
                    flags 0x90
            instanceStart 8
             instanceSize 8
                 reserved 0x0
               ivarLayout 0x0
                     name 0x103c510ee GICQgdiSTB
              baseMethods 0x0 (struct method_list_t *)
            baseProtocols 0x0
                    ivars 0x0
           weakIvarLayout 0x0
           baseProperties 0x0
Meta Class
           isa 0x0
    superclass 0x0 _OBJC_METACLASS_$_NSObject
         cache 0x0
        vtable 0x0
          data 0x1049b23b0 (struct class_ro_t *)
                    flags 0x91 RO_META
            instanceStart 40
             instanceSize 40
                 reserved 0x0
               ivarLayout 0x0
                     name 0x103c510ee GICQgdiSTB
              baseMethods 0x1049b2390 (struct method_list_t *)
		   entsize 24
		     count 1
		      name 0x103c39c13 load
		     types 0x103c535db v16@0:8
		       imp 0x1000058f0 
            baseProtocols 0x0
                    ivars 0x0
           weakIvarLayout 0x0
           baseProperties 0x0
複製程式碼
  • 檢視symbol table

otool -I xxx.app/xxx

$ otool -I xxx.app/xxx
xxx.app/xxx (architecture armv7):
Indirect symbols for (__TEXT,__picsymbolstub4__TEXT) 815 entries
address    index
0x01f52e8c   491 
0x01f52e9c   492 
0x01f52eac   493 
0x01f52ebc   494 
0x01f52ecc   495
...
xxx.app/xxx (architecture arm64):
Indirect symbols for (__TEXT,__stubs) 824 entries
address            index
0x00000001023f470c    52 
0x00000001023f4718    53 
0x00000001023f4724    54 
0x00000001023f4730    55 
0x00000001023f473c    56
...
複製程式碼
  • 獲取所有方法名稱:

otool -v -s __TEXT __objc_methname xxx.app/xxx

$ otool -v -s __TEXT __objc_methname xxx.app/xxx
xxx.app/xxx (architecture armv7):
Contents of (__TEXT,__objc_methname) section
0379972a  stringByAppendingString:
03799743  load
03799748  stringWithUTF8String:
0379975e  user
03799763  setUser:
0379976c  password
03799775  setPassword:
...
xxx.app/xxx (architecture arm64):
Contents of (__TEXT,__objc_methname) section
0000000103c39bfa  stringByAppendingString:
0000000103c39c13  load
0000000103c39c18  stringWithUTF8String:
0000000103c39c2e  user
0000000103c39c33  setUser:
0000000103c39c3c  password
0000000103c39c45  setPassword:
...
複製程式碼

下面列舉一些常見的 Section。

Section 用途
__TEXT.__text 主程式程式碼
__TEXT.__cstring C 語言字串
__TEXT.__const const 關鍵字修飾的常量
__TEXT.__stubs 用於 Stub 的佔位程式碼,很多地方稱之為樁程式碼
__TEXT.__stubs_helper 當 Stub 無法找到真正的符號地址後的最終指向
__TEXT.__objc_methname Objective-C 方法名稱
__TEXT.__objc_methtype Objective-C 方法型別
__TEXT.__objc_classname Objective-C 類名稱
__DATA.__data 初始化過的可變資料
__DATA.__la_symbol_ptr lazy binding 的指標表,表中的指標一開始都指向 __stub_helper
__DATA.nl_symbol_ptr 非 lazy binding 的指標表,每個表項中的指標都指向一個在裝載過程中,被動態鏈機器搜尋完成的符號
__DATA.__const 沒有初始化過的常量
__DATA.__cfstring 程式中使用的 Core Foundation 字串(CFStringRefs
__DATA.__bss BSS,存放為初始化的全域性變數,即常說的靜態記憶體分配
__DATA.__common 沒有初始化過的符號宣告
__DATA.__objc_classlist Objective-C 類列表
__DATA.__objc_protolist Objective-C 原型
__DATA.__objc_imginfo Objective-C 映象資訊
__DATA.__objc_selfrefs Objective-C self 引用
__DATA.__objc_protorefs Objective-C 原型引用
__DATA.__objc_superrefs Objective-C 超類引用

相關文章