这里从原理上如何实现iOS的逆向工程的,以及如何从工程化的角度去实现逆向一个iPA。在我看来整体的流程上就三个步骤:砸壳->注入->重签安装。
砸壳
从AppStore上(官方渠道)分发的ipa包都是经过加密的,逆向的第一步就是对这个应用进行解密。不过在现如今,实施这个过程的前提条件:
一台越狱iOS设备
一条命令实现dump砸壳应用,Frida-ios-dump一键砸壳菜鸡版
照着上面文章中的流程在iOS和MacOS上分别装好frida后需要连到越狱机器的控制台,接着需要连接通过usb连接到iOS上,这时候用到iproxy
这个命令可以通过brew install usbmuxd
安装,同时记得要利用cydia给越狱机器装上ssh才能登录得上。
接下去利用frida-ios-dump这个工程提供的脚本进行一键dump砸壳ipa包。
1 | # 配置frida-ios-dump运行环境 |
注入
到了这一步是真正需要进行开发修改功能/代码的。注入这个话题可以很大,真正的实施过程需要
有很多的理论基础才行,之前在Hook初体验这里简单学习了在iOS平台下Hook代码及注入动态库的基本原理。
简而言之,在iOS上我们可以从两个层次来实现功能入侵和修改:
- OC层次:Metod Swizzling/+load
- C层次:修改dyld链接符号表
关于如何Hook的技术细节以及它的应用场景在这里就不讨论了,在iOS中可以利用MonkeyDev注入framework到目标app中,同时它还支持利用cocoapods开发自己的插件。
重签
一个已签名的可执行文件的签名包含在 Mach-O 二进制文件格式中;对于例如脚本这样的非 Mach-O 可执行文件,就存放在该文件系统的的扩展属性中。
这种做法使得在 OS X 和 iOS 上的任何可执行二进制文件都可以被设置签名:不论是动态库,命令行工具,还是 .app 后缀的程序包。这也意味着设置签名的过程实际上会改动可执行文件的文件内容,将签名数据写入二进制文件中。
关于证书签名(Code Signing) / 授权机制(Entitlements) / 配置文件(Provisioning)的区别和实现原理可以参考iOS App签名的原理和代码签名探析。
通过上面的文章可以知道:
- 钥匙分为公钥和私钥,它们基于RSA算法,是一种不对称的加密方式。通过公钥进行签名(加密)的数据只能通过私钥验证(解密),反之亦然。
- 数字证书中包含一个L公钥和一个经过A私钥签名(加密)的数据内容。
而在这里我们重签指的是通过MacOS下codesign
工具去替换配置文件(Provisioning Profile)以及重新签名相关资源的过程,比如我们拥有:
- Appstore上某个经过砸壳的iPA包(无证书或者使用该证书无法装到个人iPhone上)
- 个人开发证书
这时候我们装上这个iPA包就必须进行重签。
重签命令的基本格式:1
2
3
4
5# .framework 与 .dylib 签名
codesign -f -s <证书> <framework 二进制>
# app 与 appex 签名
codesign -f -s <证书> --entitlements <Entitlements 文件> <app 二进制>'
一波带走
当我们手上没有越狱机器又需要进行逆向工程的时候该怎么办呢?
- 从xx助手等第三方渠道下载破壳(越狱)的ipa包。
- 集成MonkeyDev工程进行逆向开发,其中注入和重签步骤都可以通过这个工程完成。
参考
Cydia App
iOS 10越狱与SSH连接
Coding Signing Guide
iOS开发中的证书和钥匙
iOS数字签名和iPA重签
iOS逆向之旅(进阶篇) — 重签名APP(一)