iOS上的可执行文件是Mach-O格式。Mach-O文件主要有三部分组成:分别是头部(Header)、加载命令(Load commands)、和段(segment);
下面以个推的GeTuiSdk.o可执行文件为例分别对上述三部分进行实践说明
1、 用otool -h XXXX.o可以查看可执行文件XXXX.o的头部(Header):
头部的结构体如下:
1 //32位的 2 3 struct mach_header { 4 var magic: UInt32 //魔数,0xfeedface代表的是32位,0xfeedfacf代表64位 5 var cputype: cpu_type_t //cpu的类型 6 var cpusubtype: cpu_subtype_t//cpu的子类型 7 var filetype: UInt32//文件类型 8 var ncmds: UInt32//命令数 即load commands的总数 9 var sizeofcmds: UInt32//命令所占的总字节大小 即load commands所有命令的总字节数 10 var flags: UInt32//标记 11 init() 12 init(magic magic: UInt32, cputype cputype: cpu_type_t, cpusubtype cpusubtype: cpu_subtype_t, filetype filetype: UInt32, ncmds ncmds: UInt32, sizeofcmds sizeofcmds: UInt32, flags flags: UInt32) 13 } 14 15 //64位的 16 struct mach_header_64 { 17 var magic: UInt32 18 var cputype: cpu_type_t 19 var cpusubtype: cpu_subtype_t 20 var filetype: UInt32 21 var ncmds: UInt32 22 var sizeofcmds: UInt32 23 var flags: UInt32 24 var reserved: UInt32 25 init() 26 init(magic magic: UInt32, cputype cputype: cpu_type_t, cpusubtype cpusubtype: cpu_subtype_t, filetype filetype: UInt32, ncmds ncmds: UInt32, sizeofcmds sizeofcmds: UInt32, flags flags: UInt32, reserved reserved: UInt32) 27 }
如:otool -h GeTuiSdk.o
➜ GetuiSDK git:(master) otool -h GeTuiSdk.o GeTuiSdk.o: Mach header magic cputype cpusubtype caps filetype ncmds sizeofcmds flags 0xfeedfacf 16777228 0 0x00 1 5 1824 0x00002000
2、用otool -l XXXX.o 查看XXXX可执行文件的 load commands 和section 如: GeTuiSdk.o
1 ➜ GetuiSDK git:(master) otool -l GeTuiSdk.o 2 GeTuiSdk.o: 3 Load command 0 //命令编号 4 cmd LC_SEGMENT_64 //cmd 类型 5 cmdsize 1752 //cmdsize 命令所占字节数 6 segnale //segname 段名字 7 vmaddr 0x0000000000000000 // vmaddr段的虚拟内存起始地址 8 vmsize 0x000000000000a238 // vmsize 段的虚拟内存大小 9 fileoff 1888 //fileoff 段在文件中的偏移量 10 filesize 41504 //filesize 段在文件中的大小 11 maxprot 0x00000007 //段页面所需要的最高内存保护(4=r,2=w,1=x)用otool -lv命令时 显示的是rwx 12 initprot 0x00000007 //段页面初始的内存保护 13 insects 21 //段中包含section的数量 14 flags 0x0 //flags 其他杂项标志位
PS:也可以用otool -lv XXXX.o 查看XXXX可执行文件的 load commands
3、 section
1 1 //32位 2 2 struct section { 3 3 var sectname: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)//section名 4 4 var segname: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)//段名 5 5 var addr: UInt32//该section在内存的启始位置 6 6 var size: UInt32//该section的大小 7 7 var offset: UInt32//该section的文件偏移 8 8 var align: UInt32//字节大小对齐 9 9 var reloff: UInt32//重定位入口的文件偏移 10 10 var nreloc: UInt32//需要重定位的入口数量 11 11 var flags: UInt32//包含section的type和attributes 12 12 var reserved1: UInt32//保留项 13 13 var reserved2: UInt32//保留项 14 14 init() 15 15 init(sectname sectname: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8), segname segname: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8), addr addr: UInt32, size size: UInt32, offset offset: UInt32, align align: UInt32, reloff reloff: UInt32, nreloc nreloc: UInt32, flags flags: UInt32, reserved1 reserved1: UInt32, reserved2 reserved2: UInt32) 16 16 } 17 18 //64 位 19 20 struct section_64 { 21 var sectname: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8) 22 var segname: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8) 23 var addr: UInt64 24 var size: UInt64 25 var offset: UInt32 26 var align: UInt32 27 var reloff: UInt32 28 var nreloc: UInt32 29 var flags: UInt32 30 var reserved1: UInt32 31 var reserved2: UInt32 32 var reserved3: UInt32 33 init() 34 init(sectname sectname: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8), segname segname: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8), addr addr: UInt64, size size: UInt64, offset offset: UInt32, align align: UInt32, reloff reloff: UInt32, nreloc nreloc: UInt32, flags flags: UInt32, reserved1 reserved1: UInt32, reserved2 reserved2: UInt32, reserved3 reserved3: UInt32) 35 }
如: GeTuiSdk.o
1 Section 2 sectname __text 3 segname __TEXT 4 addr 0x0000000000000000 5 size 0x00000000000019ec 6 offset 1888 7 align 2^2 (4) 8 reloff 43392 9 nreloc 825 10 type S_REGULAR 11 attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS 12 reserved1 0 13 reserved2 0 14 Section 15 sectname __gcc_except_tab 16 segname __TEXT 17 addr 0x00000000000019ec 18 size 0x000000000000058c 19 offset 8524 20 align 2^2 (4) 21 reloff 49992 22 nreloc 22 23 type S_REGULAR 24 attributes (none) 25 reserved1 0 26 reserved2 0