microsoft / DbgShell

A PowerShell front-end for the Windows debugger engine.
MIT License
675 stars 89 forks source link

WoW64 Fixes & TEB Retrieval #61

Closed Zhentar closed 5 years ago

Zhentar commented 5 years ago

A bunch of fixes & enhancements for WoW64, primarily focused around making sure the right ntdll module is used for resolving types.

$teb and $peb use the DbgEng provided module for symbol lookup, which does seem to be accurate from my testing.

For most everything else, we need to determine which ntdll module has which bitness. DbgEng knows which is which but of course does not simply expose it in a straightforward way. I ended up settling on GetSymbolModuleWide( "${$ntnsym}!" (and $ntwsym) to coax it out; it gives us the right answer in a single DbgEng call without having to parse anything and doesn't rely on any undocumented behavior (I think). Conveniently, it also matches the semantics that I think make the most sense ($ntnsym always returns a value; 64-bit when there is one and 32-bit otherwise, while $ntwsym always returns the 32-bit module when there is one and fails otherwise).

Since I needed a way to test those lookups, I added handling for DbgEng's nt! module shortcut, and invented a matching nt32! module shortcut.

I also threw in a MemoryMarshal.Read<> inspired ReadMemAs<> for easy & efficient reading of a single value (except implemented in the C++/CLI layer so that I never have to say I'm being unsafe).

jazzdelightsme commented 5 years ago

Thank you for contributing! I will take a look this week. #Closed

Zhentar commented 5 years ago

No rush - I've hit the magical customer dump of edge cases that breaks everything it touches, probably better to give it a couple more days to see if any more of those things are in DbgShell 😆 #Closed

jazzdelightsme commented 5 years ago

I'm curious: why are you interested in detecting wow64 targets? #Closed

Zhentar commented 5 years ago

It's not so much that I want to detect Wow64 targets as it is that DbgEng forces me to detect Wow64 targets to get correct behaviors; regardless of the current effective machine type it only gives you the native PEB & TEB... so to get to the PEB&TEB associated with most of the code that does anything, you have to know that it's a Wow64 process, and then from there you have to pick from a set of undocumented pointer shenanigans a way to get to the 32 bit TEB.

It's possible there's some function somewhere in DbgEng that will just give you the 32 bit TEB/PEB, but nothing I found would do it. #Closed

Zhentar commented 5 years ago

After mulling things over a bit, I realized that getting the effective architecture TEB is good enough for me, in which case comparing the effective architecture against the "actual" architecture works just fine.

Then the only thing we would need to know whether it's Wow64 or not for is to know whether or not getting the TEB address is a valid action (since you can switch the effective processor type to I386 even if it's a pure 64-bit process)... but that's enough of a strange edge case that I'm inclined to let it slide (particularly considering getting the TEB symbol will still throw) #Closed

Zhentar commented 5 years ago

There, think that's all of them :) #Closed