写几篇文章总结一下 iOS 逆向的整个流程,逆向初学者可以作为入门指南。内容包括逆向工具和环境配置、踩坑点、界面分析、砸壳、静态分析、动态分析、lldb 调试、推荐 hopper 和 IDA 插件、IDA 插件的编写、各种分析技巧。
逆向的作用
对于 iOS 开发工程师:
- 通过查看界面、阅读汇编代码,研究参考其他 app 的实现方案
- 研究系统库的实现逻辑,用于修复 bug
- 查找使用私有 API,实现一些黑科技功能
- 接触底层原理,对 iOS 安全防护有更深入的掌握
- 获取其他 app 中的资源,例如游戏贴图
- 对第三方 app 进行一些自定义”改造”
我个人觉得逆向对我最大的帮助就是能够查看各种闭源代码的实现,满足好奇心的同时也拓展了思路,能够学到很多。
工具
逆向中常用的工具有:
- 越狱 iOS 设备一台(越狱后需要安装 openSSH 和一系列开发工具,建议使用 32 位的 armv7、armv7s 设备,因为旧版 Hopper Disassembler 不支持为 arm64 架构的汇编生成伪代码,最新版虽然支持,但是仍然不如 32 位的易读)
- reveal:查看任意 app 界面
- dumpdecrypted:对 app store 上下载的 app 进行砸壳解密的工具
- clutch:和 dumpdecrypted 功能相同,也是 app 砸壳工具,用法更简单
- class-dump, class-dump-z:分析 Mach-O 文件的类,导出 Objective-C 头文件
- Hopper Disassembler:反编译 iOS app 工具
- IDA:更强大的反编译工具, 缺点是价格贵
通过这些工具的作用,也差不多能一窥 iOS 逆向的面貌。
界面分析
这篇文章首先讲讲对普通开发者最有用的界面分析:如何查看任意 app 的界面结构。
有时候我们对某个 app 的界面实现方式感兴趣,直接查看它的界面层级就能明白大致的思路。
使用 reveal 查看 app 界面
Reveal 是一个 Mac 端的商业软件,可以查看任意 app 的界面构成,以及所属的类名、约束等信息。找到对应的功能的类名后,就可以使用后面的工具找对应的头文件查看方法。Reveal 有试用版,试用期30天,官方和淘宝店铺有正版合作,有国区优惠。使用方法如下。
1.客户端安装reveal插件
Reveal 的环境配置有一些坑,并且在不同的系统版本上配置方式不一样。
配置
iPhone 越狱后在 Cydia 里搜索RevealLoader
安装插件。Reveal 有多个版本,reveal 1.6.3支持 iOS 7,reveal 2(版本号从2一直增加到了最近的13)最低支持 iOS 8。如果用的是 reveal 2,则在 iOS 9 及以下系统仍然使用RevealLoader
,iOS 10 越狱机上则安装Reveal2Loader
。安装后在设置里会出现 reveal 工具栏(可能需要重启设备),找到需要查看的 app,打开开关,然后重启 app。
如果使用 reveal 2,还需要手动添加一个动态库到设备上,原因是客户端的库需要和 Mac 端的库版本一致。在 Mac 端的 reveal 中打开 Help -> Show Reveal Library in Finder
(根据目标机器的类型选择 iOS Library 或者 TvOS Library),将RevealServer.framework
拷贝出来。
如果是 iOS 9,使用RevealLoader
插件时,需要把RevealServer.framework/RevealServer
二进制文件重命名为libReveal.dylib
,拷贝到设备的/Library/RHRevealLoader
文件夹下,没有文件夹则手动创建一个。
如果是 iOS 10,使用Reveal2Loader
插件时,则将RevealServer.framework
拷贝到目标设备上的/Library/Frameworks/
目录下,如果已经存在同名文件,则替换。
最后,终端 SSH 到 iOS 设备,执行killall SpringBoard
,重启 SpringBoard 即可。
原理
这个工具是把 reveal 的库添加到了/Library/MobileSubstrate/DynamicLibraries
,并且提供了一个管理界面,并不是必须安装。当 app 启动时,MobileSubstrate 会自动把 reveal 的动态库注入到 app 中,然后和 Mac 端的软件进行通信。
如果选择不安装此工具,配置方法请参考https://zhuanlan.zhihu.com/p/19646016?columnSlug=iOSRe。
2.Mac 端打开 reveal 软件
Mac 端安装 reveal 软件,把 iOS 设备和 Mac 连接到同一 wifi 下。
开启需要查看的 app,进入需要查看的界面,在 Mac 端 reveal 里选中,即可开启。
3.查看页面信息
你可以拖动界面,立体地查看界面结构。这个查看方式是 reveal 首先发布的,后来苹果官方把它集成到了 Xcode 中。
页面的右边,可以找到此页面对应的类名,以及尺寸、约束等信息。
下面是微信的扫一扫界面,可以看到界面的类名为 CameraScannerView 和 CameraScannerViewController。reveal2 开始,也可以查看 extension 的界面,比如通知中心插件。
其他界面查看方式
不用 reveal 也可以查看 app 的界面。
1. lldb 打印界面层级
可以在动态分析 app 时,用 lldb 打印出 app 的界面层级。命令是:
|
|
打印出来的结果类似于:
|
|
recursiveDescription
是UIView
的私有API,注意不是所有的UIView
都能使用,在有些视图上会crash。
可以再用nextResponder
获取UIView
对应的 view controller。
由于看得眼花,所以这个方式我很少用。
2. 直接使用 Xcode 的Debug View Hierarchy
可以用 Xcode 直接调试重签名后的 app,然后就可以用Debug View Hierarchy
查看界面层级了。
3. 越狱插件:FLEX
可以安装越狱插件,直接注入到 app 中,打印出界面信息。可以去 Cydia 中直接下载安装,也可以去这里编译源码使用:FLEX。
总结
界面分析对于猜想某个界面的实现方式有很大帮助。想要分析其它功能时,也可以通过界面分析先找到对应的类,再进一步进行静态分析和动态分析。下一篇文章将会讲解如何进行静态分析。