从Mach-O看砸壳及App的安全性原理

栏目: 编程工具 · 发布时间: 7年前

内容简介:1

一、前言

在正文开始之前,先提出几个问题:我们经常说的砸壳到底砸的是什么?壳有什么作用? iOS 是如何做签名验证的?苹果在应用审核的机审阶段都能获取到我们哪些信息?带着这些问题我们进入到正文。

二、 ipa内容介绍

首先来介绍下 ipa 包。 ipa 实际上是一个压缩包,我们从 App Store 下载的应用实际上都是压缩包。压缩包中包含 .app 的文件, .app 文件实际上是一个带后缀的文件夹。在 app 中,存在如下文件:

1 )资源文件

资源文件包括我们常用的内置文件,如图片、 plist 以及生成的 .car 文件等。

2 )可执行程序

可执行程序是最核心的文件,除了代码和数据外,里面包含 code signature ENCRYPTION

从Mach-O看砸壳及App的安全性原理

从Mach-O看砸壳及App的安全性原理

上图中展示的是 code signature ENCRYPTION LoadCommad 中的索引。展开 ENCRYPTION 后可以看到 ENCRYPTION 的偏移地址和大小。 Crypt ID 标记该 Mach-O 文件是否被加密,如果加密则 Crypt ID = 1 ,否则为 0

从Mach-O看砸壳及App的安全性原理

那么这个 ENCRYPTION 是什么?谁负责加密的?谁负责解密的?如果文件没有加密是否还能被运行?

实际上加密的 ENCRYPTION 就是我们所说的壳,砸壳就是将 ENCRYPTION 进行解密操作。从上面的截图我们可以看出, ENCRYPTION 的起始偏移地址为文件的 0x4000 位置,而结束位置可以计算出为 0x4000+0x424000 = 0x428000 。这个范围正好对应着 Mach-O 的文本段(不是 1:1 的,起始位置 0x4000 ,而不是 0x0 )。也就是说加密实际上是对 TEXT 段进行加密。 TEXT 内存储的是代码信息,包括函数指令、类名、方法名、字符串信息等。

从Mach-O看砸壳及App的安全性原理

TEXT 进行加密,加密后的 Mach-O 文件无法获取到代码信息,也就是说指令信息我们无法直接获取到了。除了指令外,在 DATA 段中,有些数据存储的是指针信息,指向 TEXT 段的数据,这样的数据也无法解析出来。

从Mach-O看砸壳及App的安全性原理

加壳之后的应用,在不解密的情况下,无法暴露指令和文本数据,这能很好地保护应用。这个壳是在上传到 App Store App Store 进行加密的,用户下载的应用也是被加壳的应用。存储在手机的文件也是被加密的,只有在应用 运行 时, iOS 才会对文件进行解密,也就是说在用户手机上运行的文件都是解密脱壳后的文件。我们在进行真机调试时,安装到手机上的文件是未加密的,这个时候 Crypt ID 标记为 0 iOS 系统在识别 Crypt ID 0 时不会进行解密处理。

3) code signature

code signature 包含资源文件的签名信息,如果资源文件被更改替换,那么签名是无法验证通过的。因此下载 XIB 等方式实现 UI 的动态布局是无法实现的。那么这里的 code signature Mach-O 文件里的 signature 是一样的吗?当然是不一样的。这里的签名验证的是资源文件,而 Mach-O 文件中的 code signature 是验证 Mach-O 是否被篡改以及是否是 apple 允许安装的应用。

三、 dumpdecrypted砸壳原理简介

砸壳的技术方案可以分为两种,一种是静态砸壳,一种是动态砸壳。静态砸壳的原理是硬破解 apple 的加密算法,目前是一种使用频率极低的技术方案。动态砸壳是利用 iOS 将文件解密后加载到内存后,将解密数据拷贝到磁盘的方案。动态砸壳目前成熟的方案很多,在这里介绍下 dumpdecrypted 的方式。

dumpdecrypted 是以动态库的方式,将代码注入到目标进程中。那么如何让一个应用程序在运行时加载我们的动态库呢?目前的方案主要有两种:

1 )修改 Mach-O 文件,在 LC 中,添加 LC_LOAD_DYLIB 信息,然后重签名运行。

这需要开发者对 Mach-O 文件有足够的了解,否则很容易损毁文件。不过已经有相应的工具: https://github.com/Tyilo/insert_dylib 。有兴趣的可以试验下。

2 )通过在手机的终端输入 DYLD_INSERT_LIBRARIES=" 动态库 "  APP 路径   命令(这就要求手机必须是越狱的),指定应用加载动态库, dumpdecrypted 采用的就是这种方式。

DYLD_INSERT_LIBRARIES 是系统的环境变量。通过在终端输入 man dyld 可以查看环境变量及其解释。 DYLD_INSERT_LIBRARIES 的解释如下:

从Mach-O看砸壳及App的安全性原理

除了 DYLD_INSERT_LIBRARIES 变量外,我们可以打印看到还有许多环境变量,

从Mach-O看砸壳及App的安全性原理

这些变量的解释和用处都在终端中有说明,在此不再一一解释。额外提一句,我们可以在应用中通过 getenv 函数检测是否存在环境变量,这可以作为安全监测数据。

在动态库被加载后,标记为 __attribute__((constructor)) 的函数会被执行。启动函数执行后,核心步骤只做 3 件事

1 )在加密的原文件中复制从起始位置开始的未加密的数据。

2 )从内存中的文件复制解密的数据。

3 )在加密原文件中跳过加密部分,拷贝剩余未加密数据。

从Mach-O看砸壳及App的安全性原理

3 件事做完后,应用程序脱壳就完成了。在阅读代码时,我有两个问题:

1 )函数为什么指定成

void dumptofile(int argc, const char **argv, const char **envp, const char **apple, struct ProgramVars *pvars) 类型?

后来发现实际上这是 __attribute__((constructor)) 固定的函数类型, 5 个参数分别代表了 ( 参数个数,参数列表,环境变量,可执行程序路径,文件信息 )

2 )如何获取应用在磁盘的路径?

argv[0] ,也就是参数列表的第一个,代表的是可执行文件的路径。这与 main 函数类似。通过 apple 也可以获取到文件路径, dumpdecrypted 使用的是 argv[0]

从Mach-O看砸壳及App的安全性原理

四、重签名

在脱壳后,只能保证 Mach-O 文件变成可读的,即函数指令和字符信息能暴露出来,但是此时的文件并不能运行。这是由于 apple 除了做代码可读化的加密外,还做了签名验证,从而保证在 iOS 系统中成功运行的程序都是被苹果校验过的,被篡改的或其他的渠道程序不能被加载。因此需要对砸壳后的文件进行重签名。

1) 签名的作用

在应用 ipa 内,存在多处签名,不同的签名有不同的作用。但是这些签名整体目的只有一个:所有安装和运行的 APP 必须是苹果允许的。也就是说,在安装时 iOS 会验证一些文件的签名,在启动时 iOS 系统也会验证一部分文件的签名。

2) 签名文件

App Store 下载的应用验证最简单,只要 iOS 系统用公钥验证 APP App Store 后台用私钥生成的签名即可。但是我们开发过程中的真机调试是如何进行签名验证呢?首先来看下面这个流程图(图片摘自 http://blog.cnbang.net/tech/3386/

从Mach-O看砸壳及App的安全性原理

签名的秘钥一共有两对,针对这些步骤我们来一步步解释这些步骤在什么时候操作的,如何操作的以及形式是什么。

首先,两对秘钥中, App Store 的私钥和 iOS 系统内部的公钥我们接触不到,因此不做解释。但是 Mac 中的公钥和私钥我们确实使用过。

MAC 公钥 :公钥即是我们在钥匙串中申请的 .certSigningRequest 文件。

MAC 私钥 :在申请 certSigningRequest 文件文件时生成的配对的私钥,保存在本地电脑中。

证书生成 :证书生成对应图中步骤 3 ,我们将 MAC 的公钥上传到苹果后台通过苹果的私钥进行签名,签名后生成的文件即是开发者证书。

描述文件 :由于苹果要限制安装的设备、安装的 APP 以及所具备的权限(如推送),苹果将这些信息连同证书合并再签名得到的文件就是描述文件。描述文件在开发阶段存放在 APP 包内,文件名为 embedded.mobileprovision 。至此,我们可以知道已经存在两处签名了, 1 是苹果对本地公钥的签名, 2 是对证书描述文件的签名,这两处签名都是 App Store 的私钥进行签名的。

在通过 Xcode 打包时, Xcode 会通过本地私钥对 APP 进行签名,这个签名上图中表现出一部分,实际上签名有两处:一处是对资源进行签名,也就是说 ipa 内所有的资源文件包括 xib png 等都需要进行签名,签名存放在 code signature 中。另一处签名是针对代码的签名(这个签名不是加密壳), ipa 内的 Mach-O 文件的 code signature 存放着打包时的签名信息。

3 、验证流程

有了这么多的签名,那么这些签名是在什么时候进行验证的呢?验证分两个步骤进行,分别是安装时验证和启动时验证。

1 )安装时验证

在安装时, iOS 系统会取出 code signature 验证各个资源文件的签名。如果资源文件都验证通过,那么取出 embedded.mobileprovision ,验证设备 ID ,如果该设备在设备列表中并且相符,那么安装成功。但是 INHOUSE 版本和 App Store 版的 APP 不需要验证 embedded.mobileprovision 。(因为不存在这个文件,这是由于发布市场不需要放开验证权限,与你的 Mac iPhone 无关,所以也就不需要你的公钥)

2 )启动时验证

验证 bundle id embedded.mobileprovision 中的 APPID 是否一致,验证 entitlements embedded.mobileprovision entitlements 是否一致。如果一致则尝试将执行可执行程序。在 iOS 内核执行 execve 函数调用 Mach-O 可执行文件之前,会先获取 Mach-O code signature 。那么 code signature 里到底存的啥?可以通过 codesign -dvvvvv 查看 Mach-O code signature ,里面存的都是签名信息。

从Mach-O看砸壳及App的安全性原理

五、 iOS 应用包扫描

在我们 ipa 包提交到苹果审核后,苹果会通过代码扫描我们应用程序所使用到的 API 。那么苹果根据我们提交的应用包,能扫描到什么内容呢?

1 、示例

符号信息在打包时存储在两个 Mach-O 文件中: 1 、可执行程序。 2 DSYM 文件。可执行程序中存在类相关信息及动态链接相关符号。 DSYM 是在打包时从可执行文件中剥离出来的 Mach-O 文件,包含静态链接相关符号、代码路径等完备信息。如果打包时不选用苹果自带的崩溃统计工具, DSYM 只上传给 buggly 使用。苹果所能扫描的只有资源文件以及可执行程序。但是除了可执行程序除了符号信息外,还包含其他信息。

1 )扫描类信息

类关键信息包括类名、方法名、方法描述(参数、返回值类型等)、类是否被使用、方法是否被使用。

从Mach-O看砸壳及App的安全性原理

从上图中我们可以看出 APP 中有个 KFYGoodDetailsViewController 这个类。

从Mach-O看砸壳及App的安全性原理

我们还能知道代码中包含 changeStarForegrandViewWithPoint: 方法。

我们还能拿到所有函数的描述

从Mach-O看砸壳及App的安全性原理

可以知道函数的返回值类型是什么,参数类型是什么,参数有多少,但是参数的命名获取不到( NSString* name ,这个 name 获取不到。

从Mach-O看砸壳及App的安全性原理

还能知道有哪些类被使用过,包括系统的类已经自己的声明的类。但是通过 XIB 绑定的类不会被加入到 classref 。字符串动态调用的类也不被加入。

2 )扫描动态链接符号

动态链接符号包括动态库的函数、变量、私有函数。

从Mach-O看砸壳及App的安全性原理

扫描符号可以通过 nm 命令快速扫描输出到文件

从Mach-O看砸壳及App的安全性原理

U 代表是未定义符号(动态库中的函数),而 T 表示的是符号定义在 Text 段(自己写的函数)。

3 )扫描字符串

字符串包括: OC 字符串和 C 字符串

从Mach-O看砸壳及App的安全性原理

使用到的 @"%.2f" @“backgroundStar”

六、总结

Mach-O 文件的作用其实跟打孔纸带的作用是一样的,只不过 Mach-O 文件描述的内容更加丰富。除了代码和数据外, Mach-O 还包含了加密、验证这样的机制,使得代码更加安全。

参考: http://blog.cnbang.net/tech/3386/

从Mach-O看砸壳及App的安全性原理


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Smashing Book

The Smashing Book

Jacob Gube、Dmitry Fadeev、Chris Spooner、Darius A Monsef IV、Alessandro Cattaneo、Steven Snell、David Leggett、Andrew Maier、Kayla Knight、Yves Peters、René Schmidt、Smashing Magazine editorial team、Vitaly Friedman、Sven Lennartz / 2009 / $ 29.90 / € 23.90

The Smashing Book is a printed book about best practices in modern Web design. The book shares technical tips and best practices on coding, usability and optimization and explores how to create succes......一起来看看 《The Smashing Book》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具