其他分享
首页 > 其他分享> > iOS逆向之Mach-O文件(上)

iOS逆向之Mach-O文件(上)

作者:互联网

本文主要介绍Mach-O文件格式以及通用二进制文件

8314ed5c2d86a7eb79969e8d099f0ef8.png


Mach-O文件概述

Mach-O文件格式

常见的Mach-O格式有以下几种

我们可以通过终端的file指令来查看文件的类型

1、目标文件.o

#include <stdio.h>int main(){    printf("test\n");    return 0;
}

中间产物.o文件

其中.c.out文件的区别是中间多了一个.o文件。而在我们的实际开发中,其实是有多个源码的,所以最终的可执行文件是由多个源码生成的,如下所示,将两个.o文件编译成一个可执行文件

上述所说的链接顺序,对应到我们日常开发中是指工程中的 target -> Build Phase -> Compiles Sources,这里就对应源文件的编译顺序,如果源文件的顺序发生了变化,生成的可执行文件是不一样的

2、库文件

静态库 & 动态库

参考链接:

验证.a 、 .dylib是否是Mach-O文件

验证.a

验证.dylib

3、可执行文件

这里的可执行文件,即一般是指日常项目中,编译后生成的可执行未见,可以通过file 查看其文件类型

6cb2bd41e854de305d3799e15635306f.webp

4、dyld

dyld(the dynamic link editor)是苹果的动态链接器,是苹果操作系统一个重要组成部分,在系统内核做好程序准备工作之后,交由dyld负责余下的工作。而且它是开源的,任何人可以通过苹果官网下载它的源码来阅读理解它的运作方式,了解系统加载动态库的细节。

共享缓存机制

在iOS系统中,每个程序依赖的动态库都需要通过dyld(位于/usr/lib/dyld)一个一个加载到内存,然而,很多系统库几乎是每个程序都会用到的,如果在每个程序运行的时候都重复的去加载一次,势必造成运行缓慢,为了优化启动速度和提高程序性能,共享缓存机制就应运而生。所有默认的动态链接库被合并成一个大的缓存文件,放到/System/Library/Caches/com.apple.dyld/目录下,按不同的架构保存分别保存着,

验证dyld

5、.dsym文件

dsym介绍

Xcode编译项目后,我们会看到一个同名的 dSYM 文件,dSYM 是保存 16 进制函数地址映射信息的中转文件,我们调试的 symbols 都会包含在这个文件中,并且每次编译项目的时候都会生成一个新的 dSYM 文件,位于/Users/<用户名>/Library/Developer/Xcode/Archives目录下,所以对于每一个发布版本我们都很有必要保存对应的 Archives 文件。

当我们软件 release 模式打包或上线后,不会像我们在 Xcode 中那样直观的看到用崩溃的错误,这个时候我们就需要分析 crash report 文件了,iOS设备中会有日志文件保存我们每个应用出错的函数内存地址,通过 Xcode 的 Organizer 可以将 iOS 设备中的 DeviceLog 导出成 crash 文件,这个时候我们就可以通过出错的函数地址去查询 dSYM 文件中程序对应的函数名和文件名。大前提是我们需要有软件版本对应的 dSYM 文件,这也是为什么我们很有必要保存每个发布版本的 Archives 文件了。

验证.dsym文件

通用二进制文件

mac系统所支持的cpu及硬件平台发生了很大的变化,为了解决软件在多个硬件平台上的兼容性问题,苹果开发了一个通用的二进制文件格式(Universal Binary),又称胖二进制(Fat Binary)

演示

ARM架构

ARM架构过去称作进阶精简指令集机器(Advanced RISC Machine,更早称作:Acorn RISC Machine),是一个32位精简指令集(RISC)处理器架构,ARM处理器非常适用于移动通讯领域,符合其主要设计目标为低耗电的特性。

ARM和Intel处理器的第一个区别是,前者使用精简指令集(RISC),而后者使用复杂指令集(CISC)。

ARM处理器指令集:是指计算机ARM操作指令系统。

iOS设备支持的指令集

ARM指令集对应设备
armv6iPhone, iPhone 3G, iPod 1G/2G
armv7iPhone 3GS, iPhone 4, iPhone 4S, iPod 3G/4G/5G, iPad, iPad 2, iPad 3, iPad Mini
armv7siPhone 5, iPhone 5c, iPad 4
arm64iPhone X,iPhone 8(Plus),iPhone 7(Plus),iPhone 6(Plus),iPhone 6s(Plus), iPhone 5s, iPad Air(2), Retina iPad Mini(2,3)
arm64eiPhone XS\XR\XS Max

参考链接:iOS 指令集架构 armv6、armv7、armv7s、arm64、arm64e、x86_64、i386

通用二进制文件源码

struct fat_header {
    uint32_t    magic;      /* magic字段被定义为常量FAT_MAGIC,表示这是一个胖二进制 */
    uint32_t    nfat_arch;  /* 表示有多少个Mach-O文件 */};
struct fat_arch {

    cpu_type_t  cputype;    /* cpu类型 */
    cpu_subtype_t   cpusubtype; /* CPU的子类型 */
    uint32_t    offset;     /* 指定了当前CPU架构数据相对于当前文件开头的偏移值 */
    uint32_t    size;       /* 数据的大小 */
    uint32_t    align;      /* 数据的内存对齐边界,取值必须是2的次方,它确保了当前CPU架构的目标文件在加载到内存中时,数据是经过内存优化对齐的 */};

终端命令

lipo演示

总结

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS开发交流群:130 595 548,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)


标签:可执行文件,逆向,架构,文件,二进制,iOS,lipo,Mach
来源: https://blog.51cto.com/u_15146321/2802763