PCR

当线程在内核模式下执行时,在FS寄存器中加载的是选择子30,用于寻址PCR结构体(基址0
xFFDFF000,界限0x00001FFF)。在NTDDK.H中远没有描述结构体所有的成员,只是其中不多
的部分。为了说明PCR中的成分信息,这里列出用于i386的结构体(Windows NT 4.0)

typedef struct _KPCR {             // Size: 0xB10
/*000*/ NT_TIB NtTib;
/*01C*/ struct _KPCR* SelfPcr;
/*020*/ struct _KPRCB* Prcb;       // Current PCB
/*024*/ KIRQL Irql;           // Current IRQL
/*028*/ ULONG IRR;
/*02C*/ ULONG IrrActive;
/*030*/ ULONG IDR;
/*034*/ ULONG Reserved2;
/*038*/ struct _KIDTENTRY* ULONG IDT;
/*03C*/ struct _KGDTENTRY* GDT;
/*040*/ struct _KTSS* TSS;
/*044*/ USHORT MajorVersion;       // 1
/*046*/ USHORT MinorVersion;       // 1
/*048*/ KAFFINITY SetMember;
/*04C*/ ULONG StallScaleFactor;
/*050*/ UCHAR DebugActive;
/*051*/ UCHAR Number;

// End of official portion of KPCR

/*052*/ BOOLEAN VdmAlert;
/*053*/ UCHAR Reserved;
/*054*/ UCHAR KernelReserved[0x90-0x54];
/*090*/ ULONG SecondLevelCacheSize;
/*094*/ UCHAR HalReserved[0xD4-0x94];
/*0D4*/ ULONG InterruptMode;
/*0D8*/ ULONG Spare1;
/*0DC*/ UCHAR KernelReserved2[0x120-0xDC];

// Note that current thread is at offset 0x124 (pointer to KTHREAD)
// This essentially means that the 1st PRCB must match the active CPU

/*120*/ UCHAR PrcbData[0xB10-0x120];    // PCBs for all CPUs supported
} KPCR, *PKPCR;

PCR包含着指向PCRB(Processor Control Region)的指针,但实际上,PCRB位于PCR的偏移
0x120处,并且所有的向PCRB域的转换都是相对于PCR的起点的。在WINNT.H中描述了PCRB结构
体。这里给出整个结构体(Windows NT 4.0):

// 0x120 from KPCR
typedef struct _KPRCB {
/*000*/    USHORT MinorVersion;
/*002*/    USHORT MajorVersion;
/*004*/    struct _KTHREAD *CurrentThread;
/*008*/    struct _KTHREAD *NextThread;
/*00c*/    struct _KTHREAD *IdleThread;
/*010*/    CCHAR Number;
/*011*/    CCHAR Reserved;
/*012*/    USHORT BuildType;
/*014*/    KAFFINITY SetMember;
/*015*/    struct _RESTART_BLOCK *RestartBlock;
/*018*/    CCHAR CpuType;
/*019*/    CCHAR CpuID;
/*01A*/    CCHAR CpuStep;
/*01C*/    KPROCESSOR_STATE ProcessorState;
/*13C*/    CCHAR KernelReserved[0x40];
/*17C*/    CCHAR HalReserved[0x40];
/*1BC*/    ULONG NpxThread;
/*1C0*/    ULONG InterruptCount;
/*1C4*/    ULONG KernelTime;
/*1C8*/    ULONG UserTime;
/*1CC*/    ULONG DpcTime;
/*1D0*/    ULONG InterruptTime;
/*1D4*/    ULONG ApcBypassCount;
/*1D8*/    ULONG DpcBypassCount;
/*1DC*/    ULONG AdjustDpcThreshold;
/*1E0*/    UCHAR Spare2[0x14];
/*1F4*/    ULONG64 ThreadStartCount;
/*1FC*/    SINGLE_LIST_ENTRY FsRtlFreeSharedLockList;
/*200*/    SINGLE_LIST_ENTRY FsRtlFreeExclusiveLockList;
/*204*/    ULONG CcFastReadNoWait;
/*208*/    ULONG CcFastReadWait;
/*20C*/    ULONG CcFastReadNotPossible;
/*210*/    ULONG CcCopyReadNoWait;
/*214*/    ULONG CcCopyReadWait;
/*218*/    ULONG CcCopyReadNoWaitMiss;
/*21C*/    ULONG KeAlignmentFixupCount;
/*220*/    ULONG KeContextSwitches;
/*224*/    ULONG KeDcacheFlushCount;
/*228*/    ULONG KeExceptionDispatchCount;
/*22C*/    ULONG KeFirstLevelTbFills;
/*230*/    ULONG KeFloatingEmulationCount;
/*234*/    ULONG KeIcacheFlushCount;
/*238*/    ULONG KeSecondLevelTbFills;
/*23C*/    ULONG KeSystemCalls;
/*240*/    SINGLE_LIST_ENTRY FsRtlFreeWaitingLockList;
/*244*/    SINGLE_LIST_ENTRY FsRtlFreeLockTreeNodeList
/*248*/    CCHAR ReservedCounter[0x18];
/*260*/    PVOID SmallIrpFreeEntry;
/*264*/    PVOID LargeIrpFreeEntry;
/*268*/    PVOID MdlFreeEntry
/*26C*/    PVOID  CreateInfoFreeEntry;
/*270*/    PVOID NameBufferFreeEntry
/*274*/    PVOID SharedCacheMapEntry
/*278*/    CCHAR CachePad0[8];
/*280*/    CCHAR ReservedPad[0x200];
/*480*/    CCHAR  CurrentPacket[0xc];
/*48C*/    ULONG TargetSet;
/*490*/    PVOID WorkerRoutine;
/*494*/    ULONG IpiFrozen;
/*498*/    CCHAR  CachePad1[0x8];
/*4A0*/    ULONG RequestSummary;
/*4A4*/    ULONG SignalDone;
/*4A8*/    ULONG ReverseStall;
/*4AC*/    ULONG IpiFrame;
/*4B0*/    CCHAR CachePad2[0x10];
/*4C0*/    ULONG DpcInterruptRequested;
/*4C4*/    CCHAR CachePad3 [0xc];
/*4D0*/    ULONG MaximumDpcQueueDepth;
/*4D4*/    ULONG MinimumDpcRate;
/*4D8*/    CCHAR CachePad4[0x8];
/*4E0*/    LIST_ENTRY DpcListHead;
/*4E8*/    ULONG DpcQueueDepth;
/*4EC*/    ULONG DpcRoutineActive;
/*4F0*/    ULONG DpcCount;
/*4F4*/    ULONG DpcLastCount;
/*4F8*/    ULONG DpcRequestRate;
/*4FC*/    CCHAR KernelReserved2[0x2c];
/*528*/    ULONG DpcLock;
/*52C*/    CCHAR SkipTick;
/*52D*/    CCHAR VendorString[0xf];
/*53C*/    ULONG MHz;
/*540*/    ULONG64 FeatureBits;
/*548*/    ULONG64 UpdateSignature;
/*550*/    ULONG QuantumEnd;

} KPRCB, *PKPRCB, *RESTRICTED_POINTER PRKPRCB;

PCRB中最有用的就是指向当前线程的指针(KTHREAD结构体)。通常内核代码以以下代码取得
此指针:

你可能感兴趣的:(驱动开发学习)