-
-
[翻译]iOS内核调试教程
-
2018-2-5 21:43
4656
-
iOS 内核是一种非常复杂的软件,如果你需要和它打交道,拥有一个调试器会非常的方便。它拥有单步运行代码,设置断点,读写内存和寄存器等功能。幸运的是,Apple 工程师们自用的开发调试器已经内置在产品的发行版里了。但是它有点难以安装和运行,因此我希望这篇教程能够帮到大家。
步骤1:需要的物品
进行基本的内核调试所需要的东西如下:
- 一个可以设置启动参数或是打过用于调试的内核补丁的 iOS 设备。
在这篇教程中我使用的是iPhone4 ,我们可以使用RedSn0w 工具来对它设置启动参数。
- 一条 iOS 串口调试线.
你可以根据这篇教程自己动手制作,或是在网站 AliExpress 上买。这些数据线用于把 iOS 设备上的串口数据转化为 USB 协议的数据。当然,你也需要安装适配你当前操作系统的驱动。它们可以在这里下载到
- Apple 版的 GDB.
这个 GDB 和 XCode 非常兼容。
- 安装 serialKDPproxy.
这一用于内核调试的协议一般是用于 UDP socket 通信而不是串口,所以我们需要使用一个工具帮助我们进行代理工作。幸运的是,有人已经把相关的代码写好了。代码和安装教程可以在这里找到
步骤2:对设备进行越狱并设置启动参数
iOS 内核并不能被即时地调试。这是因为苹果的工程师们不想它被轻易地发现漏洞。所以我们必须对设备进行越狱以设置正确的启动参数,并打上合适的内核补丁。
使用 RedSn0w 对 iOS 设备越狱的过程可以在其他地方找到。当你使用这一工具的时候,设置启动参数是非常重要的。你可以通过Extras -> Even More -> Preferences -> Boot Args来设置这一参数。在下一步中,你应该输入下列字符串"debug=0x8f -v wdt=0"。
这些参数是为了告诉内核去做这些事:
- 作用特定的标志伴以调试模式启动
- 以 verbose 模式启动。(译者注:该模式会在屏幕中显示启动过程中的详细信息)
- 启动中设置一个计时器,以在任意时刻暂停程序而不需要 kill 进程
当你启动的时候,设备就会在开启的时候挂起,并等待调试器附加
步骤3:使用 SerialKDPproxy
现在设备已经被挂起,我们就需要启动 serialKDPproxy。用法是./SerialKDPProxy。在我的例子中是./SerialKDPProxy /dev/tty.usbserial-AH00NR2W。在此之后,应该会有各种各样的调试信息输出在设备的控制台上。你也可以在设备启动之前运行它,这样就会有大量输出告诉你当设备启动时它到底做了些什么。例如 kernel slide 就会显示出来,它可以让我们确定函数地址。
步骤4:使用 GDB 调试
因为 serialKDPproxy 转发了我们想要的信息,现在我们可以轻易地附加调试内核了。首先你需要使用下列命令启动 gdb.gdb -arch armv7.这一命令告诉 gdb 我们要调试的是 iOS 设备而不是使用 i386 架构的 OS X 应用.当你进行 gdb 提示符后,你需要输入 target remote-kdp,然后输入attach localhost.然后你应该能获得一个已连接上的反馈信息。如果不确定是否正确地设置了启动信息,你可以使用 serialKDPproxy 来验证是否能附加上正确的设备。
你还需要做的一件事就是,如果你有一份符号化后的 kernelcache,你可以把这一参数加入 gdb 的启动参数中去。这样 gdb 就会在你连接上时把这一符号表加入到内核进程当中,这可以使你通过函数名来引用函数而不是地址。
步骤5:基本调试功能
现在你的 gdb 已经具备了它该有的能力。你可以使用命令p (int )address获取某一块内存区域的内容,你也可以使用命令set {int} = val设置内容的值。你可以使用x/i addr或是disassemble命令反汇编函数中一块代码。你也可以使用命令info registers查看所有寄存器的值。可以通过break *(addr)命令设置断点。这些都是 gdb 可以完美地执行的命令。
这些功能非常的强大,在很多场合它都能有助于你的逆向工作。
有时候一分钟的调试可以抵得上一小时的静态二进制代码分析。下一步我会举一个这样的例子。
步骤6:设置断点的例子
假设你正在分析函数 OSUnserializeXMLfor 寻找漏洞,你想要知道当它在某个特定的时候被调用时栈中的情况。你可以在诸如 IDA Pro 这样的程序中查看内核的反汇编代码,以计算出可能的情况。或是你可以只在 IDA 中找到 OSUnserializeXMLfor 函数的地址,然后把它加入到 kernel slide 中,这样它就会在启动时把真实的地址打印到串口的控制台上,然后对这个地址设置一个断点。当函数被调用时,它会暂停下来,你就获取了程序的控制权以决定下一步要做什么。
这就是本教程的全部内容,我希望你能从中获益。
本文章由看雪翻译小组 梦野间 编译
原文链接:http://www.instructables.com/id/IOS-Kernel-Debugging/
[培训]内核驱动高级班,冲击BAT一流互联网大厂工
作,每周日13:00-18:00直播授课