当前位置: 首页 > news >正文

Mach-O详解(一) - 破题

什么是Mach-O

Mach-O: Mach Object

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

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

抽象概念

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

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

在这里插入图片描述

  • Mach Header: 描述 Mach-O 的CPU架构、文件类型、加载命令等信息

    • Magic Number 32位/64位架构

    • File Type 文件类型 - 其实就是可执行文件

    • Number of Load Commands 加载的Commands有多少个命令

    • Size of Load Commands 加载命令的内存大小

    • Flags 标识 系统加载有没有关系/链接/两级命名空间(通过两级命名空间将符号编码成 对象:符号 的两级名字,这样不同的动态库就避免了符号冲突)…

  • Load Commands: 描述文件中数据等具体组织结构,不同数据类型使用不同等加载命令表示

    • 其实就是一张包含很多内容的表,内容包括区域的位置、符号表、动态符号表等

    • LC_SEGMENT_64 将文件中(32位或64位)的段映射到进程地址空间中

      • 当然了,点开 LC_SEGMENT_64,还会看见更细节的内容,命令的执行需要依赖一些记录信息 代码 常量 其他数据类型等等 比如 LC_SEGMENT_64 类型的加载命令

      • VM Address 虚拟地址

      • VM Size 虚拟地址大小

      • File Offset 文件偏移

      • File size 文件大小

      • Maximum VM Protection 就是最大能使用的大小,因为不能操作物理内存,系统会分配一个最大的进程空间,只能通过虚拟空间 + offset的方式去映射物理内存,永远不会超过系统分配的边界

      • Number of Sections 加载进内存的section数量

    • 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 代码签名

  • Data: Data中每一个段(Segment)的数据保存在此,段用来存放数据和代码

    • Data 区主要就是负责代码和数据记录的

    • Mach-O 是以 Segment 这种结构来组织数据的, 一个 Segment 可以包含 0 个或多个 Section

    • Segment 中 section 就可以被解读为是代码,常量或者一些其他的数据类型

    • 在装载在内存中时,也是根据 Segment 做内存映射的

    • TEXT.text: 机器码

    • TEXT.cstring: 硬编码的字符串

    • TEXT.const: 初始化过的常量

    • DATA.data: 初始化过的可变的(静态/全局)数据

    • DATA.const: 没有初始化过的常量

    • DATA.bss: 没有初始化过的 (静态/全局)变量

    • DATA.common: 没有初始化过的符号声明

    • Section64(__TEXT,__text) 存放的就是代码的指令 汇编指令

    • Section64(__TEXT,cstring) 存放的就是硬编码的字符串

    • Section64(__DATA_CONST,__objc_classlist) OC中的类都记录在此section

    • Section64(__TEXT,__swift5_types) swift中的类都记录在此section 包含结构体 enumor 或者 类的descriptor(地址信息)

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

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

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

在这里插入图片描述

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

在这里插入图片描述

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

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

在这里插入图片描述

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

在这里插入图片描述

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

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

在这里插入图片描述

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

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

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

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

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

复习一遍

__swift5_types 中的 基址 + 相对地址

在这里插入图片描述

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

在这里插入图片描述

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

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

相关文章:

  • 今天来说说Java开发中常用的框架有哪些?
  • Three.js对模型进行多区域染色
  • 超全面试汇总——Hadoop(二)
  • Android辅助功能(Accessibility)简介
  • SSM网约车管理系统毕业设计-附源码051630
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • 第11章Linux实操篇-Linux磁盘分区、挂载
  • Kotlin协程:Flow的融合、Channel容量、溢出策略
  • android毕业设计选题基于Uniapp+SSM实现的互联网云数据环境下的供销APP购物商城电商
  • 超级详细的mysql安装和配置教程
  • 超级详细的Maven使用教程
  • 界面组件DevExpress WPF Data Grid哪些功能还能增强?一起来看
  • 爱上开源之golang入门至实战第四章函数(Func)(十)
  • SQL Dblink SQL
  • 超级无敌详细使用ubuntu搭建hadoop完全分布式集群
  • 分享一款快速APP功能测试工具
  • Intervention/image 图片处理扩展包的安装和使用
  • Java|序列化异常StreamCorruptedException的解决方法
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • SpringBoot 实战 (三) | 配置文件详解
  • 给github项目添加CI badge
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 提醒我喝水chrome插件开发指南
  • 王永庆:技术创新改变教育未来
  • 小程序开发之路(一)
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​flutter 代码混淆
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (TOJ2804)Even? Odd?
  • (windows2012共享文件夹和防火墙设置
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (四)Controller接口控制器详解(三)
  • (四)JPA - JQPL 实现增删改查
  • (转)Unity3DUnity3D在android下调试
  • .NET Core 版本不支持的问题
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .net MySql
  • .net分布式压力测试工具(Beetle.DT)
  • .net下简单快捷的数值高低位切换
  • :如何用SQL脚本保存存储过程返回的结果集
  • @Transactional类内部访问失效原因详解
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [AIGC] Redis基础命令集详细介绍
  • [android] 天气app布局练习
  • [C#]C# winform部署yolov8目标检测的openvino模型
  • [codevs 1288] 埃及分数 [IDdfs 迭代加深搜索 ]
  • [Electron]ipcMain.on和ipcMain.handle的区别
  • [Erlang 0129] Erlang 杂记 VI 2014年10月28日
  • [Foreman]解决Unable to find internal system admin account
  • [Fri 26 Jun 2015 ~ Thu 2 Jul 2015] Deep Learning in arxiv