2018年5月1日星期二

手工分析进程的句柄表

对象体由执行体管理
对象头由对象管理器管理器
句柄由进程的句柄表维护。


0: kd> $实验环境是:
0: kd> vertarget
Windows 8 Kernel Version 9200 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 16299.15.amd64fre.rs3_release.170928-1534
Machine Name:
Kernel base = 0xfffff803`7b41c000 PsLoadedModuleList = 0xfffff803`7b782fd0
Debug session time: Tue Mar  6 09:25:21.921 2018 (UTC + 8:00)
System Uptime: 27 days 19:47:07.599
0: kd> $文件的版本是:
0: kd> lm vm nt
Browse full module list
start             end                 module name
fffff803`7b41c000 fffff803`7bcf1000   nt         (pdb symbols)          c:\symbols\ntkrnlmp.pdb\9378084E8DBD4AB1A155099BCE693E341\ntkrnlmp.pdb
    Loaded symbol image file: ntkrnlmp.exe
    Image path: ntkrnlmp.exe
    Image name: ntkrnlmp.exe
    Browse all global symbols  functions  data
    Timestamp:        Mon Jan  1 19:07:05 2018 (5A4A1659)
    CheckSum:         00842CC4
    ImageSize:        008D5000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4
0: kd> $测试的进程是:
0: kd> !process 0 0 cmd.exe
PROCESS ffff8c08dc95f080
    SessionId: 4  Cid: 0fdc    Peb: 008ff000  ParentCid: 1934
    DirBase: 1d7a00000  ObjectTable: 00000000  HandleCount:   0.
    Image: cmd.exe

PROCESS ffff8c08d9136080
    SessionId: 11  Cid: 0168    Peb: f170b88000  ParentCid: 16fc
    DirBase: 112600000  ObjectTable: ffffa00a63dc1600  HandleCount:  40.
    Image: cmd.exe

0: kd> $这里选定第二个。
0: kd> $另一个看法是:
0: kd> dt  nt!_eprocess ffff8c08d9136080 ObjectTable
   +0x418 ObjectTable : 0xffffa00a`63dc1600 _HANDLE_TABLE
 
句柄表的信息是:
0: kd> dt 0xffffa00a`63dc1600 nt!_HANDLE_TABLE
   +0x000 NextHandleNeedingPool : 0x400
   +0x004 ExtraInfoPages   : 0n0
   +0x008 TableCode        : 0xffffa00a`591d4000
   +0x010 QuotaProcess     : 0xffff8c08`d9136080 _EPROCESS
   +0x018 HandleTableList  : _LIST_ENTRY [ 0xffffa00a`74606b58 - 0xffffa00a`56527758 ]
   +0x028 UniqueProcessId  : 0x168
   +0x02c Flags            : 0x10
   +0x02c StrictFIFO       : 0y0
   +0x02c EnableHandleExceptions : 0y0
   +0x02c Rundown          : 0y0
   +0x02c Duplicated       : 0y0
   +0x02c RaiseUMExceptionOnInvalidHandleClose : 0y1
   +0x030 HandleContentionEvent : _EX_PUSH_LOCK
   +0x038 HandleTableLock  : _EX_PUSH_LOCK
   +0x040 FreeLists        : [1] _HANDLE_TABLE_FREE_LIST
   +0x040 ActualEntry      : [32]  ""
   +0x060 DebugInfo        : (null)


要实现的效果是:
0: kd> !handle 0 0 0168

PROCESS ffff8c08d9136080
    SessionId: 11  Cid: 0168    Peb: f170b88000  ParentCid: 16fc
    DirBase: 112600000  ObjectTable: ffffa00a63dc1600  HandleCount:  40.
    Image: cmd.exe

Handle table at ffffa00a63dc1600 with 40 entries in use

0004: Object: ffff8c08d7911fe0  GrantedAccess: 001f0003 (Protected) (Inherit)

0008: Object: ffff8c08d9a8b4d0  GrantedAccess: 00000001 (Inherit)

000c: Object: ffff8c08d4ae0700  GrantedAccess: 001f0003 (Protected) (Audit)

0010: Object: ffff8c08de983660  GrantedAccess: 000f00ff (Protected) (Inherit)

0014: Object: ffff8c08d509e430  GrantedAccess: 00100002

0018: Object: ffff8c08d65c3260  GrantedAccess: 00000001 (Protected) (Inherit)

001c: Object: ffff8c08d6353f30  GrantedAccess: 00100002

0020: Object: ffff8c08d50642b0  GrantedAccess: 00000001

0024: Object: ffff8c08d8e81e20  GrantedAccess: 00000804 (Protected) (Inherit) (Audit)

0028: Object: ffff8c08d78fabd0  GrantedAccess: 00000804 (Inherit)

002c: Object: ffff8c08d81c6bb0  GrantedAccess: 00000804

0030: Object: ffffa00a484f2560  GrantedAccess: 00000003 (Protected) (Inherit)

0034: Object: ffff8c08d82241f0  GrantedAccess: 001f0003 (Audit)

0038: Object: ffff8c08d7aeba60  GrantedAccess: 001f0003 (Protected) (Inherit)

003c: Object: ffff8c08d5b034b0  GrantedAccess: 00100020

0040: Object: ffff8c08d9b79e30  GrantedAccess: 0012019f

0044: Object: ffff8c08d8d678e0  GrantedAccess: 0012019f (Protected) (Inherit)

0048: Object: ffff8c08dfe92a10  GrantedAccess: 001f0001 (Inherit) (Audit)

004c: Object: ffff8c08d50d9ef0  GrantedAccess: 0012019f (Audit)

0050: Object: ffff8c08d82243b0  GrantedAccess: 0012019f

0054: Object: ffff8c08d82243b0  GrantedAccess: 0012019f

0058: Object: ffff8c08d7fcd1f0  GrantedAccess: 00000804 (Audit)

005c: Object: ffff8c08d477f070  GrantedAccess: 00000804 (Audit)

0060: Object: ffff8c08d7692080  GrantedAccess: 001f0003 (Protected) (Audit)

0064: Object: ffff8c08d5fef8a0  GrantedAccess: 000f00ff (Protected) (Inherit) (Audit)

0068: Object: ffff8c08d56f6470  GrantedAccess: 00100002 (Audit)

006c: Object: ffff8c08dbcbcbb0  GrantedAccess: 00000001

0070: Object: ffff8c08d3aa7b00  GrantedAccess: 00100002 (Protected) (Audit)

0074: Object: ffff8c08da19e7a0  GrantedAccess: 00000001 (Protected) (Inherit) (Audit)

0078: Object: ffffa00a651f3b20  GrantedAccess: 00020019 (Protected) (Inherit) (Audit)

007c: Object: ffff8c08db568700  GrantedAccess: 001fffff (Protected) (Audit)

0088: Object: ffffa00a5f9292a0  GrantedAccess: 000f003f (Protected) (Inherit) (Audit)

008c: Object: ffffa00a555e3780  GrantedAccess: 000f003f (Protected) (Audit)

0090: Object: ffffa00a62d1cf70  GrantedAccess: 00020019 (Audit)

0094: Object: ffffa00a5b95f760  GrantedAccess: 00020019 (Protected) (Inherit)

0098: Object: ffffa00a6f835950  GrantedAccess: 00020019 (Inherit)

009c: Object: ffff8c08d5ca9070  GrantedAccess: 00000804 (Audit)

00a0: Object: ffffa00a627c16c0  GrantedAccess: 00000001 (Protected)

00a4: Object: ffffa00a59d39880  GrantedAccess: 00020019 (Protected) (Audit)

00a8: Object: ffff8c08dba217c0  GrantedAccess: 00120089 (Protected)

也就是要手工实现/分析出这个命令的效果。
有时候仅仅这一个命令就够了,但是有时候,需要更详细的分析,会有更多/更深的用途。


--------------------------------------------------------------------------------------------------
先熟悉两个结构的信息:


nt!_HANDLE_TABLE
   +0x000 NextHandleNeedingPool : Uint4B
   +0x004 ExtraInfoPages   : Int4B
   +0x008 TableCode        : Uint8B
   +0x010 QuotaProcess     : Ptr64 _EPROCESS
   +0x018 HandleTableList  : _LIST_ENTRY
   +0x028 UniqueProcessId  : Uint4B
   +0x02c Flags            : Uint4B
   +0x02c StrictFIFO       : Pos 0, 1 Bit
   +0x02c EnableHandleExceptions : Pos 1, 1 Bit
   +0x02c Rundown          : Pos 2, 1 Bit
   +0x02c Duplicated       : Pos 3, 1 Bit
   +0x02c RaiseUMExceptionOnInvalidHandleClose : Pos 4, 1 Bit
   +0x030 HandleContentionEvent : _EX_PUSH_LOCK
   +0x038 HandleTableLock  : _EX_PUSH_LOCK
   +0x040 FreeLists        : [1] _HANDLE_TABLE_FREE_LIST
   +0x040 ActualEntry      : [32] UChar
   +0x060 DebugInfo        : Ptr64 _HANDLE_TRACE_DEBUG_INFO

0: kd> dt nt!_object_header
   +0x000 PointerCount     : Int8B
   +0x008 HandleCount      : Int8B
   +0x008 NextToFree       : Ptr64 Void
   +0x010 Lock             : _EX_PUSH_LOCK
   +0x018 TypeIndex        : UChar
   +0x019 TraceFlags       : UChar
   +0x019 DbgRefTrace      : Pos 0, 1 Bit
   +0x019 DbgTracePermanent : Pos 1, 1 Bit
   +0x01a InfoMask         : UChar
   +0x01b Flags            : UChar
   +0x01b NewObject        : Pos 0, 1 Bit
   +0x01b KernelObject     : Pos 1, 1 Bit
   +0x01b KernelOnlyAccess : Pos 2, 1 Bit
   +0x01b ExclusiveObject  : Pos 3, 1 Bit
   +0x01b PermanentObject  : Pos 4, 1 Bit
   +0x01b DefaultSecurityQuota : Pos 5, 1 Bit
   +0x01b SingleHandleEntry : Pos 6, 1 Bit
   +0x01b DeletedInline    : Pos 7, 1 Bit
   +0x01c Reserved         : Uint4B
   +0x020 ObjectCreateInfo : Ptr64 _OBJECT_CREATE_INFORMATION
   +0x020 QuotaBlockCharged : Ptr64 Void
   +0x028 SecurityDescriptor : Ptr64 Void
   +0x030 Body             : _QUAD
0: kd> ?? sizeof(nt!_object_header)
unsigned int64 0x38

因为nt!_object_header包含Body成员信息,所以nt!_object_header的大小为0x030。

0: kd> ?? sizeof(nt!_HANDLE_TABLE_ENTRY)
unsigned int64 0x10

注意:以上结构,你应该能看到位成员的信息,如果又联合还应看到联合成员的信息。


--------------------------------------------------------------------------------------------------


注意:_HANDLE_TABLE的TableCode的信息实际是PHANDLE_TABLE_ENTRY,而且最低的几位是几维数组的标志。
这里是0,说明这就是HANDLE_TABLE_ENTRY的数组的第一个元素。
不过第一个元素始终为空,见各种书籍的说明。
之所以这样设计是因为句柄为0的是无效的吧!

_HANDLE_TABLE的TableCode的信息实际是PHANDLE_TABLE_ENTRY,这句话的证据的是:见ExpAllocateHandleTable的函数。

0: kd> dq 0xffffa00a`591d4000
ffffa00a`591d4000  00000000`00000000 00000000`00000000
ffffa00a`591d4010  8c08d791`1fb0fffb 00000000`001f0003
ffffa00a`591d4020  8c08d9a8`b4a0fffd 00000000`00000001
ffffa00a`591d4030  8c08d4ae`06d0fff7 00000000`001f0003
ffffa00a`591d4040  8c08de98`3630fff9 00000000`000f00ff
ffffa00a`591d4050  8c08d509`e400fffd 00000000`00100002
ffffa00a`591d4060  8c08d65c`3230fffd 00000000`00000001
ffffa00a`591d4070  8c08d635`3f00fffd 00000000`00100002
注意:这个到底有多少个有效的呢?
WIN7的_HANDLE_TABLE有个成员叫HandleCount,但是win10没有。
其实dq的命令的地址的后面加个参数,就是显示的长度,尽量长些,但是不超过NextHandleNeedingPool。
可以发现,dq的第一个64位的值位0就是为空,就是无效的句柄。

注意:
1.句柄是按照数组的位置来计算的,具体的算法相信你应该领会,但是还是看WRK的代码为好。
2.句柄不一定是连续的,只要第一个64位不为空,就是有效的句柄,数组的大小不超过NextHandleNeedingPool。

从这里也能看到一些信息,如准许的权限等。
注意第一个是空的。


0: kd> dt nt!_HANDLE_TABLE_ENTRY ffffa00a`591d4010
   +0x000 VolatileLowValue : 0n-8356192090284032005
   +0x000 LowValue         : 0n-8356192090284032005
   +0x000 InfoTable        : 0x8c08d791`1fb0fffb _HANDLE_TABLE_ENTRY_INFO
   +0x008 HighValue        : 0n2031619
   +0x008 NextFreeHandleEntry : 0x00000000`001f0003 _HANDLE_TABLE_ENTRY
   +0x008 LeafHandleValue  : _EXHANDLE
   +0x000 RefCountField    : 0n-8356192090284032005
   +0x000 Unlocked         : 0y1
   +0x000 RefCnt           : 0y0111111111111101 (0x7ffd)
   +0x000 Attributes       : 0y000
   +0x000 ObjectPointerBits : 0y10001100000010001101011110010001000111111011 (0x8c08d7911fb)
   +0x008 GrantedAccessBits : 0y0000111110000000000000011 (0x1f0003)
   +0x008 NoRightsUpgrade  : 0y0
   +0x008 Spare1           : 0y000000 (0)
   +0x00c Spare2           : 0
0: kd> dt nt!_HANDLE_TABLE_ENTRY_INFO
   +0x000 AuditMask        : Uint4B
   +0x004 MaxRelativeAccessMask : Uint4B
0: kd> dt nt!_EXHANDLE
   +0x000 TagBits          : Pos 0, 2 Bits
   +0x000 Index            : Pos 2, 30 Bits
   +0x000 GenericHandleOverlay : Ptr64 Void
   +0x000 Value            : Uint8B

注意:
  0x8c08d7911fb
ffff8c08d7911fe0 
最后一个补0,高位补f,还差0x30

0: kd> !object ffff8c08d7911fe0 
Object: ffff8c08d7911fe0  Type: (ffff8c08d32ecdb0) Event
    ObjectHeader: ffff8c08d7911fb0 (new version)
    HandleCount: 1  PointerCount: 32768


0: kd> dt nt!_HANDLE_TABLE_ENTRY ffffa00a`591d4020
   +0x000 VolatileLowValue : 0n-8356189789977772035
   +0x000 LowValue         : 0n-8356189789977772035
   +0x000 InfoTable        : 0x8c08d9a8`b4a0fffd _HANDLE_TABLE_ENTRY_INFO
   +0x008 HighValue        : 0n1
   +0x008 NextFreeHandleEntry : 0x00000000`00000001 _HANDLE_TABLE_ENTRY
   +0x008 LeafHandleValue  : _EXHANDLE
   +0x000 RefCountField    : 0n-8356189789977772035
   +0x000 Unlocked         : 0y1
   +0x000 RefCnt           : 0y0111111111111110 (0x7ffe)
   +0x000 Attributes       : 0y000
   +0x000 ObjectPointerBits : 0y10001100000010001101100110101000101101001010 (0x8c08d9a8b4a)
   +0x008 GrantedAccessBits : 0y0000000000000000000000001 (0x1)
   +0x008 NoRightsUpgrade  : 0y0
   +0x008 Spare1           : 0y000000 (0)
   +0x00c Spare2           : 0



0: kd> dt nt!_HANDLE_TABLE_ENTRY
   +0x000 VolatileLowValue : Int8B
   +0x000 LowValue         : Int8B
   +0x000 InfoTable        : Ptr64 _HANDLE_TABLE_ENTRY_INFO
   +0x008 HighValue        : Int8B
   +0x008 NextFreeHandleEntry : Ptr64 _HANDLE_TABLE_ENTRY
   +0x008 LeafHandleValue  : _EXHANDLE
   +0x000 RefCountField    : Int8B
   +0x000 Unlocked         : Pos 0, 1 Bit
   +0x000 RefCnt           : Pos 1, 16 Bits
   +0x000 Attributes       : Pos 17, 3 Bits
   +0x000 ObjectPointerBits : Pos 20, 44 Bits
   +0x008 GrantedAccessBits : Pos 0, 25 Bits
   +0x008 NoRightsUpgrade  : Pos 25, 1 Bit
   +0x008 Spare1           : Pos 26, 6 Bits
   +0x00c Spare2           : Uint4B
注意:位和联合的定义。


--------------------------------------------------------------------------------------------------


注意:WRK还顶一个系统进程的句柄表,可以说是内核的全局的句柄表,专用于内核的句柄的。
0: kd> x nt!ObpKernelHandleTable
fffff803`7b780ce0 nt!ObpKernelHandleTable = <no type information>


made by correy
made at 10:36 2018/3/8
http://correy.webs.com

没有评论:

发表评论