# iOS冰与火之歌番外篇 - App Hook答疑以及iOS 9砸壳

Author: 乌云历史资料库 (@wooyun_archive)
Published: 2016-03-16T02:29:00Z
Canonical: https://wepostx.com/topics/132

> 乌云历史资料归档
>
> **原始作者：** 蒸米
> **原始编号：** superkieran-wooyundrops:1091
> **原始发布时间：** 2016-03-16 10:29
> **声明：内容仅用于技术研究和个人使用，版权归 wooyun.org。**

---

# 0x00 序

上一章我们讲到了在非越狱的iOS上进行App Hook。利用这个技术，你可以在非越狱的iOS系统上实现各种hook功能（e.g., 微信自动抢红包，自动聊天机器人，游戏外挂等）。但因为篇幅原因，有一些细节并没有讲的非常清楚。没想到阅读量非常大，很多人都来私信问我一些hook中遇到的问题，并且问的问题都很类似。于是我专门写了一篇答疑的文章来帮助大家解决一些常见的问题，顺便介绍一下如何在iOS 9上进行app 砸壳 (Dumpdecrypted)。另外想看主线剧情的读者也不要着急，下一篇就会给大家带来如何过沙盒的文章。
《iOS冰与火之歌》系列的目录如下：

- Objective-C Pwn and iOS arm64 ROP

- 在非越狱的iOS上进行App Hook（番外篇）

- App Hook答疑以及iOS 9砸壳（番外篇）

- █████████████

- █████████████
另外文中涉及代码可在我的github下载:
[https://github.com/zhengmin1989/iOS_ICE_AND_FIRE](https://github.com/zhengmin1989/iOS_ICE_AND_FIRE)

# 0x01 如何编译hook.dylib

很多人私信给我提到hook.dylib无法编译成功，这个问题大多是因为没有安装Command Line Tools和越狱开发环境iOSOpenDev造成的，这两个工具都是搞iOS安全必备的环境，可以按照以下步骤进行安装：
Command Line Tools 是Xcode的一个命令行工具插件，安装方法有两种：
(1) 打开终端，输入：

```text
#!bash xcode-select --install
```
(2) 去苹果官网下载安装包
[https://developer.apple.com/downloads/](https://developer.apple.com/downloads/)

![原文图片](/media/2016/06/2b0aa2c3684399753532f265c8e73720)

iOSOpenDev里提供了很多越狱开发的模板，可以在[http://iosopendev.com/download/](http://iosopendev.com/download/)下载到。安装完iOSOpenDev后就可以在Xcode里通过新建一个project看到我们进行非越狱Hook的时候需要用的CaptainHook了。

![原文图片](/media/2016/06/9715b6f1c4f2c0d00f674d6172e53327)

# 0x02 如何得到App Store上解密后的ipa

我们开发时的app默认是没有加密的，但App Store上下载的app却被加了密。如果我们想要进行hook以及重打包的话，我们需要拿到解密后的app才行，否则的话，就算hook成功，签名成功，安装成功，app还是会闪退。
(1) 查看app是否加密：
首先用file来看一下ipa解压后的二进制文件包含哪些架构（e.g., armv7, arm64）。如果有多个架构的话，最好是把所有的架构都解密了。但理论上只要把最老的架构解密就可以了，因为新的cpu会兼容老的架构。比如我们拿微博作为例子，可以看到weibo的客户端包含了armv7和arm64这两个架构。

![原文图片](/media/2016/06/edc9e6bf444bb5512c88c113fe6712d5)

随后我们可以通过”otool –l”来输出app的load commands，随后再查看cryptid这个标志位来判断app是否被加密了。如果是1的话代表加密了，如果是0的话代表解密了。

![原文图片](/media/2016/06/a9ecf31f63159e55069443037a8b2f96)

从上图可以看到，weibo的armv7架构的代码被加密了，arm64架构却是解密的，原因是我已经通过dumpdecrypted对arm64架构的代码砸过壳了。如果没有解密的话，用ida打开app会看到加密的提示：

![原文图片](/media/2016/06/cebed468e6c438f4cb20c6e8be2e3fcf)

(2) dumpdecrypted砸壳：
如果需要解密的话，我们就需要用工具进行砸壳。最有名的砸壳工具就是dumpdecrypted了。他的原理是让app预先加载一个解密的dumpdecrypted.dylib，然后在程序运行后，将代码动态解密，最后在内存中dump出来整个程序。这个工具可以在: [https://github.com/stefanesser/dumpdecrypted](https://github.com/stefanesser/dumpdecrypted)下载到。但下载完的只是源码，我们还需要编译一下，这里我会放一份编译好后的dumpdecrypted.dylib到我的github上。
虽然hook可以在越狱的环境下实现，但是想要砸壳的话，必须具备越狱的环境，比如这篇文就使用的越狱后的iOS 9。用ssh连接上iOS设备后，我们打开想要砸壳的app。然后输入ps ax，就可以在进程中找到这个app的二进制文件的地址：

![原文图片](/media/2016/06/d1fc32df4bd360bc715e5de5d90e8c48)

因为每个app目录下都有一个Info.plist。我们可以通过这个Info.plist得到app的Bundle ID：

```text
#!bash cat /var/mobile/Containers/Bundle/Application/19A9AE5E-22DC-449A-A530-C793D88ACB24/Weibo.app/Info.plist
```

![原文图片](/media/2016/06/6aa6deb1ac50ac3d09e86f8ce843450f)

比如Weibo的Bundle ID就是：com.sina.weibo。得到BundleID后我们下一步要知道app的data目录，原因是app的运行会受到沙盒的限制，因此dump出来的app只能保存在自己的data目录下，这里我们可以通过Bundle ID和一个private API得到data目录的位置：

![原文图片](/media/2016/06/f10838d25c6ec76d2b27d1f664d1feaa)

代码如下：

```text
#!objc NSString* bundleID = [[NSString alloc] init]; bundleID = @"com.sina.weibo"; id dataID = [[NSClassFromString(@"LSApplicationProxy") applicationProxyForIdentifier:bundleID] dataContainerURL]; NSLog(@"%@",dataID);
```
得到data目录的地址后，我们将dumpdecrypted.dylib 拷贝到data的tmp目录下，然后在tmp目录下执行DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/19A9AE5E-22DC-449A-A530-C793D88ACB24/Weibo.app/Weibo进行砸壳。

![原文图片](/media/2016/06/89e4ebf4bd2497682658343a8e58115f)

然后在目录下就可以得到砸壳后的二进制文件了，要注意的是我们砸壳后的app只能解密砸壳运行时的架构，所以我建议找个armv7架构的iOS设备进行砸壳，然后执行：

```text
#!bash lipo app -thin armv7 -output app_armv7
```
就可以把app的armv7架构抽取出来。这样的话，就可以保证app只在armv7的模式下运行了。
(3) 越狱市场下载：
当然，除了利用dumpdecrypted获取解密后的app还可以直接在PP助手的越狱市场上下载到，这些越狱应用都是解密后的app。但不能保证下载到AppStore上所有的app。

![原文图片](/media/2016/06/02ede121df68554c0bb62dc0febb7a1e)

# 0x03 获取embedded.mobileprovision的技巧

有人会问如何获取embedded.mobileprovision这个文件，因为自己开发的app默认会有embedded.mobileprovision，但从AppStore上下载app并没有。其实，除了在developer center上通过录入device的UDID，然后下载embedded.mobileprovision之外，我们还可以利用xcode自动生成embedded.mobileprovision。比如我们想要重打包微博这个app，只要新建一个app（为了确保万无一失，可以把app的Bundle ID也起为com.sina.weibo），然后把手机连接上电脑，编译并在手机上运行这个app。然后只要去app的目录下拷贝embedded.mobileprovision就可以了。这样获取的embedded.mobileprovision可以保证能够适配重打包的app。如下图所示：

![原文图片](/media/2016/06/c72579c3523f489ae396bc76e18fbf25)

# 0x04 签名的技巧

签名的时候我们需要提供entitlement的信息，这个entitlement是什么呢？其实这个entitlement是用来做iOS权限管理的，通过声明不同的entitlement就能得到不同的权限。并且这个信息已经保存到了二进制文件里。比如我们可以通过”ldid –e”来查看一个二进制文件的entitlement。比如Weibo的entitlement为：

![原文图片](/media/2016/06/c695fcaf382af4b67a7c758cea86c07d)

理论上需要给app签上原app对应的所有entitlement才行。
另外，除了app本身需要签名以外，app的PlugIn，WatchNative App，WatchNative App的PlugIn如果有的话，都需要签名才行，拿WeChat举例，我们要对如下的内容都签名才可以：

```text
#!bash codesign -f -s "iPhone Developer: [email protected] (**********)" WeChat.app/Watch/WeChatWatchNative.app/PlugIns/WeChatWatchNativeExtension.appex codesign -f -s "iPhone Developer: [email protected] (**********)" WeChat.app/Watch/WeChatWatchNative.app codesign -f -s "iPhone Developer: [email protected] (**********)" WeChat.app/PlugIns/WeChatShareExtensionNew.appex codesign -f -s "iPhone Developer: [email protected] (**********)" WeChat.app/hook2.dylib codesign -f -s "iPhone Developer: [email protected] (**********)" --entitlements Entitlements.plist WeChat.app
```

# 0x05 安装大ipa的方法

上一篇中介绍了一种利用libimobiledevice来安装ipa的方法。但我在尝试安装特别大的ipa的时候（大于50M），经常会失败，需要尝试多次才行。这里有个小技巧，如果有条件的话，可以使用windows下的itools来辅助我们安装，基本上一次就能搞定了。

![原文图片](/media/2016/06/590547db2532fef32a87a0b3e02d7e08)

# 0x06 总结

这篇文章基本上解决了app hook过程中遇到的常见问题，还介绍了iOS 9上砸壳的技术。如果还遇到问题的话，大家可以通过xcode里的log来分析原因，然后尝试解决问题。至此，iOS app的安全（番外篇）就告一段落了。下一章将会进入主线剧情，给大家带来app过沙盒的技术，敬请期待。

## Replies
