Mach-O详解(一) - 破题

2022-08-30  本文已影响0人  erlich

什么是Mach-O

Mach-O: Mach Object

布拉布拉.....,概念没意思,反正就是一可执行文件

ios中的常见的.o .a .dylib Framework dyld dsym 都是Mach-O

抽象概念

是一种可执行文件,用于目标代码,动态库,内核转储

每个Mach-O文件包括一个Mach-O头,一系列的载入命令,多个块

image.png
- LC_DYLD_INFO_ONLY  动态链接相关信息
- LC_SYMTAB  符号地址
- LC_DYSYMTAB 动态符号表地址
- LC_LOAD_DYLINKER dyld加载
- LC_UUID 文件的UUID
- LC_VERSION_MIN_MACOSX 支持最低的操作系统版本
- LC_SOURCE_VERSION 源代码版本
- LC_MAIN 设置程序主线程的入口地址和栈大小
- LC_LOAD_DYLIB 依赖库的路径,包含三方库
- LC_FUNCTION_STARTS 函数起始地址表
- LC_CODE_SIGNATURE 代码签名

操作一番,稍微看下具体mach-o 与 实际代码中关系

目前操作的是swift代码,此篇博客重在初步感知下Mach-O,所以具体swift的类结构暂不涉及

此后会专门写博客探究源码层面的结构

image.png

拿出计算器,当前是arm架构,小端模式

image.png

得到一个地址 , 此时发现前缀是个 0x100000000 这样的地址

在ios中,这个地址是 常量数据的存放地址, 验证一下

image.png

通过lldb调试,image list,读取镜像,得到虚拟偏移首地址,这里跟 上面Mach-O PageZero中记录的虚拟内存首地址 不一样,只是此处恰好相等而已

image.png

现在用计算器中的值 减去Mach-O中读取的虚拟首地址, 得到0x3E0C,

上Mach-O Segments部分 常量Section里看下

image.png

这里读出的偏移地址 0x00AC 与 前面得到的 0x3E0C 相加,得到 0x3EB8

这个结果 加上 刚才app启动时,lldb - image list拿到的偏移地址 0x100000000

(再次注意 - 这个值跟Mach-O中 虚拟首地址不一样,只是恰好相等了而已,Mach-O中的那个值是固定的,而此处的之个虚拟首地址值每次启动app都会变,就是所谓的ASLR,随机偏移地址)

得到 0x100003EB8, 回到调试,打开汇编,读下寄存器

--- 失败,刚才调试,类没有定义方法,临时加了一个 test_func(), 只好复刻下上面的操作,有的时候,事情总出点纰漏,出错不怕,能补漏就好

复习一遍

__swift5_types 中的 基址 + 相对地址

image.png

减去 PageZero中记录的虚拟地址首地址 得到 0x3DFC

image.png

上面得到的 0x0012 的 (基址0x3E30 + ASLR(app启动内存随机偏移 0x100000000) + 4字节偏移 + 得到的0x0012) = 0x3E46

具体是不是这样呢,时间关系,下一篇博客我通过寄存器验证,然后紧接着从验证结果入手,分析swift中的底层结构

上一篇下一篇

猜你喜欢

热点阅读