DbgEng 扩展 DLL 剖析

DbgEng 扩展 DLL 导出多个回调函数,其中一些函数可能是扩展命令的实现。

这些扩展 DLL 由 调试器引擎 加载,可以在 Microsoft Windows 上执行用户模式或内核模式调试时提供额外的功能或自动化任务。

如果执行了 Windows 调试工具的完整安装,可以在安装目录的 sdk\samples\exts 子目录中找到名为“exts”的示例 DbgEng 扩展。

扩展命令

扩展 DLL 可以导出用于执行扩展命令的任意数量的函数。 每个函数在 .def 文件中显式声明为导出,其名称必须完全由小写字母组成。

用于实现扩展命令的函数必须与原型 PDEBUG_EXTENSION_CALL匹配。

这些函数根据标准C++约定进行命名,但不允许使用大写字母。 导出的函数名称和扩展命令名称相同,但扩展命令以感叹号 (!) 开头。 例如,将 myextension.dll 加载到调试器中,然后在调试器命令窗口中键入 !stack 时,调试器将在 myextension.dll中查找名为 堆栈 的导出函数。

如果 myextension.dll 尚未加载,或者如果其他扩展 DLL 中可能有同名的其他扩展命令,则可以在调试器命令窗口中键入 !myextension.stack ,以指示该 DLL 中的扩展 DLL 和扩展命令。

其他导出的函数

DbgEng 扩展 DLL 必须导出 DebugExtensionInitialize。 加载 DLL 时会调用此调用,以初始化 DLL。 DLL 可以使用它初始化全局变量。

扩展 DLL 可以导出 DebugExtensionUninitialize。 如果导出此代码,则在卸载扩展 DLL 之前将调用它。 DLL 可以使用它进行清理,然后再将其卸载。

扩展 DLL 可以导出 DebugExtensionNotify。 如果导出此项,则会在会话开始或结束以及目标启动或停止执行时调用它。 这些通知也发送到向客户端注册的IDebugEventCallbacks对象。

扩展 DLL 可以导出 KnownStructOutput。 如果导出此内容,将在加载 DLL 时调用它。 此函数返回一个结构列表,这些结构可以由 DLL 以单行格式打印。 稍后可以调用它来设置这些结构的实例的格式以供打印。

用于加载 DbgEng 扩展 DLL 的引擎过程

加载扩展 DLL 时,按以下顺序由引擎调用回调函数:

  1. DebugExtensionInitialize 被调用,以便扩展 DLL 可以初始化。

  2. 如果导出,则如果引擎具有活动会话,则调用 DebugExtensionNotify ,并在会话挂起且可访问时再次调用。

  3. 如果导出,则调用 KnownStructOutput 请求 DLL 返回其能够单行打印的结构列表。

有关如何使用调试器加载和卸载扩展 DLL 的信息,请参阅 加载调试器扩展 DLL ,并参阅 使用调试器扩展命令 了解有关执行扩展命令的信息。

调试器引擎将在调用扩展 DLL 时放置 try/except block。 这会保护引擎免受扩展代码中某些类型的 bug;但是,由于扩展调用在引擎所在的同一线程中执行,因此它们仍可能导致它崩溃。