pspcidtable之旅 (win8.1 x86)
本帖最后由 wjshome 于 2013-12-8 12:11 编辑1. 获取pspcidtable的地址
lkd> dd pspcidtable
812a031482006000 00000002 00000200 0000000f
812a03240000001e 00000258 00000000 00000000
812a0334812a0324 8108e4cc 0000001e 812a0320
812a03448108e4fc 0000000f 812a0328 8108e528
812a035400000258 812a031c 8108e558 00000200
812a03648486f520 84873040 8486bb38 00000000
812a0374ffffffff 00000000 00000000 00000002
812a038400000000 00000005 c0000044 00000005
2. pspcidtable 地址为82006000, 是指向一个 _handle_table
lkd> dt _handle_table 82006000
ntdll!_HANDLE_TABLE
+0x000 NextHandleNeedingPool : 0x1000
+0x004 ExtraInfoPages : 0n0
+0x008 TableCode : 0x80901001
+0x00c QuotaProcess : (null)
+0x010 HandleTableList: _LIST_ENTRY [ 0x82006010 - 0x82006010 ]
+0x018 UniqueProcessId: 0
+0x01c Flags : 1
+0x01c StrictFIFO : 0y1
+0x01c EnableHandleExceptions : 0y0
+0x01c Rundown : 0y0
+0x01c Duplicated : 0y0
+0x020 HandleContentionEvent : _EX_PUSH_LOCK
+0x024 HandleTableLock: _EX_PUSH_LOCK
+0x028 FreeLists : _HANDLE_TABLE_FREE_LIST
+0x028 ActualEntry : ""
+0x03c DebugInfo : (null)
3. 其中的TableCode为0x80901001, TableCode 字段的解释与其他系统中一样的,低 3 Bits 表示是几层表结构,低3位清0之后的值就是层表地址。
0x80901001 低3位清零后为0x80901000 ,是一个二级表
lkd> dd 0x80901000
8090100082008000 80903000 00000000 00000000
8090101000000000 00000000 00000000 00000000
8090102000000000 00000000 00000000 00000000
8090103000000000 00000000 00000000 00000000
8090104000000000 00000000 00000000 00000000
8090105000000000 00000000 00000000 00000000
8090106000000000 00000000 00000000 00000000
8090107000000000 00000000 00000000 00000000
4. 二级表是包含指向一级表的指针,发掘第一个一级表82008000
lkd> dd 82008000
8200800000000000 00000000 8486e441 98000000
8200801084875bc1 00000000 84875741 00000000
820080208487e041 00000000 8487e8c1 00000000
8200803084880bc1 00000000 84880741 00000000
820080408487b041 00000000 00000000 809032a8
820080508487b4c1 00000000 848a5a41 00000000
82008060848a55c1 00000000 848825c1 00000000
82008070848329c1 00000000 84832581 00000000
5. 一级表是_HANDLE_TABLE_ENTRY数组,第一个为0,我们看看第二个
lkd> dt _handle_table_entry 8486e441
ntdll!_HANDLE_TABLE_ENTRY
+0x000 VolatileLowValue : 0n10240
+0x000 LowValue : 0n10240
+0x000 InfoTable : 0x00002800 _HANDLE_TABLE_ENTRY_INFO
+0x000 Unlocked : 0y0
+0x000 Attributes : 0y00
+0x000 ObjectPointerBits : 0y00000000000000000010100000000 (0x500)
+0x004 HighValue : 0n1207959552
+0x004 NextFreeHandleEntry : 0x48000000 _HANDLE_TABLE_ENTRY
+0x004 LeafHandleValue: _EXHANDLE
+0x004 GrantedAccessBits : 0y0000000000000000000000000 (0)
+0x004 ProtectFromClose : 0y0
+0x004 NoRightsUpgrade: 0y0
+0x004 RefCnt : 0y01001 (0x9)
6. 计算出object 的地址为: 8486e440
Object Address = (Object/ObjectPointerBits & 0xFFFFFFF8) | 0x80000000
lkd> !object 8486e440
Object: 8486e440Type: (8486bf70) Process
ObjectHeader: 8486e428 (new version)
HandleCount: 5PointerCount: 305
lkd> dt _eprocess 8486e440
ntdll!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x0a0 ProcessLock : _EX_PUSH_LOCK
+0x0a8 CreateTime : _LARGE_INTEGER 0x01ceec99`1748a0c8
+0x0b0 RundownProtect : _EX_RUNDOWN_REF
+0x0b4 UniqueProcessId: 0x00000004 Void
....
+0x170 ImageFileName : "System"
....
原来是 System 进程, PID 为 4
参考:
http://bbs.pediy.com/showthread.php?t=170205
http://hi.baidu.com/_achillis/item/d76dd19faa660e8d5914611a
-----------------------------------------------------------------------------------
【更新:通过KPCR获取pspcidtable地址】
1. 在windbg里面可以通过!pcr指令获得,ring0下直接读取FS:即可.
WINDBG>!pcr 0
KPCR for Processor 0 at 82027000:
Major 1 Minor 1
NtTib.ExceptionList: 83151004
NtTib.StackBase: 00000000
NtTib.StackLimit: 00001f80
NtTib.SubSystemTib: 81379000
NtTib.Version: 000222ee
NtTib.UserPointer: 00000001
NtTib.SelfTib: 00000000
SelfPcr: 82027000
Prcb: 82027120
Irql: 0000001f
IRR: 00000000
IDR: 00000000
InterruptMode: 00000000
IDT: 81375400
GDT: 81375000
TSS: 81379000
CurrentThread: 82036100
NextThread: 00000000
IdleThread: 82036100
DpcQueue: Unable to read nt!_KDPC_DATA.DpcListHead.Flink @ 82029300
WINDBG>dd fs:
0030:0000000083151004 00000000 00001f80 81379000
0030:0000001000084b96 00000001 00000000 82027000
0030:0000002082027120 0000001f 00000000 00000000
0030:0000003000000000 81ffdd60 81375400 81375000
0030:0000004081379000 00010001 00000001 00000dad
0030:0000005000000000 00000000 00000000 00000000
0030:0000006000000000 00000000 00000000 00000000
0030:0000007000000000 00000000 00000000 00000000
WINDBG>dt _kpcr 82027000
nt!_KPCR
+0x000 NtTib : _NT_TIB
+0x000 Used_ExceptionList : 0x83151004 _EXCEPTION_REGISTRATION_RECORD
+0x004 Used_StackBase : (null)
+0x008 MxCsr : 0x1f80
+0x00c TssCopy : 0x81379000 Void
+0x010 ContextSwitches: 0x222ee
+0x014 SetMemberCopy : 1
+0x018 Used_Self : (null)
+0x01c SelfPcr : 0x82027000 _KPCR
+0x020 Prcb : 0x82027120 _KPRCB
+0x024 Irql : 0x1f ''
+0x028 IRR : 0
+0x02c IrrActive : 0
+0x030 IDR : 0
+0x034 KdVersionBlock : 0x81ffdd60 Void
+0x038 IDT : 0x81375400 _KIDTENTRY
+0x03c GDT : 0x81375000 _KGDTENTRY
+0x040 TSS : 0x81379000 _KTSS
+0x044 MajorVersion : 1
+0x046 MinorVersion : 1
+0x048 SetMember : 1
+0x04c StallScaleFactor : 0xdad
+0x050 SpareUnused : 0 ''
+0x051 Number : 0 ''
+0x052 Spare0 : 0 ''
+0x053 SecondLevelCacheAssociativity : 0 ''
+0x054 VdmAlert : 0
+0x058 KernelReserved : 0
+0x090 SecondLevelCacheSize : 0
+0x094 HalReserved : 0x1000000
+0x0d4 InterruptMode : 0
+0x0d8 Spare1 : 0 ''
+0x0dc KernelReserved2: 0
+0x120 PrcbData : _KPRCB
2. KeVersionBlock 指向的是_DBGKD_GET_VERSION64结构体,紧跟在后面的是KDDEBUGGER_DATA64
在wdk8.1中以下位置可以得到这些结构体的定义:
C:\Program Files (x86)\Windows Kits\8.1\Debuggers\inc\wdbgexts.h
WINDBG>dt _dbgkd_get_version64 0x81ffdd60
nt!_DBGKD_GET_VERSION64
+0x000 MajorVersion : 0xf
+0x002 MinorVersion : 0x2580
+0x004 ProtocolVersion: 0x6 ''
+0x005 KdSecondaryVersion : 0 ''
+0x006 Flags : 3
+0x008 MachineType : 0x14c
+0x00a MaxPacketType : 0xc ''
+0x00b MaxStateChange : 0x3 ''
+0x00c MaxManipulate : 0x31 '1'
+0x00d Simulation : 0 ''
+0x00e Unused : 0
+0x010 KernBase : 0xffffffff`81e1c000
+0x018 PsLoadedModuleList : 0xffffffff`82015218
+0x020 DebuggerDataList : 0xffffffff`82313030
3. _DBGKD_GET_VERSION64这个结构体的大小是0x20,最后一个成员DebuggerDataList是一个指向KDDEBUGGER_DATA64指针的指针,所以:
WINDBG>dd 0x81ffdd60 + 0x20
81ffdd8082313030 ffffffff 00000040 81f1d748
81ffdd9081f1d76c 00000001 00000007 00000000
81ffdda0823e1426 823e152a fffff000 000000ff
81ffddb0fffff000 000000ff 00002728 00100000
81ffddc00000000d 00000001 0007ab6e 00000012
81ffddd000000001 00000000 00000005 0000016c
81ffdde000000000 004c4b40 ffffffff 00000007
81ffddf000000000 82156d18 00000000 81eb0498
4. 81ffda00 是一个KDDEBUGGER_DATA64指针,继续
WINDBG>dd 82313030
8231303081ffda00 81ffda00 00000000 81f1dae4
8231304000000000 00000000 00000000 00000000
8231305000000000 00000000 00000000 00000000
8231306000000000 00000000 00000000 00000000
8231307000000000 00000000 00000000 00000000
8231308000000000 00000000 00000000 00000000
8231309000000000 00000000 00000000 00000000
823130a000000000 00000000 00000000 00000000
5. 来到KDDEBUGGER_DATA64结构,这个结构请自己参考: wdbgexts.h
WINDBG>dd 81ffda00
81ffda0082313030 82313030 00000000 00000000
81ffda104742444b 00000360 81e1c000 00000000
81ffda2081f1dae4 00000000 00000000 00000000
81ffda3000000000 00010018 81f1cbc0 00000000
81ffda4000000000 00000000 82015218 00000000
81ffda508200cc58 00000000 82045314 00000000
81ffda6082009398 00000000 820453f0 00000000
81ffda70820453e8 00000000 820443ec 00000000
6. 在偏移0x58处,找到pspcidtable的地址
WINDBG>dd 81ffda00 + 0x58
81ffda5882045314 00000000 82009398 00000000
81ffda68820453f0 00000000 820453e8 00000000
81ffda78820443ec 00000000 8201aa40 00000000
81ffda888201a360 00000000 8201d0b8 00000000
81ffda988200e1d0 00000000 8200e1d4 00000000
81ffdaa800000000 00000000 00000000 00000000
81ffdab8820381c0 00000000 82044708 00000000
81ffdac800000000 00000000 00000000 00000000
7. 比较: 82045314
WINDBG>dd pspcidtable
8204531483206000 00000002 00000200 0000000f
820453240000001e 00000258 00000000 00000000
8204533482045324 81e334cc 0000001e 82045320
8204534481e334fc 0000000f 82045328 81e33528
8204535400000258 8204531c 81e33558 00000200
820453648566c3f0 8566c320 8566af70 00000000
82045374ffffffff 00000000 00000000 00000002
8204538400000000 00000005 c0000044 00000005
8. 顺便贴下相关的结构
typedef struct _DBGKD_DEBUG_DATA_HEADER64 {
//
// Link to other blocks
//
LIST_ENTRY64 List;
//
// This is a unique tag to identify the owner of the block.
// If your component only uses one pool tag, use it for this, too.
//
ULONG OwnerTag;
//
// This must be initialized to the size of the data block,
// including this structure.
//
ULONG Size;
} DBGKD_DEBUG_DATA_HEADER64, *PDBGKD_DEBUG_DATA_HEADER64;
//
// This structure is the same size on all systems.The only field
// which must be translated by the debugger is Header.List.
//
//
// DO NOT ADD OR REMOVE FIELDS FROM THE MIDDLE OF THIS STRUCTURE!!!
//
// If you remove a field, replace it with an "unused" placeholder.
// Do not reuse fields until there has been enough time for old debuggers
// and extensions to age out.
//
typedef struct _KDDEBUGGER_DATA64 {
DBGKD_DEBUG_DATA_HEADER64 Header;
//
// Base address of kernel image
//
ULONG64 KernBase;
//
// DbgBreakPointWithStatus is a function which takes an argument
// and hits a breakpoint.This field contains the address of the
// breakpoint instruction.When the debugger sees a breakpoint
// at this address, it may retrieve the argument from the first
// argument register, or on x86 the eax register.
//
ULONG64 BreakpointWithStatus; // address of breakpoint
//
// Address of the saved context record during a bugcheck
//
// N.B. This is an automatic in KeBugcheckEx's frame, and
// is only valid after a bugcheck.
//
ULONG64 SavedContext;
//
// help for walking stacks with user callbacks:
//
//
// The address of the thread structure is provided in the
// WAIT_STATE_CHANGE packet.This is the offset from the base of
// the thread structure to the pointer to the kernel stack frame
// for the currently active usermode callback.
//
USHORTThCallbackStack; // offset in thread data
//
// these values are offsets into that frame:
//
USHORTNextCallback; // saved pointer to next callback frame
USHORTFramePointer; // saved frame pointer
//
// pad to a quad boundary
//
USHORTPaeEnabled:1;
//
// Address of the kernel callout routine.
//
ULONG64 KiCallUserMode; // kernel routine
//
// Address of the usermode entry point for callbacks.
//
ULONG64 KeUserCallbackDispatcher; // address in ntdll
//
// Addresses of various kernel data structures and lists
// that are of interest to the kernel debugger.
//
ULONG64 PsLoadedModuleList;
ULONG64 PsActiveProcessHead;
ULONG64 PspCidTable;
ULONG64 ExpSystemResourcesList;
ULONG64 ExpPagedPoolDescriptor;
ULONG64 ExpNumberOfPagedPools;
ULONG64 KeTimeIncrement;
ULONG64 KeBugCheckCallbackListHead;
ULONG64 KiBugcheckData;
ULONG64 IopErrorLogListHead;
ULONG64 ObpRootDirectoryObject;
ULONG64 ObpTypeObjectType;
ULONG64 MmSystemCacheStart;
ULONG64 MmSystemCacheEnd;
ULONG64 MmSystemCacheWs;
ULONG64 MmPfnDatabase;
ULONG64 MmSystemPtesStart;
ULONG64 MmSystemPtesEnd;
ULONG64 MmSubsectionBase;
ULONG64 MmNumberOfPagingFiles;
ULONG64 MmLowestPhysicalPage;
ULONG64 MmHighestPhysicalPage;
ULONG64 MmNumberOfPhysicalPages;
ULONG64 MmMaximumNonPagedPoolInBytes;
ULONG64 MmNonPagedSystemStart;
ULONG64 MmNonPagedPoolStart;
ULONG64 MmNonPagedPoolEnd;
ULONG64 MmPagedPoolStart;
ULONG64 MmPagedPoolEnd;
ULONG64 MmPagedPoolInformation;
ULONG64 MmPageSize;
ULONG64 MmSizeOfPagedPoolInBytes;
ULONG64 MmTotalCommitLimit;
ULONG64 MmTotalCommittedPages;
ULONG64 MmSharedCommit;
ULONG64 MmDriverCommit;
ULONG64 MmProcessCommit;
ULONG64 MmPagedPoolCommit;
ULONG64 MmExtendedCommit;
ULONG64 MmZeroedPageListHead;
ULONG64 MmFreePageListHead;
ULONG64 MmStandbyPageListHead;
ULONG64 MmModifiedPageListHead;
ULONG64 MmModifiedNoWritePageListHead;
ULONG64 MmAvailablePages;
ULONG64 MmResidentAvailablePages;
ULONG64 PoolTrackTable;
ULONG64 NonPagedPoolDescriptor;
ULONG64 MmHighestUserAddress;
ULONG64 MmSystemRangeStart;
ULONG64 MmUserProbeAddress;
ULONG64 KdPrintCircularBuffer;
ULONG64 KdPrintCircularBufferEnd;
ULONG64 KdPrintWritePointer;
ULONG64 KdPrintRolloverCount;
ULONG64 MmLoadedUserImageList;
// NT 5.1 Addition
ULONG64 NtBuildLab;
ULONG64 KiNormalSystemCall;
// NT 5.0 hotfix addition
ULONG64 KiProcessorBlock;
ULONG64 MmUnloadedDrivers;
ULONG64 MmLastUnloadedDriver;
ULONG64 MmTriageActionTaken;
ULONG64 MmSpecialPoolTag;
ULONG64 KernelVerifier;
ULONG64 MmVerifierData;
ULONG64 MmAllocatedNonPagedPool;
ULONG64 MmPeakCommitment;
ULONG64 MmTotalCommitLimitMaximum;
ULONG64 CmNtCSDVersion;
// NT 5.1 Addition
ULONG64 MmPhysicalMemoryBlock;
ULONG64 MmSessionBase;
ULONG64 MmSessionSize;
ULONG64 MmSystemParentTablePage;
// Server 2003 addition
ULONG64 MmVirtualTranslationBase;
USHORT OffsetKThreadNextProcessor;
USHORT OffsetKThreadTeb;
USHORT OffsetKThreadKernelStack;
USHORT OffsetKThreadInitialStack;
USHORT OffsetKThreadApcProcess;
USHORT OffsetKThreadState;
USHORT OffsetKThreadBStore;
USHORT OffsetKThreadBStoreLimit;
USHORT SizeEProcess;
USHORT OffsetEprocessPeb;
USHORT OffsetEprocessParentCID;
USHORT OffsetEprocessDirectoryTableBase;
USHORT SizePrcb;
USHORT OffsetPrcbDpcRoutine;
USHORT OffsetPrcbCurrentThread;
USHORT OffsetPrcbMhz;
USHORT OffsetPrcbCpuType;
USHORT OffsetPrcbVendorString;
USHORT OffsetPrcbProcStateContext;
USHORT OffsetPrcbNumber;
USHORT SizeEThread;
ULONG64 KdPrintCircularBufferPtr;
ULONG64 KdPrintBufferSize;
ULONG64 KeLoaderBlock;
USHORT SizePcr;
USHORT OffsetPcrSelfPcr;
USHORT OffsetPcrCurrentPrcb;
USHORT OffsetPcrContainedPrcb;
USHORT OffsetPcrInitialBStore;
USHORT OffsetPcrBStoreLimit;
USHORT OffsetPcrInitialStack;
USHORT OffsetPcrStackLimit;
USHORT OffsetPrcbPcrPage;
USHORT OffsetPrcbProcStateSpecialReg;
USHORT GdtR0Code;
USHORT GdtR0Data;
USHORT GdtR0Pcr;
USHORT GdtR3Code;
USHORT GdtR3Data;
USHORT GdtR3Teb;
USHORT GdtLdt;
USHORT GdtTss;
USHORT Gdt64R3CmCode;
USHORT Gdt64R3CmTeb;
ULONG64 IopNumTriageDumpDataBlocks;
ULONG64 IopTriageDumpDataBlocks;
// Longhorn addition
ULONG64 VfCrashDataBlock;
ULONG64 MmBadPagesDetected;
ULONG64 MmZeroedPageSingleBitErrorsDetected;
// Windows 7 addition
ULONG64 EtwpDebuggerData;
USHORT OffsetPrcbContext;
// Windows 8 addition
USHORT OffsetPrcbMaxBreakpoints;
USHORT OffsetPrcbMaxWatchpoints;
ULONG OffsetKThreadStackLimit;
ULONG OffsetKThreadStackBase;
ULONG OffsetKThreadQueueListEntry;
ULONG OffsetEThreadIrpList;
USHORT OffsetPrcbIdleThread;
USHORT OffsetPrcbNormalDpcState;
USHORT OffsetPrcbDpcStack;
USHORT OffsetPrcbIsrStack;
USHORT SizeKDPC_STACK_FRAME;
// Windows 8.1 Addition
USHORT OffsetKPriQueueThreadListHead;
USHORT OffsetKThreadWaitReason;
} KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64;
参考:
http://www.cnblogs.com/unixstudio/archive/2012/11/05/2755356.html 不错不错。支持一下。 终于注册成功 !!!1 没接触过64位的,有空研究研究
页:
[1]