欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

一款实用的macOS内核调试工具——LLDBagility

来源:本站整理 作者:佚名 时间:2019-11-22 TAG: 我要投稿

这是Francesco Cagnin有关macOS内核调试的第二篇文章。在上一篇文章中,作者定义了本篇文章中使用的大多数术语,描述了如何为macOS内核实施内核调试,并讨论了可用工具的局限性。本篇文章中,我们就介绍LLDBagility,这是上文中为macOS内核实施内核调试的解决方案,可提供更轻松,更实用的macOS调试体验。
在当前情况下,调试macOS内核(XNU)不太实用,尤其是考虑到诸如必须安装调试内核构建以及无法设置监测点或暂停执行的内核调试器的不便之处。为了改善这种情况,作者开发了LLDBagility ,这是一种借助快速调试协议(FDP,在本文后面进行介绍)调试macOS虚拟机的工具。最重要的是,LLDBagility实现了一组新的LLDB命令,这些命令允许调试器执行以下操作:
1.连接到运行中的macOS VirtualBox虚拟机并秘密地调试其内核,而无需更改客户操作系统(例如,无需开发或调试内核, boot-args修改或禁用SIP),并且只需对虚拟机的配置进行最小的更改;
2.随时中断(然后恢复)客户内核的执行;
3.即使在启动过程开始时,也可以在内核代码中的任何位置设置硬件断点;
4.设置在指定存储位置的读取或写入访问时触发的硬件观察点;
5.保存并在几秒钟内恢复虚拟机的状态。
这些命令旨在与LLDB中已经可用的命令一起使用,例如内存/寄存器读/写、断点(软件),步骤等。此外,如果调试后的内核附带了其内核调试工具包(甚至可能没有,后面会讨论),那么绝大多数lldbmacros都可以正常工作。
下面,我们首先简要介绍什么是FDP,以及它如何增强VirtualBox来实现虚拟机自省。然后,我们研究LLDBagility如何利用这些新功能透明地将LLDB连接到macOS虚拟机,并演示一个简单的内核调试会话。最后,我们提出了一些在缺乏调试工具包的内核构建中使用现有lldbmacros的想法。
通过快速调试协议对虚拟机进行自省
快速调试协议是一个轻量级、快速和高效的调试API,用于虚拟机的自省性检查,使用C语言编写,目前仅作为VirtualBox源代码[FDP]的补丁发布。该API的作用如下:
1.读取和写入虚拟机寄存器和内存;
2.设置和取消设置硬件/软件断点和观察点;
3.暂停、恢复和单步执行虚拟机;
4.保存并恢复虚拟机状态;
FDP的隐身性来自对虚拟机扩展页面表的操作(从客户系统中很难检测到的操作),而速度是FDP和虚拟机之间使用共享内存的结果(在某些情况下达到一百万每秒的内存读取次数)。
除了底层C接口之外,该API还提供了Python绑定(PyFDP),可用于概念的快速证明和LLDBagility等大型项目。下面是一个示例脚本,下面的脚本在每次系统调用时都会中断:
#!/usr/bin/env python2
from PyFDP.FDP import FDP
# Open the debuggee VM by its name
fdp = FDP("18E226")
# Pause the VM to install a breakpoint
fdp.Pause()
# Install a hardware breakpoint (very fast and stealth)
UnixSyscall64 = 0xffffff80115bae84
fdp.dr0 = UnixSyscall64
fdp.dr7 = 0x403
# Resume the execution after the breakpoint installation
fdp.Resume()
while True:
    # Wait for a breakpoint hit
    fdp.WaitForStateChanged()
    print "%x" % (fdp.rax)
    # Jump over the breakpoint
    fdp.SingleStep()
    # Resume the debuggee
    fdp.Resume()
更多关于FDP的细节可以在Winbagility [WinbagilitySSTIC2016]的原始文章中找到,这是LLDBagility在Windows和WinDbg上的老版本。
将LLDB附加到虚拟机
如前一篇文章中详细介绍的那样,在常规的两台设备调试期间,LLDB通过向其内部KDP存根发送命令来与被调试对象的macOS内核进行交互,该存根本身是内核的一部分,然后可以检查和更改根据要求确定设备的状态,并传达结果。 LLDBagility背后的关键思想是使用虚拟机管理程序级别的FDP提供的(虚拟)设备自省和修改的类似功能来复制此类代理提供的功能,以便可以用内核外部的等效替代项替换内核的调试存根来调试设备。此外,通过保持与KDP协议的兼容性,这个新的存根可以利用LLDB对macOS内核的现有支持,而无需在任何方面修改调试器,因为与内核中的KDP服务器通信没有区别。在这方面,Ian Beer为他的iOS内核调试器使用了类似的解决方案。
这种方法具有两个显着的优点:消除了在内核中启用KDP进行调试的必要性,以及使用其他功能扩展LLDBagility的存根的可能性,这意味着在第一篇文章中描述的经典调试方法的所有局限性都可以解决。首先,由于不再需要设置XNU进行调试,因此无需修改NVRAM并可能禁用SIP。同样,也无需安装DEBUG或DEVELOPMENT版本。其次,与KDP代码有关的所有系统范围的副作用都消失了,这意味着,例如,rootkit对调试器的检测更加困难。第三,现在可以在内核引导过程中在KDP存根初始化之前开始调试。最后,借助FDP对设备进行完全控制,可以轻松实现硬件断点,观察点以及用于在调试器的命令下暂停内核的机制。
LLDBagility工具的详细概述
如上所述,LLDBagility的前端是一组新的LLDB命令,这些命令在lldbagility.py中实现(来自[LLDBagility100]):
1.fdp-attach或简称为fa,用于将调试器连接到正在运行的macOS VirtualBox虚拟机;
2.fdp-hbreakpoint或fh,用于设置和取消设置读/写/执行硬件断点;
3.fdp-interrupt或fi,以暂停虚拟机的执行并将控制权返回给调试器(相当于已知的sudo dtrace -w -n"BEGIN { breakpoint(); }");
4.fdp-save或fs,保存虚拟机当前状态;
5.fdp-restore或fr,将虚拟机还原到上一次保存的状态。
另一方面,后端由以下部分组成:
1.kdpserver.py,LLDB连接到的新KDP服务器(XNU的替代品),其工作是将调试器收到的KDP请求转换为虚拟机的命令并发送回响应和异常通知(例如断点命中);
2. stubvm.py,用于抽象常见的虚拟机操作并通过FDP实现。

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载