Open extperl opened 1 year ago
The issue with "!pte" command has been described here: https://medium.com/@jellykuo1234/pte-levels-not-implemented-for-this-platform-ed230ab8db93
In short, kdexts.dll reads nt!MiState.Vs.PagingLevels
. Instead of expected value 3/4/5, it receives value 0xFF.
And that happens because definition of nt!_MI_SYSTEM_INFORMATION
structure in public symbols is incorrect (it's the type of the nt!MiState
global variable). Here's original discovery post: https://twitter.com/33y0re/status/1769462827683615211
Additionally, here's post with temporary hack which works by overwriting some kernel data for the sake of the "!pte" command (the overwrite happen to be quite benign): https://twitter.com/sixtyvividtails/status/1762096415990272199
To fix the issue, 2 things should be done:
Pull public pdbs with incorrect _MI_SYSTEM_INFORMATION
definitions, push correct pdbs.
That'll not only ensure "!pte" command correctness, but also help driver writers and crashdump wizards to properly diagnose other issues related to memory subsystem.
Adjust kdexts.dll extension. It should use nt!MiState
as fallback path, but primary info retrieval should go via nt!MiVisibleState
pointer (when it's available). It points to nt!MiState.Vs
field, so even if _MI_SYSTEM_INFORMATION
definition is incorrect in public symbols, using nt!MiVisibleState
pointer will retrieve correct address of _MI_VISIBLE_STATE
.
Even though it might seem that any of the 2 steps above is enough, I believe both steps should be taken to ensure the most robust fix for this and realted issues, while at the same time ensuring the best experience for users who have pdbs with incorrect definitions already downloaded and cached.
forgot the source but for others looking for a quick and easy fix, these commands will do:
ed nt!MiState+0x4440+0xd4 0x4 .unload kdexts .load kdexts
That's just variant of the hack from the twitter link provided above, but with hardcoded offsets. Let's copypaste full hack for convenience then:
r$t0=4; .catch {.if (by(nt!MmPteBase+6) != ff) {r$t0=5}};
? @@(((nt!_MI_SYSTEM_INFORMATION*)@@(nt!MiState))->Vs.PagingLevels = @$t0);
.unload kdexts; .load kdexts
This full variant is a bit more correct because it overwrites just a single byte of some unrelated structure and not four of them, and also takes into account possibility of LA57.
However, neither hack variant is good enough. Both might kill the target system because they just plaster kdexts-expected value over some other data. That other data can be sort of important for target system - it just happens it's not that important on many systems. We need real fix from Microsoft for WinDbg kdexts, and for incorrect symbols.
The incorrect type information for _MI_SYSTEM_INFORMATION
has been fixed for future builds of Windows. That fix has been available since last fall, so I'd expect insiders builds are seeing the correct type information.
Version 1.2402.24001.0 of WinDbg has a small mitigation that might be good enough for most uses of !pte
- if kdexts
reads an invalid value for Vs.PagingLevels
, it will assume it should it was 4.
The suggestion to try nt!MiVisibleState
seems worthwhile, we'll consider that change.
@lzybkr
That's great news!
Could you please clarify - does it mean only new-new builds (such as insider) shall receive proper pdbs with fixed _MI_SYSTEM_INFORMATION
, or would that also apply to new-current OS (such as security update for win10 22H2 ntoskrnl.exe to be published 2024-05-14)?
@extperl please provide some details when reporting issues. Without more information, it's virtually impossible to do anything about it.
I've started monitoring this feedback channel, and I noticed this after someone (not sure it's you) mentioned a similar thing on twitter: https://twitter.com/0xNemi/status/1648421678635167745
FWIW, my replay there was...
HTH