Mach-O文件结构

status
category
date
summary
slug
icon
tags
password
本文源码从苹果开源官网获得

什么是Mach-O

Mach-OMach Object文件格式的缩写,是用于 iOS 和 macOS 的可执行文件,目标代码,动态库,内核转储的文件格式。

Mach-O 文件格式

苹果官方给的一张文件结构图:
notion image
我们编写一个HelloWorld程序,将其编译,然后通过MachOView来打开.out文件:
notion image
可以知道Mach-O由三部分组成: * Header:指明了CPU架构、文件类型、Load Commands 个数等一些基本信息。 * Load Commands:描述了怎样加载每个 Segment 的信息。在 Mach-O 文件中可以有多个 Segment,每个 Segment 可能包含零个、一个或多个 Section。 * Data:Segment 的具体数据,包含了代码和数据等。

Header

  • magic:魔数,0xfeedface是32位,0xcefaedfe是64位
  • cputype:CPU类型
  • cpusubtype:CPU具体类型
  • filetype:文件类型,例如可执行文件、库文件等 文件类型filetype的宏定义有:
  • ncmds:Load Commands的数量
  • sizeofcmds:Load Commands的总大小
  • flags:标志位,用于描述该文件的详细信息。
  • reserved:64位才有的保留字段,暂时没用
标志位flags的宏定义有:
对于上面的HelloWorld程序来说,它的Header信息如下:
notion image

Load Commands

  • cmd类型:指定command类型
  • cmdsize:表示command大小,用于计算到下一个command的偏移量
cmd类型:
cmd
作用
LC_SEGMENT/LC_SEGMENT_64
将段内数据加载映射到内存中去
LC_SYMTAB
符号表信息
LC_DYSYMTAB
动态符号表信息
LC_DYLD_INFO_ONLY
动态库信息
LC_LOAD_DYLINKER
启动dyld
LC_UUID
唯一标识符
LC_SOURCE_VERSION
源代码版本
LC_MAIN
程序入口
LC_LOAD_DYLIB
加载动态库
LC_FUNCTION_STARTS
函数符号表
LC_DATA_IN_CODE
Data注入代码地址
| LC_CODE_SIGNATURE|代码签名信息|

segment

notion image
首先看看segment的定义:
  • cmd:上面提到的Load Command类型
  • cmdsize:Load Command大小
  • segname[16]:段名称
notion image
segname
含义
__PAGEZERO
可执行文件捕获空指针的段
__TEXT
代码段和只读数据
__DATA
全局变量和静态变量
| __LINKEDIT | 包含动态链接器所需的符号、字符串表等数据
  • vmaddr:段虚拟地址(未偏移),真实虚拟地址要加上ASLR的偏移量
  • vmsize:段的虚拟地址大小
  • fileoff:段在文件内的地址偏移
  • filesize:段在文件内的大小 加载segment的过程,就是从文件偏移fileoff处,将大小为filesize的段,加载到虚拟机vmaddr处。
  • nsects:段内section数量
  • flags:标志位,用于描述详细信息 标志位宏定义:

section

section的定义:
  • sectname:section名称
  • segname:所属的segment名称 (大写的__TEXT代表segment,小写的__text代表section
notion image
sectname
含义
__text
主程序代码
__subs
桩代码
__stub_helper
用于动态链接,启动dyld
__cstring
硬编码的C字符串
__la_symbol_ptr
延迟加载
| __data | 初始化的可变的变量
  • addr:section在内存中的地址
  • size:section大小
  • offset:section在文件中的偏移
  • align:内存对齐边界
  • reloff:重定位入口在文件中的偏移
  • nreloc:重定位入口数量
Loading...

© 刘口子 2018-2025