Android 的源码是开放的, 开发者很容易了解系统机制, 但是 iOS 的代码是封闭的, 单从文档上还是不足以深入的了解系统机制, 有没有方法能够对 iOS 进行逆向工程, 让开发者能够更深入了解系统?
按照意图和深度的话,大概有这么几种途径与资源:
- 为了学习框架,提升开发水平,可以看看私有API列表。iOS (Cocoa Touch)的各私有API都可以通过runtime查看获得,您可以自己写个method browser。如果觉得麻烦的话可以到Github看现成的,我收藏了俩: https://github.com/kennytm/iphone-private-frameworks 和 https://github.com/nst/iOS-Runtime-Headers ,但还是推荐自己来实时获取,因为iOS在更新,API也在更新。在App Store产品中使用私有API是违反苹果规定的,所以能不用这些API而实现一些功能是iOS工程师水平的体现。
- 对iOS工程师而言,如果只是开发的话(1)也就差不多了。如果您十分有爱,想了解API以下的东西的话,依然可以利用Obj-C的runtime。可以在这里看到 http://opensource.apple.com/source/objc4/objc4-493.11/runtime/ ,尤其是objc-runtime.m,这里提供了很多学习用的"工具"。比如经典的method_exchangeImplementations(),您可以用它研究很多黑箱过程的来龙去脉。值得一提的是,这种技巧(method swizzling)是合法的,可以在App Store 中使用! 苹果曾给使用了相关技巧的开发者发过邮件,表示出于安全性和稳定性最好不再使用,但没有禁止。
- 如果是对系统本身感兴趣的话,不妨越狱看看。iOS和Mac OS X类似,基于Darwin,是一种UNIX系统。越狱后你就有了root权,可以安装个Terminal,装gcc都没问题的哈哈~ 接下来就像您研究Linux那样摆弄就好了。对于开发者来说,有了root权也就可以写一些system tweak或全局的代码,自然也可以用来深入了解系统、原生app等。这方面我很久没折腾了,所以不敢瞎说。
- 如果您是想成为一名iOS Hacker的话,最近有本书挺火的: http://www.amazon.com/iOS-Hackers-Handbook-Charlie-Miller/ 我没空看不知道咋样,但作者很神。另外现在iOS越狱界也有了自己的大会,可以看看“越狱梦之队”的演讲和文档: http://absinthejailbreak.com/dream-team-presentation-at-hitbsecconf-videos/ 。如果您还是没有满足的话,可以看看从硬件入手的逆向工程和调试,分享一个我收藏的宝贝: http://wenku.baidu.com/view/dae22c30eefdc8d376ee32c9.html
- 另外说iOS代码是封闭/闭源的其实不全对,苹果算是开源界的一面大旗了,比如WebKit。iOS的组成部分也一样是开源的,可以在官网 http://opensource.apple.com/ 看到,最新的iOS 5.1.1在这: http://opensource.apple.com/release/ios-511/ 。但是如您所见,这里并没有iOS操作系统的代码,而是一些库和编译器、调试器...其中JavaScriptCore和WebCore很有用,这两者是WebKit的基础,可以说WebKit是iOS最重要的组成之一,截止iOS 5 (6我还没下呢=___=),所有多于一行文字的控件其实都是WebKit标准的(不可思议吧?!)。很多iOS的Hack都是从这里开始的。说到WebKit,之前Comex大神的Spirit越狱(那个"Slide to Jailbreak")就是利用Safari->WebKit->PDF Engine->TIFF字体的漏洞实现了代码注入!所以每一个系统组件都可能是iOS逆向/Hack的突破口!
- 0x0.Background: 你必须要有很强的逆向sense,这个是逆向分析的基础,逆向的sense举个栗子:如果你发现看到一个产品之后能够大致猜出它的架构,它的关键部分,核心算法以及可能存在的bug,甚至能够猜出影响性能的是哪部分,这个需要很长时间的逆向分析和工程开发的经验。BTW:语言什么的就不说了,ARM,X86指令,Objective-C,C,C++
- 0x1.Tools: 你需要掌握以下工具:otool,lipo,ar,libtool,class-dump,mach-o-view(有空读一读它的代码,自己编译以下,加点功能什么的),hopper disassemble,ida pro,gdb,xcode开发要会的就不提了,还有一个很有用的codeunsign,最后再推荐一个我写的一个magic类:cccssw/call_at_anywhere GitHub 这个类用途很广,发挥余地很多.
- 0x2.Frameworks: 调用私有API什么的是最简单的部分,最直接的路径是去private frameworks下面根据frameworks的名称猜测各个framework是干什么的,然后用class-dump dump出header,在项目里面引用就可以用了.如果观察力到位,发现某些官方app有某些功能能够猜测出背后可能有调用私有api,反汇编这个官方程序就能找到私有api的调用形式.
- 0x3.Kernel: ios 和macos都是bsd+mach-o的混合模型,网上有一个图很清楚,说明其架构的. mach-o 的格式学习的最佳途径就是看mach-oview这个开源项目的代码。
- 0x4.Defend technics used by Apple:用得最普遍得就是利用xpcservice将调用放在另外一个可执行程序中,然后函数调用通过进程间通信完成,核心得逻辑不会在这个xpc调用里面,该xpc远程程序会继续调用底层frameworks,最后你就很难找到最核心的逻辑和算法到底在哪里了;关键部分用c实现,然后隐藏data structure,只留出必要的指针,hidden pointer的技术,keychain的实现就是这样做的,要逆向出它keychain的数据库格式非常难,尝试过,失败了;另外一方面可能考虑到代码的可维护性,大部分苹果的代码都有很详细的log,可能有开关控制log的打开关闭,如果能把log开起来,一个程序,framework就很容易跟踪了(静态分析),打开这些log一般要直接修改二进制文件,或者修改特殊的plist文件.
- 0x5.static analysis:静态分析一般就是先定位最关键的地方,定位的方法很多,一般先开log,然后分析完log后通过关键字来找。定位成功后,没有什么底层技术时,你想要干的事情基本上就快完成了,逻辑就在你面前,汇编配合伪代码就很简单了(除了有FSM或者jmp table的情况,这种情况还是动态分析吧). 有些涉及到底层技术,有一种内核级别调用的陷入函数(涉及到mach-o内核机制)比较麻烦,这种情况也有一些办法,做起来怎么样都是限制大,这篇文章How I cracked the security foundation of Mac OSX System 提供了一些技巧和思路。
- 0x6.dynamic analysis:动态分析要配合静态来做,主要还是用xcode的调试器或者gdb,xcode的符号断点.f6-f7-f6慢慢调.
- 0x7.reimplement logics:功能重现,逆向里面经常要做的事情,一个加密算法,解密算法要重新实现一遍,让自己可以用。途径有两条:1.照着汇编写出汇编版,c版或者objective-c的实现;2.直接调用二进制中的函数. 途径1是考你功底的,功底深做起来就是个体力活而已。途径2有两条路,一是修改二进制文件,或者patch你要的逻辑到一个有架子了的二进制文件,二是计算函数地址动态加载。 重点讲一下途径2,静态修改很麻烦,直接暴露需要解决以下问题:mach-o文件中有两个section与export function有关,其中一个Symbol table和与之相关的String table较容易修改,另外一个是Dynamic loader info比较难修改,里面有的相对位置需要做uleb128转换,另外存储信息的格式是链表格式,解决这两个就可以了. 静态修改除了这些,mach-o前面与section对应的头信息也要修改,长度,位置偏移量.; 途径2的动态加载就不多说了,看我github的项目call_it_any_where 应该是目前为止最方便的方式。
- 0x8.jail-development:越狱开发其实门槛比app store还要低.这一块与逆向有关的主要是hook class之类的,老外有一篇很详细的博文讲这块。貌似就在后面的blog list里面.
- 0x9.security issues: 建议手机别越狱,mac和ios下的maleware其实比windows下面还难发现.;keychain里面即使最严格的ACL策略也是能够绕过的;
不会逆向的程序员不是好程序员。
最后再给些blog供学习:
- Reverse Engineering Mac OS X
- ChinaAlex
- Reverse Engineering
- rentzsch (Jonathan 'Wolf' Rentzsch) GitHub
- Matt Galloway