美文网首页
MachO文件

MachO文件

作者: superFool | 来源:发表于2021-06-08 08:55 被阅读0次

MachO文件

前言

Mach-O(Mach Object):Mach-O 文件是Mach object文件格式的缩写,它是可执行文件、目标代码、动态库的文件格式

主要包括:

  • 目标文件.o
  • 库文件
  • .a
  • .dylib
  • Framework
  • 可执行文件
  • dyld
  • .dsym

可以通过file命令查看文件类型
下面就来用file简单查看下这些文件

  1. .o 文件
    首先创建一个C文件通过Clang编译可以得到目标文件.o


    1622547092622.png
1622547134411.png

通过 clang -c demo.命令编译生成.o目标文件

1622547224293.png

通过file命令查看.o文件


1622547331572.png

说明.o文件是Mach-O文件类型的 64位(64-bit) object文件 x86_64架构
使用clang demo.o生成a.out可执行文件

1622547660467.png

a.out 是一个可执行文件(executable)

  1. .a 文件 和 Framework
    使用 find ~/ -name "*.a" 命令可以找到家目录下的.a文件
    找到之后查看一下.a
    使用file命令查看.a文件
    1622548473914.png

输出current ar archive random library这一坨不知道是什么鬼,有知道的大神可以帮忙解释一下

  1. .dylib文件
    使用file命令查看


    1622548728531.png

4.dyld


1622549080217.png

dyld 是一个动态连接器(dynamic linker),包含多个架构的通用二进制文件(universal binary with 3 architectures)

通用二进制文件

通用二进制文件是苹果公司提出来的一种程序代码,能同时适用多种架构
实现同一个程序包为多种架构提供最理想的性能
因为存在针对多种架构的代码所以比单一架构的包体积大,又因为存在共同的非执行资源(代码以外的),所以比多个单一平台代码包的体积小
由于每种架构只运行对应架构的代码,所以运行起来时不会占用额外的内存

指令集
Armv6、armv7、armv7s、arm64都是arm处理器的指令集,所有指令集原则上都是向下兼容的,如iPhone4S的CPU默认指令集为armv7指令集,但它同时也兼容armv6指令集,只是使用armv6指令集时无法充分发挥其性能,即无法使用armv7指令集中的新特性,同理,iPhone5的处理器标配armv7s指令集,同时也支持armv7指令集,只是无法进行相关的性能优化,从而导致程序的执行效率没那么高。

需要注意的是iOS模拟器没有运行arm指令集,编译运行的是x86指令集,所以,只有在iOS设备上,才会执行设备对应的arm指令集。

移动设备默认指令集

  • armv6 : iPhone, iPhone2, iPhone3G
  • armv7(32bit):iPhone3GS, iPhone4, iPhone4S
  • armv7S(32bit):iPhone4/iPhone4s (32位)
  • arm64(64bit):iPhone5s(5s+)
  • x86_64(64bit): 支持非M1Mac电脑的cpu架构(64位模拟器)
  • i386:32位架构模拟器

iOS11(及以上)系统只支持64位的设备就是5s(及以上)的设备才能安装,Xcode所以选择iOS11及以上系统Archive时生成的包只包含arm64架构,选择iOS10及以下系统打出来的包才有可能包含多个架构
在Xcode -> build Settings->search "mach"可以选择编译生成的产物


1622552989804.png

Mach-O Type

  • Executable:可执行文件
  • Dynamic Library:动态库
  • Static Library:静态库
  • Bundle:Bundle
  • Relocatable Object File:这个不知道是什么鬼

使用Xcode编译 选择最低支撑iOS11.0系统


1622553451512.png

查看编译生成包中的可执行文件


1622553521769.png

可以看到编译生成包中的可执行文件只支持arm64架构

再次选择最低支撑iOS10.0系统


1622553668749.png

可以看到编译生成包中的可执行文件变成了通用二进制文件支持arm64、和armv7两种架构

Xcode中编译架构设置 Build Settings -> Search "architectures" 下的Architecture


1622553897010.png

默认最多只支持arm64、armv7,可以修改这个配置支持更多架构
选择others加上armv7s然后再build


1622555144857.png

可以看到可执行文件多了armv7s架构

Lipo工具

  1. 使用lipo -info 可以查看MachO文件包含的架构 lipo -info MachO名称

    1622555459535.png
  2. 使用lifo –thin 拆分某种架构 lipo MachO文件 –thin 架构 –output 输出文件路径

    1622555576836.png

3.使用lipo -create 合并多种架构lipo -create MachO1 MachO2 -output 输出文件路径

1622555764340.png

MachO文件结构

1622631734095.png

如图所示MachO文件包含三个部分:
1. Header
header 是MachO的头,其中包含了该MachO文件的一些信息

  • 字节顺序、架构类型、加载指令数量等
  • 通过Header快速确认一些信息,比如32位还是64位,处理器架构,文件类型等

2. Load commands
Load commands是一张包含一堆加载指令表

  • 包含加载指令告诉dyld如何加载这个MachO

3. Data
Data是MachO中最大的部分

  • 包含Segement的具体数据

首先用MachOView查看一下Header


1622636950762.png

在Xcode里command + shift + o 搜索Loader.h可以找到Header的定义


1622637106397.png

Header的具体内容及释义


1622632746599.png

使用MachOView查看MachO文件

2D5CD41B-67A9-43AE-84A3-06B20B829279.jpeg

其中Load commands各条加载指令的含义如下:

  1. LC_SEGMENT_64:将文件中(32位或者64位)的段映射到进程地址空间中
  2. LC_DYLD_INFO_ONLY:动态连接相关信息
  3. LC_SYMTAB:符号地址
  4. LC_DYSYMTAB:动态符号表地址
  5. LC_LOAD_DYLINKER:使用什么加载,iOS的App使用dyld加载
  6. LC_UUID:文件的UUID
  7. LC_VERSION_MIN_IPHONEOS:最低支持的操作系统版本
  8. LC_SOURCE_VERSION:源代码版本
  9. LC_MAIN:程序主线程的入口地址和栈大小
  10. LC_ENCRYPTION_INFO_64 加密信息
  11. LC_LOAD_DYLIB:依赖库的路径,包含三方库
  12. LC_RPATH:dyld维护一个称为运行路径列表的路径的当前堆栈。当遇到@rpath时,它会被替换为运行路径列表中的每个路径,直到找到可加载的dylib(此项释义是网上摘录的还没弄懂啥意思)
  13. LC_FUNCTION_STARTS:函数起始地址表
  14. LC_DATA_IN_CODE:定义在代码段内的非指令的表
  15. LC_CODE_SIGNATURE:代码签名

接下来详细看下各个command的内容:
LC_SEGMENT_64

1622638513362.png
  • VM Address:运行时加载到内存(虚拟内存)的起始地址(要加上ALSR才是真正的内存地址)
  • VM Size:内存中占用大小
  • File Offset:在文件中的偏移地址
  • File Size:在文件中占用大小
    PS:可以看到_TEXT的File Offset是0,所以MachO文件是以代码段起始的

LC_DYLD_INFO_ONLY

1622638704330.png
  • Rebase Info Offset:重定向开始位置的偏移地址
  • Rebase Info Size:需要重定向的内容的大小
  • Binding Info Offset:绑定数据的偏移地址
  • Binding Info Size:绑定数据的大小
  • Weak Binding Info Offset:弱绑定
  • Weak Binding Info Size:
  • Lazy Binding Info Offset:懒绑定(用到的时候再绑定)
  • Lazy Binding Info Size:
  • Export Info Offset:对外开放的函数
  • Export Info Size:

LC_SYMTAB符号相关(函数名称,函数地址)
LC_MAIN 逆向找不到切入点的时候经常用到这个,当别人做了防护App启动就闪退时可以断住这个函数再做分析

使用 otool工具可以查看MachO的信息

Load commands的下面就是Data
Data分为_TEXT段(代码段)和_DATA段(数据段)


1622639877442.png

其中Section64(__TEXT,__text)是主程序代码
Section64(__TEXT,__stubs)Section64(__TEXT,__stub_helper)是做符号绑定的
Section64(__TEXT,__objc_methname)是方法名称
Section64(__TEXT,__objc_classname)是类名称
Section64(__TEXT,__objc_methtype)是方法类型

其他内容后面在用到的时候再补充

相关文章

  • 6.MachO

    MachO文件 MachO文件 MachO文件结构 DYLD Mach-O其实是Mach Object文件格式的缩...

  • iOS逆向-砸壳(Clutch & dumpdecryp

    MachO文件 -> 苹果加密 -> 加壳文件加壳文件 -> 苹果解密 -> MachO文件(DYLD) 解密过程...

  • 7.Mach-O&LLDB

    [TOC] MachO文件结构 单个架构的mach-O文件包含:MachO Header、Load Command...

  • Golang标准库——debug/macho

    macho 包macho可以实现对Mach-O对象文件的访问。 Constants Variables 如果文件不...

  • 从 MachO 加载到对象创建!

    MachO MachO -- Mach Object, 是一种用于可执行文件/目标文件(.o)/动态库的文件格式....

  • Mach-O文件(12)

    MachO文件(12) MachO文件 Mach-O其实是Mach Object文件格式的缩写,是mac以及iOS...

  • IOS 逆向工具的使用

    工具的使用 MachO View 查看MachO(可执行文件)的文件信息 LLDB low level debug...

  • MachO文件

    MachO文件 官方介绍总共有11种格式! 是 Mach Object的缩写,是Mac\iOS 上用于存储程序,库...

  • MachO文件

    以一个简单的iOS项目,只有NSLog输出语句,然后编译(最好真机器),将编译后的MachO文件使用MachOVi...

  • MachO文件

    Mach-O其实是Mach Object文件格式的缩写,它是一种用于可执行文件·目标代码·动态库的文件格式。作为a...

网友评论

      本文标题:MachO文件

      本文链接:https://www.haomeiwen.com/subject/mcfasltx.html