0x01 什么是Mach-O
Mach-O为Mach Object文件格式的缩写,它是一种用于可执行文件,目标代码,动态库,内核转储的文件格式。作为a.out格式的替代,Mach-O提供了更强的扩展性,并提升了符号表中信息的访问速度。 ——维基百科
Mach-O格式全称为Mach Object文件格式的缩写,是mac上可执行文件的格式, 类似于windows上的PE格式 (Portable Executable ), linux上的elf格式 (Executable and Linking Format)
0x02 Mach-O的结构
Mach-o包含三个基本区域:
头部(header structure)。
加载命令(load command)。
段(segment)。可以拥有多个段(segment),每个段可以拥有零个或多个区域(section)。每一个段(segment)都拥有一段虚拟地址映射到进程的地址空间。
链接信息。一个完整的用户级Mach-o文件的末端是链接信息。其中包含了动态加载器用来链接可执行文件或者依赖库所需使用的符号表,字符串表等等。
1.magic,是mach-o文件的魔数,0xfeedface代表的是32位,0xfeedfacf代表64位
2.cputype和cupsubtype代表的是cpu的类型和其子类型,例子中分别是c和9,定义如下:
#define CPU_TYPE_ARM((cpu_type_t) 12)
#define CPU_SUBTYPE_ARM_V7((cpu_subtype_t) 9
即为:armv7
3.接着是filetype,2,代表可执行的文件
#defineMH_EXECUTE 0×2
4.ncmds 指的是加载命令(load commands)的数量,例子中一共23个,编号0-22
5.sizeofcmds 表示23个load commands的总字节大小, load commands区域是紧接着header区域的。
第一张图截取的是第一个load command,从第一张图所知道,cmd类型是segment_command,就是截图的第2张图,依次分析:
1.cmd 是load command的类型,本文中值=1就是LC_SEGMENT,,LC_SEGMENT的含义是(将文件中的段映射到进程地址空间)
2.cmdsize 代表load command的大小(0x38个字节,从0x401C-0x4053)。
3.segname 16字节的段名字,当前是__PAGEZERO,有以下几种段:
#defineSEG_PAGEZERO"__PAGEZERO"/* the pagezero segment which has no */
/* protections and catches NULL */
/* references for MH_EXECUTE files */
#defineSEG_TEXT"__TEXT"/* the tradition UNIX text segment */
#defineSEG_DATA"__DATA"/* the tradition UNIX data segment */
#defineSEG_OBJC"__OBJC"/* objective-C runtime segment */
#defineSEG_ICON"__ICON"/* the icon segment */
#defineSEG_LINKEDIT"__LINKEDIT"/* the segment containing all structs */
/* created and maintained by the link */
/* editor. Created with -seglinkedit */
/* option to ld(1) for MH_EXECUTE and */
/* FVMLIB file types only */
#define SEG_IMPORT"__IMPORT"/* the segment for the self (dyld) */
/* modifing code stubs that has read, */
/* write and execute permissions */
4.vmaddr 段的虚拟内存启始地址
5.vmsize 段的虚拟内存大小
6.fileoff 段在文件中的偏移量
7.filesize 段在文件中的大小
8.maxprot 段页面所需要的最高内存保护(4=r,2=w,1=x)
9.initprot 段页面初始的内存保护
10.nsects 段中包含section的数量
11.flags 其他杂项标志位