In kernel-mode programming, the
FS selector is the follow:
Kernel mode segments:
CS : Selector = 0008, Base = 00000000, Limit = FFFFFFFF, DPL0, Type = CODE -ra
DS : Selector = 0023, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = DATA -wa
ES : Selector = 0023, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = DATA -wa
FS : Selector = 0030, Base = FFDFF000, Limit = 00001FFF, DPL0, Type = DATA -wa
The address 0xFFDFF000 is known as the Processor Control Region,
ou the KPCR structure.
From Four-F KmdKit includes:
KPCR STRUCT ; sizeof = 54h
; Start of the architecturally defined section of the PCR. This section
; may be directly addressed by vendor/platform specific HAL code and will
; not change from version to version of NT.
NtTib NT_TIB <>
SelfPcr PVOID ? ; 1Ch PTR KPCR flat
; address of this PCR
Prcb PVOID ? ; 20h pointer to Prcb
Irql BYTE ? ; 24h KIRQL
db 3 dup(?) ; padding
IRR DWORD ? ; 28h
IrrActive DWORD ? ; 2Ch
IDR DWORD ? ; 30h
Reserved2 DWORD ? ; 34h <---
IDT PVOID ? ; 38h PTR KIDTENTRY
GDT PVOID ? ; 3Ch PTR KGDTENTRY
TSS PVOID ? ; 40h PTR KTSS
MajorVersion WORD ? ; 44h
MinorVersion WORD ? ; 46h
SetMember KAFFINITY ? ; 48h
StallScaleFactor DWORD ? ; 4Ch
DebugActive BYTE ? ; 50h
Number BYTE ? ; 51h
db 2 dup(?) ; 052 padding
KPCR ENDS
PKPCR typedef PTR KPCR
While debugging one driver using SoftICE in Windows XP,
I perceveid that KPCR+0x34 was not equal 0x00000000,
wich as usual in W2K!
Or, in another words, was no more a RESERVED field,
it is an undocumented structure!
Dumping the structure pointed by [KPCR+0x34]
I perceived that it have many important pointers
to non-exported kernel variables like
PsActiveProcessHead, PsLoadedModuleList
MmPfnDatabase, PspCidTable
ObpRootDirectoryObject and more...
Many advanced (I need to be careful with this word) drivers
search for this variables by scanning the whole kernel
memory area, searching for specific opcodes or
signatures.
Kernel variables like PsActiveProcessHead points
to the list of all the process being executed
by the kernel.
Now, with my method, intead of scanning,
is just a question of
mov eax, 0ffdff034h
mov eax, [eax]
mov eax, [eax+078h]
to get the PsActiveProcessHead list!
Researching more, I discovered that
the structure pointed by KPCR+0x34
is exactly the same KDDEBUGGER_DATA32
structure used to create extension to the
WinDbg debugger!
If you know the meaning of each of these
hidden kernel variables, you will be
able to create some very powerfull drivers.
By example, with the PsActiveProcessHead
variable, it is easy to create a more
complete process listener, because this
variable is the head of a doubled-linked
list of EPROCESS structures.
Well, I have tested my program only in Windows XP with
SP1. It will do not work in W2K, because the field
is reserved.
If someone test it in another systems, like w2k3 or
XP without SP, please send me the results in my mail.
I hope that this informations becomes useful to someone.