lorddoskias wrote:SelfPcr is 0 ? Why is that - how to get the address of KPCR?
!pcr command for x64 is totally bugged.
As you know KPCR for x64 and KPCR for x86 are different. They have differently named fields. kdexts.dll seems to be broken as it tries to read fields that are not exists on x64 resulting in bugged output for !pcr command.
Take a simple example. This is inline macro KeGetPcr
for x86 it reads field named
SelfPcr which is flat address of this Pcr
Code: Select allFORCEINLINE
PKPCR
NTAPI
KeGetPcr(VOID)
{
#if NT_UP
return (PKPCR)KIP0PCRADDRESS;
#else
#if (_MSC_FULL_VER >= 13012035)
return (PKPCR) (ULONG_PTR) __readfsdword (FIELD_OFFSET (KPCR, SelfPcr));
#else
__asm { mov eax, _PCR KPCR.SelfPcr }
#endif
#endif
}
for x64 it reads field named
Self
Code: Select all__forceinline
PKPCR
KeGetPcr (
VOID
)
{
return (PKPCR)__readgsqword(FIELD_OFFSET(KPCR, Self));
}
Now lets check how it possible that !pcr gives NULL for IDT, GDT, TSS and SelfPcr?
Checking the first function which comes into my mind regarding to PCR.
Code: Select allMicrosoft (R) Windows Debugger Version 6.12.0002.633 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [C:\Windows\livekd.dmp]
Kernel Complete Dump File: Full address space is available
Comment: 'LiveKD live system view'
Symbol search path is: srv*c:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows 7 Kernel Version 7601 (Service Pack 1) MP (16 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 7601.17640.amd64fre.win7sp1_gdr.110622-1506
Machine Name:
Kernel base = 0xfffff800`02c1e000 PsLoadedModuleList = 0xfffff800`02e63670
Debug session time: Sun Feb 13 10:34:57.897 17420 (UTC + 1:00)
System Uptime: 0 days 0:27:22.580
Loading Kernel Symbols
...............................................................
................................................................
....................................................
Loading User Symbols
Loading unloaded module list
0: kd> u PsGetCurrentProcess
nt!PsGetCurrentProcess:
fffff800`02cad150 65488b042588010000 mov rax,qword ptr gs:[188h]
fffff800`02cad159 488b4070 mov rax,qword ptr [rax+70h]
gs in place.
Lets list KPCR data by address given from !pcr
Code: Select all0: kd> !pcr
KPCR for Processor 0 at fffff80002e10d00:
Major 1 Minor 1
NtTib.ExceptionList: fffff80000b95000
NtTib.StackBase: fffff80000b96080
NtTib.StackLimit: 000000000229f648
NtTib.SubSystemTib: fffff80002e10d00
NtTib.Version: 0000000002e10e80
NtTib.UserPointer: fffff80002e114f0
NtTib.SelfTib: 000007fffffdd000
SelfPcr: 0000000000000000
Prcb: fffff80002e10e80
Irql: 0000000000000000
IRR: 0000000000000000
IDR: 0000000000000000
InterruptMode: 0000000000000000
IDT: 0000000000000000
GDT: 0000000000000000
TSS: 0000000000000000
CurrentThread: fffff80002e1ecc0
NextThread: 0000000000000000
IdleThread: fffff80002e1ecc0
DpcQueue:
Code: Select all0: kd> dt nt!_KPCR fffff80002e10d00
+0x000 NtTib : _NT_TIB
+0x000 GdtBase : 0xfffff800`00b95000 _KGDTENTRY64
+0x008 TssBase : 0xfffff800`00b96080 _KTSS64
+0x010 UserRsp : 0x229f648
+0x018 Self : 0xfffff800`02e10d00 _KPCR
+0x020 CurrentPrcb : 0xfffff800`02e10e80 _KPRCB
+0x028 LockArray : 0xfffff800`02e114f0 _KSPIN_LOCK_QUEUE
+0x030 Used_Self : 0x000007ff`fffdd000 Void
+0x038 IdtBase : 0xfffff800`00b95080 _KIDTENTRY64
+0x040 Unused : [2] 0
+0x050 Irql : 0 ''
+0x051 SecondLevelCacheAssociativity : 0x8 ''
+0x052 ObsoleteNumber : 0 ''
+0x053 Fill0 : 0 ''
+0x054 Unused0 : [3] 0
+0x060 MajorVersion : 1
+0x062 MinorVersion : 1
+0x064 StallScaleFactor : 0x703
+0x068 Unused1 : [3] (null)
+0x080 KernelReserved : [15] 0
+0x0bc SecondLevelCacheSize : 0x200000
+0x0c0 HalReserved : [16] 0x6b063950
+0x100 Unused2 : 0
+0x108 KdVersionBlock : (null)
+0x110 Unused3 : (null)
+0x118 PcrAlign1 : [24] 0
+0x180 Prcb : _KPRCB
As you see IdtBase, GdtBase, TssBase and Self are not NULL (and cant be). Probably this is kdexts.dll bug and it seems exists for years (6.12.0002.633 AMD64 output here).
Do not blindly trust Windbg :)