4

I can dump types from an arbitrary module using

dt modulename!type

In some cases I saw e.g.

dt nt!_TEB

(and it works) although the module is called 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

As you can see above, ntdll cannot always be replaced by nt.

Is there a difference in dt nt!type versus dt ntdll!type or can it always be used in its shortcut form? I'm looking for a credible answer with sources, not just "Yes".

I have tried:

  • reading WinDbg help .hh dt

Bonus questions if you have some background knowledge you'd like to share:

  • are there other commands where nt can be used instead of ntdll or is this dt-specific?
  • are there other modules which have a shortcut form?
  • where does this come from (e.g. is there some historical background for this behavior)?
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222

2 Answers2

6

nt is an automatic alias set by debugger lookup for $ntsym or $ntnsym. Explanation is in WinDbg help "Using aliases" (online version at MSDN). You can use it wherever you would require that alias.

Suppose you have a script that works in both kernelmode as well as usermode. You can use {nt} to denote either of ntdll, ntkrnlpa, ntkrnlmp, ntoskrnl or ntwowxxxx.

Not only ntdll and ntXXXXX in kernel mode has this automatic alias as both have functionally equivalent code in common. No other module has common code like these two modules. For example ntdll!NtCreateFile has an equivalent nt!NtCreateFile where the former is a stub that reaches the real implementation in the latter via syscall.

You can't use nt as is everywhere. For example, autocompleting dt nt!_p in usermode won't autocomplete, but dt ntdll!_p will autocomplete properly. evaluate nt it will err with cannot evaluate but evaluating ? ntdll will work.

nt is parsed specially in dt command and has a function to assign a proper module value to the string so it can be used in dt as is.

pseudo code for the function that parses nt is something like this:

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

If you are curious disassemble dbgeng and search around the functions that has the string typedump in it that is x dbgeng!*typedump* one of that functions has a subcall that parses the string nt and assigns it a value.

mechgt
  • 41
  • 1
  • 9
blabb
  • 8,674
  • 1
  • 18
  • 27
  • Thanks. This explains why I can also use `dt $ntsym!_TEB`, but not really why I can use `nt` (especially without $ or ${}) – Thomas Weller Apr 09 '15 at 21:51
  • no you cant use nt as it is everywhere it is parsed and assigned a proper value inside typedump function try ? nt in usermode it wont evaluate take a look at exapnded edit in reply – blabb Apr 10 '15 at 07:42
1

nt and ntdll are entirely different modules. nt is a kernel mode module that contains both the Executive Subsystems and the Windows Kernel (we usually call this image simply "the Kernel"). ntdll is a user mode DLL that provides some user mode APIs for interfacing with the Kernel.

The dt command displays a type from a given module. In this case, both modules happen to contain the same data type. It's as if you and I both wrote drivers that used the same data structure, you could dump it from either module and get the same result.

As for why they're not entirely interchangeable, you can only use the "dt nt!" form if you're debugging a kernel mode target (live or dump).

And as others have pointed out, "nt" is special in that it's an alias for the real name of the Kernel. There are different names for this module based on processor architecture and features, so the alias lets us refer to the module without knowing the exact name. The only other module this applies to is the Hardware Abstraction Layer (the HAL), which has various names but can be referred to in the debugger with simply "hal".

snoone
  • 5,409
  • 18
  • 19
  • "you can only use the "dt nt!" form if you're debugging a kernel mode target" - that's not true. It works fine in user mode live debugging as well, using WinDbg 6.2.9200 (both amd64 and x86). – Thomas Weller Apr 09 '15 at 19:50
  • "nt is a kernel mode module" - I can neither find a `nt.dll` nor a `nt.exe` on my system. There are `ntkrnlpa.exe` and `ntoskrnl.exe`, so IMHO this sentence is not precise. Later you say "it's an alias for the real name of the Kernel", which is more likely. – Thomas Weller Apr 09 '15 at 20:02