概述

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. centos7构建kylo-0.10.1

      构建服务器使用centos7,8G内存.建议使用8G内存,因为内存不够失败了好几次. 系统需要提前安装一下组件: yum install -y gcc bzip2 rpm-build rpmdev ...

  2. NX二次开发-将工程图视图+尺寸的最大边界导出图片

    /***************************************************************************** ** ** ExportPicture.c ...

  3. NX二次开发-UFUN按类型遍历名字获取Tag函数UF_OBJ_cycle_by_name_and_type

    NX9+VS2012 #include <uf.h> #include <uf_draw.h> #include <uf_obj.h> #include <u ...

  4. Android 防止多次点击提交数据

    package com.test1.test; import android.app.Activity; import android.os.Bundle; import android.view.V ...

  5. 第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

    在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...

  6. SSM 整合 Shiro

    1. 导包 <!-- spring --> <dependency> <groupId>org.springframework</groupId> &l ...

  7. 如何使用Spring管理Filter和Servlet

    在使用spring容器的web应用中,业务对象间的依赖关系都可以用context.xml文件来配置,并且由spring容器来负责依赖对象 的创建.如果要在filter或者servlet中使用sprin ...

  8. 纯css制作三级菜单

    <!DOCTYPE html> <html> <head> <title>三级菜单</title> <meta charset=&qu ...

  9. VBA中msgbox的用法小结

    1.作用在消息框中显示信息,并等待用户单击按钮,可返回单击的按钮值(比如“确定”或者“取消”).通常用作显示变量值的一种方式.2.语法MsgBox(Prompt[,Buttons][,Title][, ...

  10. META标签的定义与使用(一、HTTP标题信息(http-equiv))

    META标签分两大部分:HTTP标题信息(http-equiv)和页面描述信息(name). 一.http-equiv类似于HTTP的头部协议,它回应给浏览器一些有用的信息,以帮助正确和精确地显示网页 ...