以下主要来自Windows背景,但我想它也应该适用于Linux。这些概念并没有太大的不同。
首先是一些内联答案
据我了解,从高层次上讲,用户模式调试为您提供了对进程私有虚拟地址的访问。
正确的。
调试会话仅限于该进程
不可以。您可以同时附加到多个进程,例如使用 WinDbg 的.tlist
/.attach
命令。
并且它不能覆盖或篡改其他进程的虚拟地址空间/数据。
不可以。您可以修改内存,例如使用 WinDbg 的ed
命令。
据我了解,内核模式调试提供对需要完全访问多个资源的其他驱动程序和内核进程的访问,
正确的。
除了原始进程地址空间。
据我所知,您只能访问物理 RAM。一些虚拟地址空间可能会被交换,因此没有完整的地址空间可用。
由此,我开始认为内核模式调试似乎比用户模式调试更健壮。
我认为相反。如果您在内核模式的某处写入不正确的值,PC 会崩溃并出现蓝屏。如果您在用户模式下执行此操作,则只有应用程序崩溃。
这给我提出了一个问题:当调试模式的两个选项都可用时,是否有必要选择用户模式而不是更健壮的内核模式?
如果您只调试应用程序而不涉及驱动程序,我更喜欢用户模式调试。
恕我直言,内核模式调试不是更健壮,而是更脆弱——你真的可以在最低级别破坏一切。用户模式调试提供了针对操作系统崩溃的典型保护。
我只是似乎注意到很多人似乎试图避免内核调试
我观察相同。通常,一旦他们尝试过,这并不难。在我的调试研讨会中,我从内核的角度解释进程和线程,并在内核中进行。一旦人们尝试内核调试,它就不再是一个谜了。
我不完全确定为什么,因为它看起来更健壮。
好吧,你真的可以在内核模式下炸毁一切。
用户模式调试
用户模式调试是任何 IDE 的默认设置。集成通常很好,在某些 IDE 中感觉非常原生。
在用户模式调试期间,事情很简单。如果您访问已调出到磁盘的内存,则操作系统仍在运行,并且只会将其调入页面,因此您可以对其进行读写。
您可以访问从应用程序开发中了解的所有内容。有线程,您可以暂停或恢复它们。您从应用程序开发中获得的知识足以操作调试器。
您可以设置断点并检查变量(只要您有正确的符号)。
某些类型的调试仅在用户模式下可用。例如,用于调试 .NET 应用程序的 WinDbg 的 SOS 扩展仅在用户模式下工作。
内核调试
内核调试相当复杂。通常,你不能简单地进行本地内核调试——如果你在内核的某个地方停止,你如何控制调试器?系统只会冻结。因此,对于内核调试,您需要 2 台 PC(或虚拟 PC)。
在内核模式调试期间,事情很复杂。当您只是在应用程序中时,一毫秒后,会发生一些中断并执行完全不同的操作。您不仅有线程,还需要处理应用程序外部的调用堆栈,您会看到 CPU 寄存器内容、指令指针等。这些都是“普通”应用程序开发人员不想关心的东西。
您不仅可以访问您实施的所有内容。您还可以访问 Microsoft、Intel、NVidia 和许多其他公司开发的所有内容。
您不能简单地访问所有内存,因为一些被调出到交换文件的内存首先会产生页面错误,然后涉及一些磁盘驱动程序来获取数据,可能会调出一些其他数据,等等。
内核模式中有很多 giong ,为了不破坏它,您需要对所有这些主题有真正的专业理解。
结论
大多数开发人员只想关心他们的源代码。因此,如果他们正在编写程序(又名应用程序、脚本、工具、游戏),他们只需要用户模式调试。如果“他们的代码”是驱动程序代码,他们当然想要内核调试。
当然,安全专家和破解者想要内核模式调试,因为他们想要特权。