最近各大“媒体”都在报道《iOS 应用逆向与安全》这本书,这是自“小黄书”出版后的又一本关于逆向安全的书。而目前很多 iOS 开发者对逆向还非常“小白”,以至于盲目地觉得逆向很难、很厉害。而这本书的出现,无疑为逆向这个世界打开了另一扇窗,我们一起看看这扇窗里纠结“藏”了什么。本文并不打算介绍书中具体细节,只是说明每一章都讲了哪些内容,点到为止。
第一章 概述
本章主要对逆向整体进行描述,分别从应用中存在的风险、如何保护应用的安全、和开发工具的使用来介绍。而我觉得本章的核心是掌握逆向的流程和作用,了解 APP 开发中需要注意的安全问题。
逆向流程: 逆向的整个流程基本是相同的,而这些流程可以总结为:
获取应用的 ipa 包,解密(如果是越狱应用则不需要解密),导出头文件;
通过界面查看 APP 的布局,从布局中找到对应的头文件,查看关键函数;
hook 相关函数,达到你的目的;
静态分析加动态调试分析关键函数;
模拟或篡改原有 APP 的逻辑;
达到自己的目的。
应用场景:掌握逆向肯定非常有用,如果你想从事安全方面的工作,可以深究,否则不必投入太多的精力,毕竟正向开发中很少用到逆向知识。学习逆向知识可以总结为:
借鉴第三方 APP 的实现思路,比如某个功能是如何实现的、界面使用了哪一类型的 View,数据库结构是什么样的等等;
加深对正向开发的理解,比如 runtime;
普及安全知识,了解逆向可以做什么后,在开发中你就会知道哪些信息会被别人获取到,比如某个 APP 根据本地的数据判断是否可以使用付费的资源,这明显使用逆向即可使用付费资源;
第二章 越狱设备
本章主要讲解越狱在逆向中的作用及越狱工具的使用。这里需要强调一点,逆向不一定需要越狱,而想要更好地掌握逆向的原理,一台越狱设备是必不可少的。目前市面上很多越狱工具,也提供了一键越狱,读者可自行搜索。
登录越狱设备:
手机越狱后,会安装一个 Cydia 的软件,它主要用来在越狱手机上安装各种工具,相当于越狱中的 “App Store” 。想要读取越狱设备中的资源文件,必须进行远程登录。搞服务器的同学都知道使用 SSH 进行远程登录,而登录越狱设备也可以使用 SSH 登录。通过 Cydia 搜索 OpenSSH 来安装即可,安装完后执行:
sudo ssh root@手机ip地址
登录成功即可对越狱设备进行操作了。作者还介绍了其它登录越狱设备的方式,使用公钥 登录,USB 登录。
文件目录:
如果想查看设备的文件系统,在 Mac 上可使用 iFunBox,手机端需要安装 Apple File Conduit 2 。安装成功后,即可通过 iFunBox 查看手机的目录结构,比如安装的 APP 沙盒目录,系统自带 APP 的沙盒目录,各种 Frameworks 等等。
越狱必备工具
adv-cmds: 执行 ps 命令报错,需要安装这个工具;
appsync: 让系统不再验证签名,以免安装应用失败;
iFile:在手机上查看文件目录;
scp:终端命令,把远程设备的文件复制到另一个设备;
Cydia Substrate:允许第三方开发者在越狱系统的方法中打一些补丁或扩展方法。
第三章 逆向工具详解
你可能仅仅停留在对这些工具(dumpdecrypted、Clutch、class-dump、Reveal、Cycript、Charles、Wireshark)的使用上,比如我。而作者却给我们讲解了原理,可见他的功力很深。
dumpdecrypted
AppStore 中的应用都是经过加密的,而逆向的前提需要把加密的内容解密出来。dumpdecrypted 这个工具就是专干这件事的。当然,如果你不想解密,可以直接从越狱市场上下载被解密的 APP。不过有时候越狱市场上没有你要的应用就不得不自行解密了。它的原理引用作者的原话:
dumpdecrypted 是一个开源的工具,它会注入可执行文件,动态地从内存中 dump 出解密后的内容。
Clutch
除了使用 dumpdecrypted 进行解密,Clutch 也可以做到。不过作者提到使用这个经常会出错,建议使用 dumpdecrypted。
class-dump
class-dump 的作用是从可执行文件中导出类、方法、属性信息的工具,这里需要强调一下可执行文件,被解密的 APP 应用中会有一个可执行文件(Mach-O)。可以从 xxx.app 中的 info.plist 文件找到 Executable file 它的值即是 xxx.app 的可执行文件。使用 MatchOView 可以查看 Mach-O 文件。
导出 We.app 的头文件:
class-dump -H ~/Desktop/reverse/ipa/We.app -o ~/Desktop/reverse/header/we
Reveal
是用来查看APP界面的工具,查看第三方 APP 不一定非用越狱设备。
Cycript
Cycript 是一个允许开发者使用 Objective-C++ 和 JavaScript 组合语法查看及修改运行时 APP 的内存信息的工具。在逆向中主要用来验证某些猜测是否正确,查看界面信息等。比如查看当前显示的 VC,某个对象执行某个函数后的结果,动态修改某个 UI 的信息。
Charles、Wireshark
介绍了这两个抓包工具的使用。
第四章 开发储备
这一章主要介绍正向开发的一些知识,而这些知识对逆向开发很重要。
ipa 包
获取应用的 ipa 包,主要可以通过两种方式获取:
从 iTunes 中获取,目前的 iTunes 中已不支持,需要下载低版本的 iTunes。 下载;
直接从越狱设备获取,其实直接从各种助手中无需越狱设备即可下载越狱应用,获取到 ipa 包;
应用包的构建过程:
compile:使用 Clang 编译源文件;
link:将编译生成的目标文件链接成一个可执行文件;
storyboard:编译项目中的 storyboard 文件;
plist:生成 plist 文件;
asset:将需要的资源文件复制到 App 目录下;
dsym:生成符号文件;
codesign:对 App 进行签名;
package:打包。
界面与事件传递
介绍了 iOS 中的 UI 、事件传递和事件响应。
类与方法
主要介绍了类的底层实现,OC 中的消息机制,runtime 的一些使用场景。
App签名
正向开发中,每个同学都会经历一次苹果的证书配置。而作者在这里主要讲解了 App 签名的原理,这样为逆向重签名做好铺垫。
第五章 分析与调试
前面四章主要为后四章做一个铺垫,从接下来的章节中正式开启了逆向。本章主要从静态分析和动态调试来介绍逆向。
静态分析,指在不允许 App 的前提下对程序分析的一种方法。一般有以下几种方式:
基于 ipa 和 app 包;
基于文件格式;
基于二进制反汇编;
反汇编
反汇编主要有两个工具:Hopper 和 IDA。而这两个工具可以查看源代码实现的汇编代码,关键还可以查看伪代码。以前一直觉得 Hopper 不好用就没用,今天下载了一个用起来发现比 IDA 用着舒服。
Hopper 只支持 Mac 和 Linux,相对于 IDA 比较弱一些。而 IDA 支持 Windows 平台。
静态库分析
有时候想看某个静态库的实现,其实也可以使用 Hopper 查看他的汇编代码。
? 5.1 静态分析 ls
Crashlytics UserLogin
? 5.1 静态分析 lipo -info Crashlytics
Architectures in the fat file: Crashlytics are: armv7 armv7s i386 x86_64 arm64
? 5.1 静态分析 lipo Crashlytics -thin arm64 -output Crashlytics_arm64
? 5.1 静态分析 mkdir Objects
? 5.1 静态分析 cd Objects
? Objects ar -x ../Crashlytics_arm64
? Objects grep "Upload" -rn ./
Binary file .//CLSReportsController.o matches
Binary file .//CLSCrashReportingController.o matches
Binary file .//CLSNetworkClient.o matches
? Objects otool -l Crashlytics.o|grep bitcode
sectname __bitcode
? Objects ld -r -arch arm64 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -bitcode_bundle ./*.o -o ../output
动态调试
动态调试是在程序运行的时候执行一系列操作,比如获取某个对象的值,执行上下文等。
LLDB 动态调试:正向开发中常会使用到 LLDB 来调试程序,而在逆向中它也发挥很大作用。
用 Xcode 调试第三方应用:使用 Xcode 在非越狱设备中调试第三方应用、进行符号的还原、查看带符号的堆栈调用。不过调试的时候需要一个第三方应用。
Theos
越狱开发中除了 Thoes 外还有一个叫 iOSOpenDev 的工具,功能和 Thoes 是一样的,不同点是iOSOpenDev 是整合到 Xcode 中使用的,而 MonkeyDev 和 iOSOpenDev 属于同一类型的工具。
MonkeyDev
MonkeyDev 是作者开发的一个工具,主要用 Xcode 进行越狱开发。具体使用可以查看 MonkeyDev 的 wiki 。
第六章 逆向进阶
这一章,看着比较吃力。很多都没接触到,这里简单的做个介绍,如果以后用到这部分内容再继续深究。
程序加载
在程序执行 Main 函数之前,都做了哪些事。
Mach-O 文件格式
对于每个 ipa 包,都会包含一个可执行文件,而这个文件就是 Mach-O 文件。
ARM 汇编
逆向如果想看懂代码,那么必须学会汇编。
hook
hook 直译为 钩子,通过 hook 可以改变程序执行逻辑。hook 最常见的有以下三种方式:
MethodSwizzle:
通过 runtime 交换方法的实现。
fishhook:
fishhook 是 facebook 开源的一个库。
A library that enables dynamically rebinding symbols in Mach-O binaries running on iOS.
Cydia Substrate:
动态库
特点:
存在形式有 .dylib,.framework 和链接符号 .tdb;
它的格式和普通二进制文件没有区别;
它的好处是可以只保留一份文件和内存空间,从而能够被多个进程使用,例如系统动态库;
可减小可执行文件的体积,不需要链接到目标文件。
在逆向中会经常用到动态库,比如使用 Reveal 调试第三方应用时需要把 RevealServer. framework 注入到 APP 程序中。可以通过引入头文件的方式调用 和 dlopen 动态加载的方式调用动态库。
第七章 实战演练
这章主要应用前几章学到的知识。而逆向开发可以在越狱设备和非越狱设备中开发。
越狱设备
目标是给 WhatsApp 长按消息添加一个收藏菜单,并在设置中添加已收藏的消息。分别在越狱设备、非越狱设备进行分析。
下载 WhatsApp 使用 dumpdecrypted 解密;
使用 class-dump 导出头文件,导出头文件时加上 -A 参数可以显示方法在文件中的实现地址;
符号还原,方便后续使用 lldb 进行调试;
分析某个应用时,需要从界面入手,使用 Reveal 查看界面的层级结构,定位到具体的视图控制器,从头文件找到对应的方法;
根据找到的方法,使用 lldb 添加断点,验证是否会调用对应的方法,以确定是否为需要找的方法;
使用 Hopper 查看伪代码,猜测具体的实现方式;
非越狱设备
目标是给 WhatsApp 添加自动回复功能。越狱设备分析有诸多繁琐的工作,比如导出头文件,使用 Reveal,使用 LLDB 调试不方便等。所以作者把这些功能都集成到了 MonkeyDev 这个工具中,通过 MonkeyDev 新建工程将自动集成 class-dump、符号还原、Reveal、Cycript、注入动态库、自动重签名等一系列重复性的工作,可以直接在非越狱设备上进行逆向分析。具体使用参考
Frida 实战应用
Frida 是一款跨平台的注入工具,通过注入 JS 与 Native 的 JS 引擎进行交互,从而执行 Native 的代码进行 hook 和动态调用。这个工具可以用于 Android 和 iOS,它可以通过一段 JS 来调试应用。