debugging kernel driver and understanding i/o routing with various structures
Let’s debug a very simple driver from pavel’s latest book on kernel programming and understand different structures along with their relationship and overall...
Quite often on windows accessing native api and undoc structures is required.
The repo contains needed headers to be included to access structure and api. The projet is updated frequently and very actively maintained over the years. process hacker’s phnt
There is another neat utility pdbex to get such undoc strucutres from
publicly available pdb similar to phnt.
Just to get an idea let’s have a look at the difference between the one microsoft provides and phnt.
As one can notice most of the fields and structures are either marked as reserved/hidden in winternl.
typedef struct _PEB {
  BYTE                          Reserved1[2];
  BYTE                          BeingDebugged;
  BYTE                          Reserved2[1];
  PVOID                         Reserved3[2];
  PPEB_LDR_DATA                 Ldr;
  PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
  PVOID                         Reserved4[3];
  PVOID                         AtlThunkSListPtr;
  PVOID                         Reserved5;
  ULONG                         Reserved6;
  PVOID                         Reserved7;
  ULONG                         Reserved8;
  ULONG                         AtlThunkSListPtr32;
  PVOID                         Reserved9[45];
  BYTE                          Reserved10[96];
  PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
  BYTE                          Reserved11[128];
  PVOID                         Reserved12[1];
  ULONG                         SessionId;
} PEB, *PPEB;
And here is the same structure definition for PEB from phnt.
typedef struct _PEB
{
    BOOLEAN InheritedAddressSpace;
    BOOLEAN ReadImageFileExecOptions;
    BOOLEAN BeingDebugged;
    union
    {
        BOOLEAN BitField;
        struct
        {
            BOOLEAN ImageUsesLargePages : 1;
            BOOLEAN IsProtectedProcess : 1;
            BOOLEAN IsImageDynamicallyRelocated : 1;
            BOOLEAN SkipPatchingUser32Forwarders : 1;
            BOOLEAN IsPackagedProcess : 1;
            BOOLEAN IsAppContainer : 1;
            BOOLEAN IsProtectedProcessLight : 1;
            BOOLEAN IsLongPathAwareProcess : 1;
        };
    };
    HANDLE Mutant;
    PVOID ImageBaseAddress;
    PPEB_LDR_DATA Ldr;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    PVOID SubSystemData;
    PVOID ProcessHeap;
    PRTL_CRITICAL_SECTION FastPebLock;
    PSLIST_HEADER AtlThunkSListPtr;
    PVOID IFEOKey;
    union
    {
        ULONG CrossProcessFlags;
        struct
        {
            ULONG ProcessInJob : 1;
            ULONG ProcessInitializing : 1;
            ULONG ProcessUsingVEH : 1;
            ULONG ProcessUsingVCH : 1;
            ULONG ProcessUsingFTH : 1;
            ULONG ProcessPreviouslyThrottled : 1;
            ULONG ProcessCurrentlyThrottled : 1;
            ULONG ProcessImagesHotPatched : 1; // REDSTONE5
            ULONG ReservedBits0 : 24;
        };
    };
    union
    {
        PVOID KernelCallbackTable;
        PVOID UserSharedInfoPtr;
    };
    ULONG SystemReserved;
    ULONG AtlThunkSListPtr32;
    PAPI_SET_NAMESPACE ApiSetMap;
    ULONG TlsExpansionCounter;
    PVOID TlsBitmap;
    ULONG TlsBitmapBits[2];
    PVOID ReadOnlySharedMemoryBase;
    PVOID SharedData; // HotpatchInformation
    PVOID *ReadOnlyStaticServerData;
    PVOID AnsiCodePageData; // PCPTABLEINFO
    PVOID OemCodePageData; // PCPTABLEINFO
    PVOID UnicodeCaseTableData; // PNLSTABLEINFO
    ULONG NumberOfProcessors;
    ULONG NtGlobalFlag;
    ULARGE_INTEGER CriticalSectionTimeout;
    SIZE_T HeapSegmentReserve;
    SIZE_T HeapSegmentCommit;
    SIZE_T HeapDeCommitTotalFreeThreshold;
    SIZE_T HeapDeCommitFreeBlockThreshold;
    ULONG NumberOfHeaps;
    ULONG MaximumNumberOfHeaps;
    PVOID *ProcessHeaps; // PHEAP
    PVOID GdiSharedHandleTable;
    PVOID ProcessStarterHelper;
    ULONG GdiDCAttributeList;
    PRTL_CRITICAL_SECTION LoaderLock;
    ULONG OSMajorVersion;
    ULONG OSMinorVersion;
    USHORT OSBuildNumber;
    USHORT OSCSDVersion;
    ULONG OSPlatformId;
    ULONG ImageSubsystem;
    ULONG ImageSubsystemMajorVersion;
    ULONG ImageSubsystemMinorVersion;
    ULONG_PTR ActiveProcessAffinityMask;
    GDI_HANDLE_BUFFER GdiHandleBuffer;
    PVOID PostProcessInitRoutine;
    PVOID TlsExpansionBitmap;
    ULONG TlsExpansionBitmapBits[32];
    ULONG SessionId;
    ULARGE_INTEGER AppCompatFlags;
    ULARGE_INTEGER AppCompatFlagsUser;
    PVOID pShimData;
    PVOID AppCompatInfo; // APPCOMPAT_EXE_DATA
    UNICODE_STRING CSDVersion;
    PVOID ActivationContextData; // ACTIVATION_CONTEXT_DATA
    PVOID ProcessAssemblyStorageMap; // ASSEMBLY_STORAGE_MAP
    PVOID SystemDefaultActivationContextData; // ACTIVATION_CONTEXT_DATA
    PVOID SystemAssemblyStorageMap; // ASSEMBLY_STORAGE_MAP
    SIZE_T MinimumStackCommit;
    PVOID SparePointers[4]; // 19H1 (previously FlsCallback to FlsHighIndex)
    ULONG SpareUlongs[5]; // 19H1
    //PVOID* FlsCallback;
    //LIST_ENTRY FlsListHead;
    //PVOID FlsBitmap;
    //ULONG FlsBitmapBits[FLS_MAXIMUM_AVAILABLE / (sizeof(ULONG) * 8)];
    //ULONG FlsHighIndex;
    PVOID WerRegistrationData;
    PVOID WerShipAssertPtr;
    PVOID pUnused; // pContextData
    PVOID pImageHeaderHash;
    union
    {
        ULONG TracingFlags;
        struct
        {
            ULONG HeapTracingEnabled : 1;
            ULONG CritSecTracingEnabled : 1;
            ULONG LibLoaderTracingEnabled : 1;
            ULONG SpareTracingBits : 29;
        };
    };
    ULONGLONG CsrServerReadOnlySharedMemoryBase;
    PRTL_CRITICAL_SECTION TppWorkerpListLock;
    LIST_ENTRY TppWorkerpList;
    PVOID WaitOnAddressHashTable[128];
    PVOID TelemetryCoverageHeader; // REDSTONE3
    ULONG CloudFileFlags;
    ULONG CloudFileDiagFlags; // REDSTONE4
    CHAR PlaceholderCompatibilityMode;
    CHAR PlaceholderCompatibilityModeReserved[7];
    struct _LEAP_SECOND_DATA *LeapSecondData; // REDSTONE5
    union
    {
        ULONG LeapSecondFlags;
        struct
        {
            ULONG SixtySecondEnabled : 1;
            ULONG Reserved : 31;
        };
    };
    ULONG NtGlobalFlag2;
} PEB, *PPEB;
git clone --recurse-submodules https://github.com/manurautela/phnt-sample
cd phnt-demo
open phnt-demo.sln with vs2019
build

0:000> !teb
TEB at 00925000
    ExceptionList:        005ff85c
    StackBase:            00600000
    StackLimit:           005fd000
    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 00925000
    EnvironmentPointer:   00000000
    ClientId:             00004224 . 00001bb8
    RpcHandle:            00000000
    Tls Storage:          0092502c
    PEB Address:          00922000
    LastErrorValue:       0
    LastStatusValue:      c00700bb
    Count Owned Locks:    0
    HardErrorMode:        0
0:000> dd fs:[0x18] l1
0053:00000018  00925000
0:000> dd fs:[0x30] l1
0053:00000030  00922000
0:000> dv /v /t
005ff338          unsigned long dwTeb = 0x925000
005ff344          unsigned long dwPeb = 0x922000
005ff368          struct _PEB _peb = struct _PEB
005ff35c          unsigned long peb_x86 = 0x922000
005ff350          unsigned long teb_x86 = 0x925000
0:000> dx -r1 (*((phnt_demo!_PEB *)0x5ff368))
(*((phnt_demo!_PEB *)0x5ff368))                 [Type: _PEB]
    [+0x000] InheritedAddressSpace : 0x0 [Type: unsigned char]
    [+0x001] ReadImageFileExecOptions : 0x0 [Type: unsigned char]
    [+0x002] BeingDebugged    : 0x1 [Type: unsigned char]
    [+0x003] BitField         : 0x4 [Type: unsigned char]
    [+0x003 ( 0: 0)] ImageUsesLargePages : 0x0 [Type: unsigned char]
    [+0x003 ( 1: 1)] IsProtectedProcess : 0x0 [Type: unsigned char]
    [+0x003 ( 2: 2)] IsImageDynamicallyRelocated : 0x1 [Type: unsigned char]
    [+0x003 ( 3: 3)] SkipPatchingUser32Forwarders : 0x0 [Type: unsigned char]
    [+0x003 ( 4: 4)] IsPackagedProcess : 0x0 [Type: unsigned char]
    [+0x003 ( 5: 5)] IsAppContainer   : 0x0 [Type: unsigned char]
    [+0x003 ( 6: 6)] IsProtectedProcessLight : 0x0 [Type: unsigned char]
    [+0x003 ( 7: 7)] IsLongPathAwareProcess : 0x0 [Type: unsigned char]
    [+0x004] Mutant           : 0xffffffff [Type: void *]
    [+0x008] ImageBaseAddress : 0x6d0000 [Type: void *]
    [+0x00c] Ldr              : 0x77245d80 [Type: _PEB_LDR_DATA *]
    [+0x010] ProcessParameters : 0xa92928 [Type: _RTL_USER_PROCESS_PARAMETERS *]
    [+0x014] SubSystemData    : 0x0 [Type: void *]
    [+0x018] ProcessHeap      : 0xa90000 [Type: void *]
    [+0x01c] FastPebLock      : 0x77245b40 [Type: _RTL_CRITICAL_SECTION *]
    [+0x020] AtlThunkSListPtr : 0x0 [Type: _SLIST_HEADER *]
    [+0x024] IFEOKey          : 0x0 [Type: void *]
    [+0x028] CrossProcessFlags : 0x0 [Type: unsigned long]
    [+0x028 ( 0: 0)] ProcessInJob     : 0x0 [Type: unsigned long]
    [+0x028 ( 1: 1)] ProcessInitializing : 0x0 [Type: unsigned long]
    [+0x028 ( 2: 2)] ProcessUsingVEH  : 0x0 [Type: unsigned long]
    [+0x028 ( 3: 3)] ProcessUsingVCH  : 0x0 [Type: unsigned long]
    [+0x028 ( 4: 4)] ProcessUsingFTH  : 0x0 [Type: unsigned long]
    [+0x028 ( 5: 5)] ProcessPreviouslyThrottled : 0x0 [Type: unsigned long]
    [+0x028 ( 6: 6)] ProcessCurrentlyThrottled : 0x0 [Type: unsigned long]
    [+0x028 ( 7: 7)] ProcessImagesHotPatched : 0x0 [Type: unsigned long]
    [+0x028 (31: 8)] ReservedBits0    : 0x0 [Type: unsigned long]
    [+0x02c] KernelCallbackTable : 0x0 [Type: void *]
    [+0x02c] UserSharedInfoPtr : 0x0 [Type: void *]
    [+0x030] SystemReserved   : 0x0 [Type: unsigned long]
    [+0x034] AtlThunkSListPtr32 : 0x0 [Type: unsigned long]
    [+0x038] ApiSetMap        : 0x4a0000 [Type: _API_SET_NAMESPACE *]
    [+0x03c] TlsExpansionCounter : 0x0 [Type: unsigned long]
    [+0x040] TlsBitmap        : 0x77245d30 [Type: void *]
    [+0x044] TlsBitmapBits    [Type: unsigned long [2]]
    [+0x04c] ReadOnlySharedMemoryBase : 0x7fc90000 [Type: void *]
    [+0x050] SharedData       : 0x0 [Type: void *]
    [+0x054] ReadOnlyStaticServerData : 0x7fc90750 [Type: void * *]
    [+0x058] AnsiCodePageData : 0x7fdf0000 [Type: void *]
    [+0x05c] OemCodePageData  : 0x7fe00228 [Type: void *]
    [+0x060] UnicodeCaseTableData : 0x7fe10650 [Type: void *]
    [+0x064] NumberOfProcessors : 0x8 [Type: unsigned long]
    [+0x068] NtGlobalFlag     : 0x470 [Type: unsigned long]
    [+0x070] CriticalSectionTimeout : {0xffffe86d079b8000} [Type: _ULARGE_INTEGER]
    [+0x078] HeapSegmentReserve : 0x100000 [Type: unsigned long]
    [+0x07c] HeapSegmentCommit : 0x2000 [Type: unsigned long]
    [+0x080] HeapDeCommitTotalFreeThreshold : 0x10000 [Type: unsigned long]
    [+0x084] HeapDeCommitFreeBlockThreshold : 0x1000 [Type: unsigned long]
    [+0x088] NumberOfHeaps    : 0x1 [Type: unsigned long]
    [+0x08c] MaximumNumberOfHeaps : 0x10 [Type: unsigned long]
    [+0x090] ProcessHeaps     : 0x77244840 [Type: void * *]
    [+0x094] GdiSharedHandleTable : 0x0 [Type: void *]
    [+0x098] ProcessStarterHelper : 0x0 [Type: void *]
    [+0x09c] GdiDCAttributeList : 0x0 [Type: unsigned long]
    [+0x0a0] LoaderLock       : 0x77243390 [Type: _RTL_CRITICAL_SECTION *]
    [+0x0a4] OSMajorVersion   : 0xa [Type: unsigned long]
    [+0x0a8] OSMinorVersion   : 0x0 [Type: unsigned long]
    [+0x0ac] OSBuildNumber    : 0x4a63 [Type: unsigned short]
    [+0x0ae] OSCSDVersion     : 0x0 [Type: unsigned short]
    [+0x0b0] OSPlatformId     : 0x2 [Type: unsigned long]
    [+0x0b4] ImageSubsystem   : 0x3 [Type: unsigned long]
    [+0x0b8] ImageSubsystemMajorVersion : 0x6 [Type: unsigned long]
    [+0x0bc] ImageSubsystemMinorVersion : 0x0 [Type: unsigned long]
    [+0x0c0] ActiveProcessAffinityMask : 0xff [Type: unsigned long]
    [+0x0c4] GdiHandleBuffer  [Type: unsigned long [34]]
    [+0x14c] PostProcessInitRoutine : 0x0 [Type: void *]
    [+0x150] TlsExpansionBitmap : 0x77245d18 [Type: void *]
    [+0x154] TlsExpansionBitmapBits [Type: unsigned long [32]]
    [+0x1d4] SessionId        : 0x23 [Type: unsigned long]
    [+0x1d8] AppCompatFlags   : {0x0} [Type: _ULARGE_INTEGER]
    [+0x1e0] AppCompatFlagsUser : {0x0} [Type: _ULARGE_INTEGER]
    [+0x1e8] pShimData        : 0x620000 [Type: void *]
    [+0x1ec] AppCompatInfo    : 0x0 [Type: void *]
    [+0x1f0] CSDVersion       [Type: _UNICODE_STRING]
    [+0x1f8] ActivationContextData : 0x610000 [Type: void *]
    [+0x1fc] ProcessAssemblyStorageMap : 0x0 [Type: void *]
    [+0x200] SystemDefaultActivationContextData : 0x600000 [Type: void *]
    [+0x204] SystemAssemblyStorageMap : 0x0 [Type: void *]
    [+0x208] MinimumStackCommit : 0x0 [Type: unsigned long]
    [+0x20c] SparePointers    [Type: void * [4]]
    [+0x21c] SpareUlongs      [Type: unsigned long [5]]
    [+0x230] WerRegistrationData : 0x0 [Type: void *]
    [+0x234] WerShipAssertPtr : 0x0 [Type: void *]
    [+0x238] pUnused          : 0x0 [Type: void *]
    [+0x23c] pImageHeaderHash : 0x0 [Type: void *]
    [+0x240] TracingFlags     : 0x0 [Type: unsigned long]
    [+0x240 ( 0: 0)] HeapTracingEnabled : 0x0 [Type: unsigned long]
    [+0x240 ( 1: 1)] CritSecTracingEnabled : 0x0 [Type: unsigned long]
    [+0x240 ( 2: 2)] LibLoaderTracingEnabled : 0x0 [Type: unsigned long]
    [+0x240 (31: 3)] SpareTracingBits : 0x0 [Type: unsigned long]
    [+0x248] CsrServerReadOnlySharedMemoryBase : 0x7df467950000 [Type: unsigned __int64]
    [+0x250] TppWorkerpListLock : 0x0 [Type: _RTL_CRITICAL_SECTION *]
    [+0x254] TppWorkerpList   [Type: _LIST_ENTRY]
    [+0x25c] WaitOnAddressHashTable [Type: void * [128]]
    [+0x45c] TelemetryCoverageHeader : 0x0 [Type: void *]
    [+0x460] CloudFileFlags   : 0x0 [Type: unsigned long]
    [+0x464] CloudFileDiagFlags : 0x0 [Type: unsigned long]
    [+0x468] PlaceholderCompatibilityMode : 0 [Type: char]
    [+0x469] PlaceholderCompatibilityModeReserved : "" [Type: char [7]]
    [+0x470] LeapSecondData   : 0x7fde0000 [Type: _LEAP_SECOND_DATA *]
    [+0x474] LeapSecondFlags  : 0x0 [Type: unsigned long]
    [+0x474 ( 0: 0)] SixtySecondEnabled : 0x0 [Type: unsigned long]
    [+0x474 (31: 1)] Reserved         : 0x0 [Type: unsigned long]
    [+0x478] NtGlobalFlag2    : 0x0 [Type: unsigned long]
0:000> dx -r1 ((phnt_demo!_RTL_USER_PROCESS_PARAMETERS *)0xa92928)
((phnt_demo!_RTL_USER_PROCESS_PARAMETERS *)0xa92928)                 : 0xa92928 [Type: _RTL_USER_PROCESS_PARAMETERS *]
    [+0x000] MaximumLength    : 0x2368 [Type: unsigned long]
    [+0x004] Length           : 0x2368 [Type: unsigned long]
    [+0x008] Flags            : 0x2001 [Type: unsigned long]
    [+0x00c] DebugFlags       : 0x0 [Type: unsigned long]
    [+0x010] ConsoleHandle    : 0x90 [Type: void *]
    [+0x014] ConsoleFlags     : 0x0 [Type: unsigned long]
    [+0x018] StandardInput    : 0x9c [Type: void *]
    [+0x01c] StandardOutput   : 0xa0 [Type: void *]
    [+0x020] StandardError    : 0xa4 [Type: void *]
    [+0x024] CurrentDirectory [Type: _CURDIR]
    [+0x030] DllPath          [Type: _UNICODE_STRING]
    [+0x038] ImagePathName    [Type: _UNICODE_STRING]
    [+0x040] CommandLine      [Type: _UNICODE_STRING]
    [+0x048] Environment      : 0xa90b80 [Type: void *]
    [+0x04c] StartingX        : 0x0 [Type: unsigned long]
    [+0x050] StartingY        : 0x0 [Type: unsigned long]
    [+0x054] CountX           : 0x0 [Type: unsigned long]
    [+0x058] CountY           : 0x0 [Type: unsigned long]
    [+0x05c] CountCharsX      : 0x0 [Type: unsigned long]
    [+0x060] CountCharsY      : 0x0 [Type: unsigned long]
    [+0x064] FillAttribute    : 0x0 [Type: unsigned long]
    [+0x068] WindowFlags      : 0x0 [Type: unsigned long]
    [+0x06c] ShowWindowFlags  : 0x0 [Type: unsigned long]
    [+0x070] WindowTitle      [Type: _UNICODE_STRING]
    [+0x078] DesktopInfo      [Type: _UNICODE_STRING]
    [+0x080] ShellInfo        [Type: _UNICODE_STRING]
    [+0x088] RuntimeData      [Type: _UNICODE_STRING]
    [+0x090] CurrentDirectories [Type: _RTL_DRIVE_LETTER_CURDIR [32]]
    [+0x290] EnvironmentSize  : 0x1d8a [Type: unsigned long]
    [+0x294] EnvironmentVersion : 0x4 [Type: unsigned long]
    [+0x298] PackageDependencyData : 0x0 [Type: void *]
    [+0x29c] ProcessGroupId   : 0x4aa8 [Type: unsigned long]
    [+0x2a0] LoaderThreads    : 0x0 [Type: unsigned long]
    [+0x2a4] RedirectionDllName [Type: _UNICODE_STRING]
    [+0x2ac] HeapPartitionName [Type: _UNICODE_STRING]
    [+0x2b4] DefaultThreadpoolCpuSetMasks : 0x0 [Type: unsigned long]
    [+0x2b8] DefaultThreadpoolCpuSetMaskCount : 0x0 [Type: unsigned long]
0:000> dx -r1 (*((phnt_demo!_UNICODE_STRING *)0xa92960))
(*((phnt_demo!_UNICODE_STRING *)0xa92960))                 [Type: _UNICODE_STRING]
    [+0x000] Length           : 0x6a [Type: unsigned short]
    [+0x002] MaximumLength    : 0x6c [Type: unsigned short]
    [+0x004] Buffer           : 0xa92df0 : "J:\dev\temp\phnt-sample\phnt-demo\Debug\phnt-demo.exe" [Type: wchar_t *]
0:000> dx -r1 (*((phnt_demo!_UNICODE_STRING *)0xa92968))
(*((phnt_demo!_UNICODE_STRING *)0xa92968))                 [Type: _UNICODE_STRING]
    [+0x000] Length           : 0x1a [Type: unsigned short]
    [+0x002] MaximumLength    : 0x1c [Type: unsigned short]
    [+0x004] Buffer           : 0xa92e5c : "phnt-demo.exe" [Type: wchar_t *]
Let’s debug a very simple driver from pavel’s latest book on kernel programming and understand different structures along with their relationship and overall...
Let’s explore how nt!PoolHitTag can be useful for while tracking memory issues. Along with useful windbg command like !pool, !poolfind, !verifier etc.
In this post let’s explore the general mechanism of how we go for virtual to physical memory. Trying to understand what happens in between.
In the prev post we saw how to use phnt to access windows native api and undoc structures.
Quite often on windows accessing native api and undoc structures is required.
TL;DR This is taken from the mwri labs doc in links below. The vulnerability is in the function win32k!xxxHandleMenuMessages. When it calls the functio...
When kernel debugging an old target like Windows 7 after a long time using windbg. I noticed not being able to see the registers in register pane. That was k...