Mach-O文件结构

Mach-O类型的文件

  • Mach-O是一种文件的格式; 是iOS/Mac OS上存储程序以及库的标准格式

    • Mach Object
  • Mach-O格式的文件

#define MH_OBJECT   0x1     /* 目标文件*/
#define MH_EXECUTE  0x2     /* 可执行文件 */
#define MH_FVMLIB   0x3     /* fixed VM shared library file */
#define MH_CORE     0x4     /*核心转储文件 */
#define MH_PRELOAD  0x5     /* preloaded executable file */
#define MH_DYLIB    0x6     /* dynamically bound shared library */
#define MH_DYLINKER 0x7     /* dynamic link editor */
#define MH_BUNDLE   0x8     /* dynamically bound bundle file */
#define MH_DYLIB_STUB   0x9     /* shared library stub for static */
                    /*  linking only, no section contents */
#define MH_DSYM     0xa     /* companion file with only debug */
                    /*  sections */
#define MH_KEXT_BUNDLE  0xb     /* x86_64 kexts */
  • 常见的Mach-O格式的文件

    • MH_OBJECT 目标文件

      • .o

      • .a/ .framework静态库

        • 静态库即多个.o文件存放在一起实现特定的功能
    • MH_EXECUTE 可执行文件

      • .app/MyApp

      • .out

    • MH_DYLIB 动态库

      • .framework/xxx

      • /dylib

    • MH_DYLINKER 动态链接器

      • usr/lib/dyld
    • MH_DSYM 存储二进制文件符号信息的文件

      • .dYSM/Contents/Resources/DWARF/MyApp
    image.png
  • 查看项目targetMach-O文件的类型

    • MH_EXECUTE类型
    image.png

Mach-O文件的基本结构

  • Mach-O包含三个主要区域

    • Header: 文件类型, 目标架构

    • Load command: 描述文件在虚拟内存中的逻辑与布局

    • Raw segment date: Load command中定义的原始数据

image.png
  • 使用otool查看Mach-O文件
➜ otool -h  DingTalk
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedface      12          9  0x00           2    79       7860 0x00218085
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           2    79       8672 0x00218085
  • 使用file查看Mach-O文件
# 该Mach-O文件类型是 executable  只有armv7指令集
➜  HomeDesign3D China.app file HomeDesign3D\ China
HomeDesign3D China: Mach-O executable arm_v7

# 该Mach-O文件 类型是 executable;  有armv7, arm64指令集是一个通用二进制文件
➜  DingTalk.app file DingTalk
DingTalk: Mach-O universal binary with 2 architectures: [arm_v7: Mach-O executable arm_v7] [arm64]
DingTalk (for architecture armv7):  Mach-O executable arm_v7
DingTalk (for architecture arm64):  Mach-O 64-bit executable arm64
  • 通用二进制文件

    • universal binary或者Fat binary

    • 含有多个不同架构的独立二进制文件; 故体积较大

    • 执行时, 只会选择一种架构的二进制文件

    image.png
  • 使用MachOView查看Mach-O文件

    • 以查看DingTalk为例
image.png
image.png
image.png
  • RAWRVA

    • RV: 虚拟地址

    • RAW: 文件偏移地址(物理地址)

    • RVA: 相对虚拟地址的偏移

Mach-O结构详解

Mach Header(arm64)
  • Magic Number : 魔数, 表示支持设备的CPU位数

    • oxFEEDFACE : 表示32位二进制

    • oxFEEDFACF : 表示64位二进制

  • cputypecpusubtype: CPU类型和子类型

  • filetype : Mach-O文件类型

  • ncmdssizeofcmds: 用于加载器的 加载命令的条数和大小

  • flags : 动态链接器dyld的标志

image.png

LC_SEGMENT / LC_SEGMENT_64段的详解

  • 常见段

    • __PAGEZERO: 空指针陷阱段

    • _TEXT: 程序代码段

    • __DATA: 程序数据段

    • __RODATA: read only程序只读数据段

    • __LINKEDIT: 链接器使用段

image.png
  • section段常见字段

    • Segment Name: 该Segment的名称, 用于load_segment

    • VM Address: 该段的虚拟物理地址

    • VM Size: 该段所需要分配的虚拟内存大小(字节)

    • File Offset: 该段在文件中的偏移量

    • File Size: 该段在文件中占据的字节数

    • Maximum VM Protection: 段的页面所需要的最高内存保护

      • ox1: x 执行

      • ox2: w 写

      • 0x4: r 读

    • Initial VM Protection: 段页面初始化的内存保护

    • Number of Sections: 段中section区的数量

    • Flags: 其他标志位

tips: 小结:

根据LC_SEGMENT命令 设置进程虚拟内存

对于每一个段, 将其内容从Mach-O文件加载到内存中

即从Mach-O文件中的偏移量为 File Offset处加载File Size字节内容到虚拟内存地址VM AddressVM Size字节空间内

image.png

段中区section详解

  • 常见区section

    • __text: 主程序代码

    • __stubs, __stub_helper: 用于动态链接的桩

    • __cstring: 程序中c语言字符串

    • __const: 常量

    • __RODATA,__objc_methname: OC方法名称

    • __RODATA,__objc_methntype: OC方法类型

    • __RODATA,__objc_classname: OC类名

    • __DATA,__objc_classlist: OC类列表

    • __DATA,__objc_protollist: OC原型列表

    • __DATA,__objc_imageinfo: OC镜像信息

    • __DATA,__objc_const: OC常量

    • __DATA,__objc_selfrefs: OC类自引用(self)

    • __DATA,__objc_superrefs: OC类超类引用(super)

    • __DATA,__objc_protolrefs: OC原型引用

    • __DATA, __bss: 没有初始化和初始化为0 的全局变量

image.png

Load Commmands加载命令中其他信息

  • LC_MAIN

    • 设置程序主线程入口地址栈大小
image.png
  • LC_CODE_SIGNATURE

    • 包含Mach-O文件的代码签名

    • 没有签名签名不正确, 该进程会被kill, 程序崩溃

image.png

Mach-O中动态库的加载

  • 动态库来源

    • 系统提供的动态库

    • 第三方动态库

  • 如图: DingTalk使用大量的系统动态库

    • Mach-O镜像中有很多对外部库以及符号的引用

    • 这些引用将在程序启动时, 由动态链接器 /usr/lib/dyld来执行符号绑定

image.png
  • 加载动态链接器

    • LC_LOAD_DYLINKER: 内核执行该命令时, 启动dyld
image.png
  • 获取符号表

    • LC_SYMTAB: 符号地址表

    • LC_DYSYMTAB: 动态符号地址表

  • 加载动态库

    • LC_LOAD_WEAK_DYLIB

    • LC_LOAD_DYLIB

动态库加载流程小结

1.0 首先启动dyld动态链接器; 内核根据LC_LOAD_DYLINKER启动/usr/lib/dyld

2.0 如果Mach-O文件中使用了外部定义的符号或函数, 则会在文本段__TEXT__stubs, __stub_helper区; 区内放着本地未被定义的符号; 编译器在编译源码时会创建对这些未定义符号桩区的调用

3.0 dyld运行时, 会在符号桩区调用地址上; 添加JMP 到 真实函数地址的指令

4.0 至于dyld怎么找到指定的动态库中指定的函数地址? 此时dyld将加载Load Command中的LC_LOAD_DYLIB命令

5.0 LC_LOAD_DYLIB(动态库), dyld将加载每一个指定的库且搜寻匹配的符号

6.0 当符号匹配时, 将在符号表(由dyld加载LC_SYMTAB, LC_DYSYMTAB获取)查找对应的函数/符号地址

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容