在内核转储中解释Section对象

我试图追查与3Party应用程序的问题。 当前正在调查的path是查看在每个进程中创build的Section对象: rpsPdf10.mutex

如果对象的名称是它的用途的任何迹象,我不知道他们为什么select一个Section对象,并将其用作互斥量,但这可能在很大程度上不相关。

使用LiveKd我已经发出以下命令试图获取Section对象的详细信息

0: kd>!process 0 0 3thParty.exe ... PROCESS fffffa800ea80060 SessionId: 0 Cid: 0a00 Peb: fffdf000 ParentCid: 014c DirBase: 99349000 ObjectTable: fffff8a004448bf0 HandleCount: 338. Image: 3thParty.exe ... 0: kd> !handle 0 7 fffffa800ea80060 ... 08 fffff8a012e26710 Section rpsPdf10.mutex ... 0: kd> !object fffff8a012e26710 Object: fffff8a012e26710 Type: (fffffa800cd7cea0) Section ObjectHeader: fffff8a012e266e0 (new version) HandleCount: 38 PointerCount: 39 Directory Object: fffff8a00a980080 Name: rpsPdf10.mutex 0: kd> dt nt!_FILE_OBJECT fffff8a012e26710 +0x000 Type : 0n256 +0x002 Size : 0n0 +0x008 DeviceObject : 0x000000000008dfb0 _DEVICE_OBJECT +0x010 Vpb : 0xfffffa80c0000001 _VPB +0x018 FsContext : (null) +0x020 FsContext2 : 0xfffffa8000000034 Void +0x028 SectionObjectPointer : 0xfffff8a0102d7820 _SECTION_OBJECT_POINTERS +0x030 PrivateCacheMap : 0x0000000000001000 Void +0x038 FinalStatus : 0n73728 +0x040 RelatedFileObject : 0x63536153030a040c _FILE_OBJECT +0x048 LockOperation : 0x74 't' +0x049 DeletePending : 0 '' +0x04a ReadAccess : 0x65 'e' +0x04b WriteAccess : 0 '' +0x04c DeleteAccess : 0x73 's' +0x04d SharedRead : 0 '' +0x04e SharedWrite : 0x74 't' 

输出中的string't' 'e' 's' 't'肯定会突出显示

  • 要么我走错了路 – > 对布拉布,这是肯定的。 这不是一个文件对象,但问题仍然是如何find更多有关Section对象的信息。 它仍然是好奇和/或一个相当不幸的巧合,遵循部分和控制区指针我从文件对象信息派生似乎是正确的?!

  • 或者Section对象有问题

  • 要么 … ?

tldr;

在上面的_FILE_OBJECT结构的_FILE_OBJECT之后,我到达

  • NumberOfMappedViews 0x26 (= HandleCount:38)
  • NumberOfUserReferences 0x27 (= PointerCount:39)

所以现在我认为我所遵循的道路是正确的。

 0: kd> dt nt!_SECTION_OBJECT_POINTERS 0xfffff8a0102d7820 +0x000 DataSectionObject : 0xfffffa800fbed900 Void +0x008 SharedCacheMap : 0x0008000000000001 Void +0x010 ImageSectionObject : 0x0000000000000001 Void 0: kd> dt nt!_CONTROL_AREA 0xfffffa800fbed900 +0x000 Segment : 0xfffff8a0102d7820 _SEGMENT +0x008 DereferenceList : _LIST_ENTRY [ 0x0000000000000000 - 0x0000000000000000 ] +0x018 NumberOfSectionReferences : 1 +0x020 NumberOfPfnReferences : 0 +0x028 NumberOfMappedViews : 0x26 +0x030 NumberOfUserReferences : 0x27 

编辑

对象头看起来像这样

  0: kd> dt nt!_OBJECT_HEADER fffff8a012e266e0 +0x000 PointerCount : 0n39 +0x008 HandleCount : 0n38 +0x008 NextToFree : 0x00000000`00000026 Void +0x010 Lock : _EX_PUSH_LOCK +0x018 TypeIndex : 0x21 '!' +0x019 TraceFlags : 0 '' +0x01a InfoMask : 0xa '' +0x01b Flags : 0 '' +0x020 ObjectCreateInfo : 0xfffffa80`0e505140 _OBJECT_CREATE_INFORMATION +0x020 QuotaBlockCharged : 0xfffffa80`0e505140 Void +0x028 SecurityDescriptor : 0xfffff8a0`1ba076a8 Void +0x030 Body : _QUAD 

编辑2

以下@ blabb的答案调整架构

 0: kd> ? @$proc Evaluate expression: -6047068061600 = fffffa80`0ea80060 0: kd> dx (char *)@$proc->ImageFileName (char *)@$proc->ImageFileName : 0xfffffa800ea80340 : [Type: char *] : "3thParty.exe" 0: kd> !handle 0 0 @$proc section ... 0474: Object: fffff8a012e26710 GrantedAccess: 000f0007 ... 0: kd> !object fffff8a012e26710 Object: fffff8a012e26710 Type: (fffffa800cd7cea0) Section ObjectHeader: fffff8a012e266e0 (new version) HandleCount: 38 PointerCount: 39 Directory Object: fffff8a00a980080 Name: rpsPdf10.mutex 0: kd> ?? (unsigned long) (#FIELD_OFFSET(nt!_OBJECT_HEADER, Body)) unsigned long 0x30 0: kd> dt nt!_object_header 0xfffff8a012e26710-0x30 +0x000 PointerCount : 0n39 +0x008 HandleCount : 0n38 +0x008 NextToFree : 0x00000000`00000026 Void +0x010 Lock : _EX_PUSH_LOCK +0x018 TypeIndex : 0x21 '!' +0x019 TraceFlags : 0 '' +0x01a InfoMask : 0xa '' +0x01b Flags : 0 '' +0x020 ObjectCreateInfo : 0xfffffa80`0e505140 _OBJECT_CREATE_INFORMATION +0x020 QuotaBlockCharged : 0xfffffa80`0e505140 Void +0x028 SecurityDescriptor : 0xfffff8a0`1ba076a8 Void +0x030 Body : _QUAD 0: kd> x nt!ObTypeIndexTable fffff800`01a70c00 nt!ObTypeIndexTable = <no type information> 0: kd> dt -r1 nt!_SECTION_OBJECT 0xfffff8a012e26710 +0x000 StartingVa : 0x00000022`00000100 Void +0x008 EndingVa : 0x00000000`0008dfb0 Void +0x010 Parent : 0xfffffa80`c0000001 Void +0x018 LeftChild : (null) +0x020 RightChild : 0xfffffa80`00000034 Void +0x028 Segment : 0xfffff8a0`102d7820 _SEGMENT_OBJECT +0x000 BaseAddress : 0xfffffa80`0fbed900 Void +0x008 TotalNumberOfPtes : 1 +0x010 SizeOfSegment : _LARGE_INTEGER 0x1 +0x018 NonExtendedPtes : 0x1000 +0x01c ImageCommitment : 0 +0x020 ControlArea : (null) +0x028 Subsection : (null) +0x030 MmSectionFlags : 0xfffffa80`10987b10 _MMSECTION_FLAGS +0x038 MmSubSectionFlags : 0x00000000`03400000 _MMSUBSECTION_FLAGS 0: kd> dc 0xfffff8a012e26710-0x30-0x50 fffff8a0`12e26690 030c0408 f4636553 0e1a02e0 fffffa80 ....Sec......... fffff8a0`12e266a0 00000048 000000b8 0000001c fffffa80 H............... fffff8a0`12e266b0 0e505140 fffffa80 00000000 00000000 @QP............. fffff8a0`12e266c0 0a980080 fffff8a0 001c001c 00000000 ................ fffff8a0`12e266d0 10eb8770 fffff8a0 00000000 00000008 p............... fffff8a0`12e266e0 00000027 00000000 00000026 00000000 '.......&....... fffff8a0`12e266f0 00000000 00000000 000a0021 fffff8a0 ........!....... fffff8a0`12e26700 0e505140 fffffa80 1ba076a8 fffff8a0 @QP......v...... 0: kd> !pool 0xfffff8a012e26710-0x30-0x50 2 Pool page fffff8a012e26690 region is Paged pool *fffff8a012e26690 size: c0 previous size: 80 (Allocated) *Sect (Protected) Pooltag Sect : Section objects 

这是一个运行Windows 7的32位机器
使用的命令是架构不可知的,但是指针算术是依赖于曲线的

当前进程

 kd> ? @$proc Evaluate expression: -2061895528 = 8519f898 

进程名称从EPROCESS-> ImageFileName

 kd> dx (char *)@$proc->ImageFileName (char *)@$proc->ImageFileName : 0xffffffff8519fa04 : "windbg.exe" [Type: char *] 

让我们在这个过程中搜索某些部分句柄
TypeName是CaseSensitive

 kd> !handle 0 3 @$proc Section Searching for handles of type Section PROCESS 8519f898 SessionId: 1 Cid: 0138 Peb: 7ffd8000 ParentCid: 0d04 DirBase: 7e257560 ObjectTable: b91a3520 HandleCount: 254. Image: windbg.exe Handle table at b91a3520 with 254 entries in use 00c0: Object: 9a10bc58 GrantedAccess: 00000004 Entry: 9945b180 Object: 9a10bc58 Type: (84eb6040) Section ObjectHeader: 9a10bc40 (new version) HandleCount: 6 PointerCount: 6 

!handle 0 3 flag转储可以使用!对象{对象地址}重新验证的对象特定信息

 kd> !object 9a10bc58 Object: 9a10bc58 Type: (84eb6040) Section ObjectHeader: 9a10bc40 (new version) HandleCount: 6 PointerCount: 6 

每个对象都有一个32位的对象头,在对象地址之前有18个字节,它是sizeof(nt!_OBJECT_HEADER- sizeof(obheader-> Body))body作为最后一个成员被嵌入在HEADER中,

 kd> ?? (unsigned long ) (#FIELD_OFFSET(nt!_OBJECT_HEADER , Body)) unsigned long 0x18 

_OBJECT_HEADER如下(尽管大小没有改变,新版本的头文件和旧版本的头文件之间有区别)

 kd> dt nt!_object_header 9a10bc58-0x18 +0x000 PointerCount : 0n6 +0x004 HandleCount : 0n6 +0x004 NextToFree : 0x00000006 Void +0x008 Lock : _EX_PUSH_LOCK +0x00c TypeIndex : 0x21 '!' +0x00d TraceFlags : 0 '' +0x00e InfoMask : 0x8 '' +0x00f Flags : 0 '' +0x010 ObjectCreateInfo : 0x82f7aa00 _OBJECT_CREATE_INFORMATION +0x010 QuotaBlockCharged : 0x82f7aa00 Void +0x014 SecurityDescriptor : (null) +0x018 Body : _QUAD 

旧版本头文件直接在头文件中有_OBJECT_TYPE,新版本是一个数组的索引

这里的类型索引是0x21

Type的数组是at

 kd> x nt!ObTypeIndexTable 82f88580 nt!ObTypeIndexTable = <no type information> 

你可以写这样的脚本来转储所有的类型

 function log(instr) { host.diagnostics.debugLog(instr + "\n"); } function exec (cmdstr) { return host.namespace.Debugger.Utility.Control.ExecuteCommand(cmdstr); } function dumptypeindex() { var cpob = host.createPointerObject var titab = exec("x nt!ObTypeIndexTable").First().substr(0,8) var obtype = cpob(host.parseInt64(titab , 16),"nt","_OBJECT_TYPE **") var i = 2 while(obtype[i] !=0 ) { log("index = "+i+"\t"+ host.memory.readWideString(obtype[i].Name.Buffer)) i++ } } 

执行这个脚本会产生如下的类型

 kd> .scriptload c:\wdscr\dumptypeindex.js JavaScript script successfully loaded from 'c:\dumptypeindex.js' kd> dx @$scriptContents.dumptypeindex() index = 2 Type index = 3 Directory index = 4 SymbolicLink index = 5 Token index = 6 Job index = 7 Process index = 8 Thread index = 9 UserApcReserve index = 10 IoCompletionReserve index = 11 DebugObject index = 12 Event index = 13 EventPair index = 14 Mutant index = 15 Callback index = 16 Semaphore index = 17 Timer index = 18 Profile index = 19 KeyedEvent index = 20 WindowStation index = 21 Desktop index = 22 TpWorkerFactory index = 23 Adapter index = 24 Controller index = 25 Device index = 26 Driver index = 27 IoCompletion index = 28 File index = 29 TmTm index = 30 TmTxȂ؃扏楄index = 31 TmRm index = 32 TmEn index = 33 Section index = 34 Session index = 35 Key index = 36 ALPC Port index = 37 PowerRequest index = 38 WmiGuid index = 39 EtwRegistration index = 40 EtwConsumer index = 41 FilterConnectionPort index = 42 FilterCommunicationPort index = 43 PcwObject 

注意0x21 = 0n33 = Section

因为我们有一个部分

我们可以转储Section对象

 kd> dt -r1 nt!_SECTION_OBJECT 9a10bc58 +0x000 StartingVa : 0x90f87b44 Void +0x004 EndingVa : 0x82efb58a Void +0x008 Parent : 0xc0802000 Void +0x00c LeftChild : (null) +0x010 RightChild : 0xc0c0a280 Void +0x014 Segment : 0x995ed8d8 _SEGMENT_OBJECT +0x000 BaseAddress : 0x86b65740 Void +0x004 TotalNumberOfPtes : 0xdf +0x008 SizeOfSegment : _LARGE_INTEGER 0x000000df`00080000 +0x010 NonExtendedPtes : 0xdf000 +0x014 ImageCommitment : 0 +0x018 ControlArea : (null) +0x01c Subsection : (null) +0x020 MmSectionFlags : 0x869f52a8 _MMSECTION_FLAGS +0x024 MmSubSectionFlags : 0x02ea0000 _MMSUBSECTION_FLAGS 

一个对象的前面是pool_header之前的对象头

 kd> dc 9a10bc58-0x18-0x18 9a10bc28 060b0204 f4636553 00000720 00000070 ....Sec. ...p... 9a10bc38 00000000 00000000 00000006 00000006 ................ 9a10bc48 00000000 00080021 82f7aa00 00000000 ....!........... 9a10bc58 90f87b44 82efb58a c0802000 00000000 D{....... ...... 9a10bc68 c0c0a280 995ed8d8 000df000 00000000 ......^......... 9a10bc78 00012000 00000004 0670020b 6666744e . ........p.Ntff 9a10bc88 00f00702 00000a48 0000c0fe 00020000 ....H........... 9a10bc98 00000000 00000002 00000000 00000000 ................ 

注意Sec标签Sect被SectionObjects使用

 d> !pool 9a10bc58-0x18-0x18 2 Pool page 9a10bc28 region is Paged pool *9a10bc28 size: 58 previous size: 20 (Allocated) *Sect (Protected) Pooltag Sect : Section objects