概述

Mach-O是Mach object的缩写,是Mac\iOS上用于存储程序、库的标准格式。

常见的Mach-O文件

属于Mach-O格式的文件类型有。



可以在xnu源码中,查看到Mach-O格式的详细定义(https://opensource.apple.com/tarballs/xnu/)

  • MH_OBJECT

    代码编译中间的产物目标文件(.o)属于MH_OBJECT类型Mach-O格式文件。我们平时制作的静态库本质就是N个.O文件的集合,所以静态库也是属于MH_OBJECT类型Mach-O格式文件。
  • MH_EXECUTE

    顾名思义是可执行文件,通过项目编译的二进制文件就是属于MH_EXECUTE类型的Mach-O格式文件。
  • MH_EXECUTE

    苹果的动态库比如.Framework、.dylib文件是属于MH_EXECUTE类型的Mach-O格式文件。
  • MH_DYLINKER

    动态库链接编译器 比如iPhone目录/usr/lib/dyld属于MH_DYLINKER类型的Mach-O格式文件。
  • MH_DSYM

    存储着二进制文件符号信息的文件。项目编译生成的不仅有程序还有一个与之对应的.dsYM文件。

Mach-O的基本结构

[官方描述(https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/MachOTopics/0-Introduction/introduction.html)

一个Mach-O文件包含3个主要区域

  • Header

    文件类型、目标架构类型等
  • Load commands

    描述文件在虚拟内存中的逻辑结构、布局
  • Raw segment data

    在Load commands中定义的Segment的原始数据

窥探Mach-O的基本结构

  • 命令行file指令查看

    • file 文件路径
  • otool查看Mach-O特定部分和段的内容

    通过otool -l 可执行文件路径 快速查看Mach-O基础结构信息,比如通过cryptid的值可以判断是否加壳。

  • 命令行lipo指令

    • 查看架构信息:lipo -info 文件路径
    • 导出某种特定架构:lipo 文件路径 -thin 架构类型 -output 输出文件路径
    • 合并多种架构:lipo 文件路径1 文件路径2 -output 输出文件路径

Universal Binary

翻译为通用的二进制文件,同时支持多种架构的二进制文件。因为需要储存多种架构的代码,通用二进制文件通常比单一平台二进制的程序要大。

由于两种架构有共同的一些资源,所以并不会达到单一版本的两倍之多,由于执行过程中,只调用一部分代码,运行起来也不需要额外的内存。因为文件比原来的要大,也被称为“胖二进制文件”(Fat Binary)。

通过xcode编译的静态库需要支持多架构的配置:

不同的CPU架构不同 指令集不同 二进制指令跟汇编指令一一对应,处理器比较高级,指令集就多,支持的功能就不比较多。

v6架构支持的机型
iPhone、iPhone3G、iPod Touch、iPod Touch2 v7架构支持的机型
iPhone3GS、iPhone4、iPhone4S、
iPad、iPad2、iPad3
iPad mini
iPod Touch3G、iPod Touch4、iPod Touch5 v7s
iPhone5、iPhone5C
iPad2 arm64
iPhone5s、iPhone6、iPhone6 Plus、iPhone6s、iPhone6s Plus
iPhoneSE、iPhone7、iPhone7 Plus、iPhone8 Plus、iPhone8 Plus、iPhoneX
iPad5、iPad Air、iPad Air2、iPad Pro、iPad Pro2
iPad mini with Retina display、iPad mini3、iPad mini4
iPod Touch6

动态库共享缓存(dyld shared cache)

在我们手机的/usr/lib目录下有个Mac-O文件dyld。

dyld是可以加载苹果的动态库。从iOS3.1开始,为了提高性能,绝大部分的系统动态库文件都打包存放到了一个缓存文件中(dyld shared cache)。



缓存文件路径:/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armX



dyld源码 https://opensource.apple.com/tarballs/dyld/。在最新的源码版本当中我们可以使用源码中的launch-cache/dsc_extractor.cpp抽取缓存文件中的动态库。

从缓存动态共享库中抽取动态库

  • 将dyld的源码中的dsc_extractor.cpp的#if 0一上代码删除,包含#if 0与#endif,代码如下
#include <stdio.h>
#include <stddef.h>
#include <dlfcn.h>
typedef int (*extractor_proc)(const char* shared_cache_file_path, const char* extraction_root_path,
void (^progress)(unsigned current, unsigned total));
int main(int argc, const char* argv[])
{
if ( argc != 3 ) {
fprintf(stderr, "usage: dsc_extractor <path-to-cache-file> <path-to-device-dir>\n");
return 1;
} //void* handle = dlopen("/Volumes/my/src/dyld/build/Debug/dsc_extractor.bundle", RTLD_LAZY);
void* handle = dlopen("/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/usr/lib/dsc_extractor.bundle", RTLD_LAZY);
if ( handle == NULL ) {
fprintf(stderr, "dsc_extractor.bundle could not be loaded\n");
return 1;
} extractor_proc proc = (extractor_proc)dlsym(handle, "dyld_shared_cache_extract_dylibs_progress");
if ( proc == NULL ) {
fprintf(stderr, "dsc_extractor.bundle did not have dyld_shared_cache_extract_dylibs_progress symbol\n");
return 1;
} int result = (*proc)(argv[1], argv[2], ^(unsigned c, unsigned total) { printf("%d/%d\n", c, total); } );
fprintf(stderr, "dyld_shared_cache_extract_dylibs_progress() => %d\n", result);
return 0;
}
  • 命令行clang编译连接可执行文件

    • clang++ -o 执行文件名称 cpp源文件
  • 通过生成的可执行文件抽取

抽离的苹果的动态库就在我们执行的framework目录下



我们就可以获取苹果所有动态库代码的Mach-O文件,就可以通过上面的Hopper等工具做源码分析了。

dyld与Mach-O

dyld文件是属于在unix内核规范中的Mach-O格式的文件。dyld可以用来加载一下类型的Mach-O文件

  • MH_EXECUTE
  • MH_DYLIB
  • MH_BUNDLE

总结:App的可执行文件、动态库都是由dyld负责加载的。

iOS逆向系列-Mach-O文件的更多相关文章

  1. iOS逆向系列-脱壳

    概述 通过iOS逆向系列-逆向App中使用class-dump工具导出App的Mach-O文件所有头文件.Hopper工具分析App的Mach-O文件代码大概实现.但是这些前体是App的Mach-O没 ...

  2. iOS逆向系列-逆向APP思路

    界面分析 通过Cycript.Reveal. 对于Reveal安装配置可参考配置iOS逆向系列-Reveal 通过Reveal找到内存中的UI对象 静态分析 开发者编写的所有代码最终编译链接到Mach ...

  3. iOS逆向系列-tweak补充

    tweak加载资源 开发自己的deb插件需要加载自己的资源,比如图片资源.iOS中常用的两种加载图片资源的方式: + (nullable UIImage *)imageNamed:(NSString ...

  4. iOS逆向系列-Reveal

    概述 Reveal是一款调试iOS程序UI界面的神器. 官网地址:https://revealall.com 下载:https://revealapp.com/download/ 建议下载Reveal ...

  5. iOS逆向系列-Cycript

    概述 Cycript 是Objective-C++.ES(JavaScript).Java等语法的混合物. 可以用来探索.修改.调试正在运行的Mac\iOS App. 通过Cydia安装Cycript ...

  6. iOS逆向系列-动态调试

    Xcode调试App原理 Mac安装了Xcode Xcode的安装包中包含了debugserver 可执行类型的Mach-O文件,iPhone第一次连接Xcode调试会将Xcode中的debugser ...

  7. iOS逆向系列-theos

    概述 theos是GitHub开源的一个项目,通过nic.pl创建tweak项目.通过编写我们注入代码,然后执行编译.打包.安装等操作将代码注入iPhone安装的制定程序. theos环境配置 安装签 ...

  8. iOS 逆向之ARM汇编

    最近对iOS逆向工程很感兴趣. 目前iOS逆向的书籍有: <Hacking and Securing IOS Applications>, <iOS Hacker's Handboo ...

  9. iOS逆向+越狱

    感觉本文涉及内容有点多的,但是自己不愿意写太多,就简单的谢谢关于ios上手的东西吧 初级入手不免要用到,pp助手,i4 tools等 iOS逆向-ipa包重签名及非越狱手机安装多个应用 1.常识 我们 ...

随机推荐

  1. thinkphp 数据分页

    通常在数据查询后都会对数据集进行分页操作,ThinkPHP也提供了分页类来对数据分页提供支持. 下面是数据分页的两种示例. 第一种:利用Page类和limit方法 $User = M('User'); ...

  2. 字符串匹配dp+bitset,滚动数组优化——hdu5745(经典)

    bitset的经典优化,即把可行性01数组的转移代价降低 bitset的适用情况,当内层状态只和外层状态的上一个状态相关,并且内层状态的相关距离是一个固定的数,可用bitset,换言之,能用滚动数组是 ...

  3. 树状数组优化dp——cf985E经典

    /* dp[i]=0|1 表示前i是否可以被成功分组, dp[i+1]能够变成1的三个条件 1:j∈[0,i-k]里存在dp[j]=1 2:dp[j]=1 3:a[i+1]-a[j+1]<=d ...

  4. Python pillow库安装报错

    报错信息: D:\pythontest\duanxinhongzha>pip3 install pillowCollecting pillow Could not find a version ...

  5. 其它课程中的python---4、Matplotlib最最最最简单使用

    其它课程中的python---4.Matplotlib最最最最简单使用 一.总结 一句话总结: 慢慢来吧,不着急,心态平和和沉稳:每次和世界交互,你就能感受到无比的自信 1.如何区别python2和p ...

  6. "Access denied for user 'root@localhost' 试一下你的mysql是不是用任何密码都可以登录,如果是的话这里

    https://blog.csdn.net/light_breeze/article/details/82070222 花了三小时...竟然是因为这个

  7. 20140307 引用赋值、类的初始化、指针数组、数组指针、new

    引用不能被赋值http://blog.csdn.net/laixingjun/article/details/9005200 类构造函数两种初始化方法区别,哪种好:http://blog.163.co ...

  8. 7-MySQL高级-主从-1

    1. 主从同步的定义 主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave). 因为复制是异步进行的,所 ...

  9. HDU 5726 线段树+dp

    题意:给出一个序列,后q次询问,求给定区间gcd及整个序列有多少个序列的gcd和这个值相同 首先线段树维护区间gcd建树,之后预处理出每个gcd有多少个子序列,这时需要dp, dp[i][tmp]表示 ...

  10. 【hihocoder】Demo Day

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 You work as an intern at a robotics startup. Today is your co ...