Interpreting Section object in kernel dump

0

I'm trying to track down issues with a 3thParty application. The path currently being investigated is to look into a Section object that get's created in each process: rpsPdf10.mutex.

If the name of the object is any indication for it's intended usage, I'm not sure why they choose a Section object and use it as a Mutex but that's likely largely irrelevant.

Using LiveKd I've issued following command's trying to get detailed info of the Section object

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'

The string 't' 'e' 's' 't' in the output definitely sticks out so

  • either I'm following a wrong path -> tx to Blabb, this is certain. It's not a fileobject but the question remains how to find out more information about the Section object. It's still curious and/or a rather unfortunate coincidence that following the section and control area pointers I derived from the fileobject info do seem correct?!

  • or there's something wrong with the Section object

  • or ... ?

tldr;

Following the _SECTION_OBJECT_POINTERS of the _FILE_OBJECT structure above, I arrive at a

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

so for the moment I assume the path I've followed is correct.

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

Edit

The object header looks like this

   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

Edit 2

following @blabb's answer adjusting for architecture

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
kernel
windbg
shared-memory
asked on Stack Overflow Oct 13, 2017 by Lieven Keersmaekers • edited Oct 14, 2017 by Lieven Keersmaekers

1 Answer

1

This is a 32 bit machine running windows 7
Commands used are architecture agnostic but pointer arithmetic are arch dependent

Current process

kd> ? @$proc

Evaluate expression: -2061895528 = 8519f898

Process Name From EPROCESS->ImageFileName

kd> dx  (char *)@$proc->ImageFileName

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

lets Search For Some Section Handles in this process
the TypeName is 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 dumps object specific information which can be reverified using !object {object address}

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

each object has an objectheader in 32 bit it is 18 bytes prior to object address that is sizeof(nt!_OBJECT_HEADER- sizeof(obheader->Body)) body is embedded in HEADER as the last member and is variable sized

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

_OBJECT_HEADER is as follows (though sizes haven't changed there are differences between new version header and old version 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

the old version header had _OBJECT_TYPE directly in the header the new version is an index into an array

here the type index is 0x21

the array of Type is at

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

you can write a script like this to dump all the types

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++
    }
}

executing this script would yield the types as follows

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

notice 0x21 = 0n33 = Section

given that we have a Section

we can dump the Section Object

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

an object is preceded by object header which is preceded by the 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  ................

notice the Sec tag Sect is used by 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
answered on Stack Overflow Oct 13, 2017 by blabb

User contributions licensed under CC BY-SA 3.0