dt nt!_TEB 和 dt ntdll!_TEB 有区别吗?

Is there a difference in dt nt!_TEB and dt ntdll!_TEB?

我可以使用

从任意模块转储类型
dt modulename!type

在某些情况下我看到了例如

dt nt!_TEB

(并且有效)尽管模块被称为 ntdll:

0:001> lm m nt
start             end                 module name
0:001> lm m ntdll
start             end                 module name
00000000`76e00000 00000000`76fa9000   ntdll      (pdb symbols)          d:\...\ntdll.pdb

正如您在上面看到的,ntdll 不能总是被 nt 替换。

dt nt!typedt ntdll!type 有区别吗?还是可以始终以其快捷方式使用?我正在寻找可靠的来源答案,而不仅仅是 "Yes".

我试过了:

如果您有一些想要分享的背景知识,则有额外问题:

nt 是调试器为 $ntsym$ntnsym 设置的自动别名。说明在 WinDbg 帮助 "Using aliases" (online version at MSDN) 中。您可以在需要该别名的任何地方使用它。

假设您有一个脚本可以在内核模式和用户模式下运行。 您可以使用 {nt} 来表示 ntdllntkrnlpantkrnlmpntoskrnlntwowxxxx.

不仅内核模式下的 ntdllntXXXXX 有这个自动别名,因为它们都有功能相同的共同代码。没有其他模块具有像这两个模块这样的公共代码。 例如 ntdll!NtCreateFile 有一个等价的 nt!NtCreateFile 其中前者是一个存根,通过系统调用到达后者的实际实现。

你不能使用 nt 因为它无处不在
尝试在用户模式下自动完成 dt nt!_p 它不会自动完成但是
dt ntdll!_p 将正确完成 evaluate nt 它会出错,无法计算但是
评估 ? ntdll 将得到适当的评估 在 dt 命令中,nt 被特殊解析,并具有为字符串分配适当的模块值的功能,因此它可以在 dt 中按原样使用

解析nt的函数的伪代码是这样的

switch(GetToken(wcschr(inputstr ,"!")) == "nt" )
case usermode nt = "ntdll";
case kmode    nt = "Nt" using machineinfo.NtModule (ntos .......)
case wow      nt = "Nt32" using getnt32module()

如果您好奇反汇编 dbgeng 并搜索其中包含字符串 typedump 的函数,即 x dbgeng!*typedump* 其中一个函数有一个解析字符串 nt 并为其赋值的子调用

nt 和ntdll 是完全不同的模块。 nt 是一个内核模式模块,包含执行子系统和 Windows 内核(我们通常简称为 "the Kernel")。 ntdll 是一个用户模式 ​​DLL,它提供一些用户模式 ​​API 用于与内核交互。

dt 命令显示给定模块的类型。在这种情况下,两个模块恰好包含相同的数据类型。就好像你和我都编写了使用相同数据结构的驱动程序,你可以从任一模块转储它并获得相同的结果。

至于为什么它们不能完全互换,如果您正在调试内核模式目标(实时或转储),则只能使用 "dt nt!" 形式。

正如其他人所指出的,"nt" 的特殊之处在于它是内核真实名称的别名。根据处理器架构和特性,此模块有不同的名称,因此别名使我们可以在不知道确切名称的情况下引用该模块。唯一适用于此的其他模块是硬件抽象层 (HAL),它有各种名称,但可以在调试器中简单地引用 "hal"。