【说明】英文原文发表时间:2013.6.3,原文链接:点击这里
简介
上一篇《iOS应用安全Part2:获取iOS应用的类信息》中,我们学习了如何使用class-dump-z工具获取APP的类信息。本文中,我们将重点学习Objective-C运行时的概念和技术。
Objective-C运行时
Objective-C是一种面向运行时的编程语言,但问题是,什么是运行时语言?运行时语言是也是一种语言,只是它可以在应用程序的运行时决定一个函数实现什么内容,以及其他方面的决策。那么,Objective-C是一种运行时语言吗?No,它只是一种面向运行时的语言,这意味着只要有可能,它会将决策从编译和链接时推迟到代码真正执行时。正如前面指出的,Cocoa提供iOS应用需要的运行时环境。下图是来自苹果文档的一段内容,里面很清楚地解释了这一点,同时你也可以在这里查看该文档。
现在,我们检查一下运行时库是否成功导入项目中。理想情况下,每一个iOS应用程序中都会包含运行时库。为了检查这一点,登录你的设备并进入到应用目录。
利用GDB对运行时分析
在本节中,我们将着眼于如何使用GDB观察APP的执行流程。首先,我们需要安装一个适当版本的GDB,而Cydia商店中的GDB版本不能正常工作。所以,要确保你从其他地方获得GDB的二进制文件。获取GDB之后,使用sftp登录到你的iOS设备,并上传GDB二进制文件。如下图所示:
然后,确保它有合适的权限来运行。
为了hook一个进程,首要的问题就是确保该进程目前正在运行。在本例中,我们将演示对谷歌地图APP的测试。所以,我们首先在设备上开始运行该应用,然后获取它的进程ID。同时,要确保该程序在前台运行。正如从下图我们能看到的,谷歌地图应用的进程ID是661,不过可能你测试时的进程ID会与此值不同。
现在,我们使用GDB hook进这个进程。
Objective-C是基于消息机制的,无论何时只要发送一条消息,objc_msgSend()方法都会被调用。为了分析一个APP的执行流程,我将为最基本的调用方法添加一个断点,例如objc_msgSend(),并打印$r0和$r1的值。从$r0的值中,我们可以找到该方法所属的类,还可以使用$r1的值来找到选择器。注意,尽管这可能会导致太多的细节,因为每次发送一条消息都会调用objc_msgSend()。在以后的文章中,我们将讲解如何更高效地使用它。因此基本上,每当程序执行到一个断点处,我都将打印$r0和$r1的值,然后继续执行。如下图所示:
我们输入指令“c”继续APP的执行。
Method Swizzling
我们已经知道,所有的iOS应用在执行时都会使用一个运行时环境,这意味着很多决策都是在运行时执行的。顾名思义,method swizzling是另一个武器,我们可以利用它来修改iOS应用的行为。它允许我们改变从选择器到实现的映射,利用这一点我们可以让程序调用我们自己的方法。在下一篇文章中,我们将深入学习method swizzling。参考资料
The Dark art of IOS Application hackinghttp://www.slideshare.net/daniel_bilar/blackhat2012-zdziarskidarkarti-osapplicationhacking/
The Objective-C runtime
http://www.slideshare.net/mobiledatasolutions/objectivec-runtime