gpt4 book ai didi

debugging - WinDbg 不显示寄存器值

转载 作者:行者123 更新时间:2023-12-04 05:37:09 26 4
gpt4 key购买 nike

基本上,这与 here 提出的问题相同。 .

对运行 Windows 7 或更早版本(使用 WinDbg 6.2 及更高版本)的计算机执行内核调试时,调试器不会在寄存器窗口中显示任何内容。按Customize...按钮会生成一个消息框,内容为 Registers are not yet known .

同时发出r命令会打印出完全有效的寄存器值。

这种行为的原因是什么,可以修复吗?

最佳答案

TL;DR : 我写了一个扩展 DLL 来修复这个错误。可用 here .

问题

要理解这个问题,我们首先需要了解WinDbg 基本上只是微软Windows Symbolic Debugger Engine 的一个前端,在dbgeng.dll 内部实现。 .其他前端包括命令行 kd.exe (内核调试器)和cdb.exe (用户模式调试器)。

引擎实现了我们对调试器的期望:处理符号文件、读写内存和寄存器、设置断点等。然后引擎通过类似 COM 的接口(interface)公开所有这些功能(它们实现 IUnknown 但不是注册组件) .例如,这允许我们编写自己的调试器(如 this person 所做的)。

有了这些知识,我们现在可以对 WinDbg 如何获取目标机器上的寄存器值进行有根据的猜测。

引擎暴露了 IDebugRegisters 操作寄存器的接口(interface)。此接口(interface)声明 GetValues 一次检索多个寄存器的值的方法。但是 WinDbg 怎么知道有多少个寄存器呢?这就是为什么我们有 GetNumberRegisters 方法。

因此,要检索目标上所有寄存器的值,我们必须执行以下操作:

  • 调用 IDebugRegisters::GetNumberRegisters得到寄存器的总数。
  • 调用 IDebugRegisters::GetValuesCount参数设置为寄存器总数,Indices参数设置为 NULL ,以及 Start参数设置为 0 .

  • 不过,有一个小问题:第二次调用失败并返回 E_INVALIDARG。 .

    嗯,对不起?怎么会失败?尤其令人费解的是这个返回值的文档:

    The value of the index of one of the registers is greater than the number of registers on the target machine.



    但是我只是问你有多少个寄存器,那么这个值怎么会超出范围呢?好吧,不管怎样,让我们​​继续阅读文档,也许有些事情会变得清晰:

    If the return value is not S_OK, some of the registers still might have been read. If the target was not accessible, the return type is E_UNEXPECTED and Values is unchanged; otherwise, Values will contain partial results and the registers that could not be read will have type DEBUG_VALUE_INVALID.



    (强调我的。)

    啊哈!所以也许引擎只是无法读取其中一个寄存器!但是哪一个?原来,引擎在 xcr0 上阻塞。登记。来自 Intel 64 和 IA-32 架构软件开发人员手册 :

    Extended control register XCR0 contains a state-component bitmap that specifies the user state components that software has enabled the XSAVE feature set to manage. If the bit corresponding to a state component is clear in XCR0, instructions in the XSAVE feature set will not operate on that state component, regardless of the value of the instruction mask.



    好的,所以寄存器控制 XSAVE的操作指令,它保存了 CPU 的扩展功能(如 XMM 和 AVX)的状态。根据 this 的最后一条评论页面,此指令需要操作系统的一些支持。尽管评论指出 Windows 7(我正在测试的 VM 正在运行)确实支持此指令,但似乎手头的问题无论如何都与操作系统有关,因为当目标是 Windows 8 时,一切正常。

    确实,尚不清楚该错误是否在调试器引擎中,它报告的寄存器数量超过了它可以检索的值,或者在 WinDbg 中,如果引擎无法生成所有值,它根本拒绝显示任何值。

    解决方案

    当然,我们可以咬紧牙关,只使用旧版本的 WinDbg 来调试旧的 Windows 版本。但这其中的挑战在哪里?

    相反,我给你一个 debugger extension解决了这个问题。它通过 Hook (在 this library 的帮助下)相关的调试器引擎方法并返回 S_OK 来实现。如果唯一失败的寄存器是 xcr0 .否则,它会传播失败。该扩展支持运行时卸载,因此如果您遇到问题,您可以随时禁用 Hook 。

    就是这样,玩得开心!

    关于debugging - WinDbg 不显示寄存器值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35961246/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com