【问题标题】:How to get the content of a Section object in a kernel dump如何在内核转储中获取 Section 对象的内容
【发布时间】:2018-03-26 12:54:30
【问题描述】:

来自 3thParty 供应商的部分对象被命名为 rpsPdf10.mutex,它的预期用途是通过向其写入布尔标志来模拟信号量。

使用 LiveKd 并在 SO 的大力帮助下,我发出了以下命令,试图获取此 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 -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

这一切对我来说都是正确的,但我怎样才能找到该部分的内容?

【问题讨论】:

    标签: windows kernel windbg shared-memory


    【解决方案1】:

    注意点,如earlier answer 机器是 32 位,操作系统是 win7,windbg 版本是内幕预览 16278 命令是拱不可知论者和指针算术(如果有的话是拱相关的)
    并且演练是在实时二进制文件上而不是在转储中,因为很有可能该页面可能已在转储中分页,并且演示可能不确定我稍后可能会添加到这个答案中

    获取内容表单部分有点复杂
    (有几种类型的部分,如
    1) ALPC 部分(com 对象)
    2) 文件支持部分
    3)PageFileBacked 部分等

    下面的演练适用于页面文件支持的部分(最常见的类型)

    假设您编译并执行了以下代码
    exe 将在全局命名空间中创建一个 SectionObject
    并且内容将由 PagingFile 支持并等待 按键

    #include <windows.h>
    #include <stdio.h>
    #define bsize 256
    int main(){
        char szMsg[]={"Message from blabb to lieven from Stack Overflow."};
        int ret = NULL;
        HANDLE hMap = CreateFileMapping((HANDLE)-1,NULL,4,0,bsize,"Global\\MyMap");
        if(hMap){
            PCHAR buff = (PCHAR) MapViewOfFile(hMap,0xf001f,0,0,bsize);
            if(buff){
                CopyMemory(buff, szMsg, sizeof(szMsg));
                ret = getchar();
                UnmapViewOfFile(buff);
            }
            CloseHandle(hMap);
        }
        return ret;
    }
    

    假设进程正在等待按键启动 livekd 或设置实时内核调试连接(如果它正在远程机器/vm 中运行)

    C:>livekd -k "c:\Program Files\Windows Kits\10\Debuggers\x86\cdb.exe"

    LiveKd v5.62 - Execute kd/windbg on a live system
    Launching c:\Program Files\Windows Kits\10\Debuggers\x86\cdb.exe:
    
    Microsoft (R) Windows Debugger Version 10.0.16278.1000 X86
    

    获取_EPROCESS并设置上下文

    kd> !process 0 0 secobj.exe
    
    PROCESS 8605ab28  SessionId: 1  Cid: 0fbc    Peb: 7ffd9000  ParentCid: 0af4
        DirBase: 7e2712e0  ObjectTable: c288ba00  HandleCount:   9.
        Image: secobj.exe
    
    kd> .process /p /r 8605ab28
    
    Implicit process is now 8605ab28
    
    kd> ? @$proc
    Evaluate expression: -2046448856 = 8605ab28
    
    kd> ?? (char *)@$proc->ImageFileName
    char * 0x8605ac94
     "secobj.exe"
    

    在当前进程通知中查找 Section 类型的句柄,因为我们的 部分在全局命名空间中命名,windbg 为我们解密

    kd> !handle 0 3 @$proc Section
    
    Searching for handles of type Section
    
    PROCESS 8605ab28  SessionId: 1  Cid: 0fbc    Peb: 7ffd9000  ParentCid: 0af4
        DirBase: 7e2712e0  ObjectTable: c288ba00  HandleCount:   9.
        Image: secobj.exe
    
    Handle table at c288ba00 with 9 entries in use
    
    0024: Object: c238e9c8  GrantedAccess: 000f0007 Entry: c37b7048
    Object: c238e9c8  Type: (84ec6040) Section
        ObjectHeader: c238e9b0 (new version)
            HandleCount: 1 PointerCount: 2
            Directory Object: 98a0f170  Name: MyMap
    

    转储 SectionObject

    kd> dt nt!_SECTION_OBJECT c238e9c8
       +0x000 StartingVa       : 0xc227e2c8 Void
       +0x004 EndingVa         : 0x00d3db6c Void
       +0x008 Parent           : 0xb0d3db20 Void
       +0x00c LeftChild        : (null)
       +0x010 RightChild       : 0x00000003 Void
       +0x014 Segment          : 0xc36aba20 _SEGMENT_OBJECT
    

    kd> $$ 注意 Last Segment 成员,它不是 SEGMENT_OBJECT 而是
    nt!_segment 或实际上是指向此部分的 ControlArea 的指针

    kd> dt nt!_SEGMENT 0xc36aba20
       +0x000 ControlArea      : 0x85182d08 _CONTROL_AREA
       +0x004 TotalNumberOfPtes : 1
       +0x008 SegmentFlags     : _SEGMENT_FLAGS
       +0x00c NumberOfCommittedPages : 1
       +0x010 SizeOfSegment    : 0x1000
       +0x018 ExtendInfo       : (null)
       +0x018 BasedAddress     : (null)
       +0x01c SegmentLock      : _EX_PUSH_LOCK
       +0x020 u1               : <unnamed-tag>
       +0x024 u2               : <unnamed-tag>
       +0x028 PrototypePte     : 0xc36aba50 _MMPTE
       +0x030 ThePtes          : [1] _MMPTE
    

    kd>$$你可以展开union u2并dump union的FirstMappedVa来查看这个Section的内容

    kd> dt nt!_SEGMENT u2.FirstMappedVa 0xc36aba20
       +0x024 u2               :
          +0x000 FirstMappedVa    : 0x000e0000 Void
    

    转储内容

    kd> da 0xe0000
    000e0000  "Message from blabb to lieven fro"
    000e0020  "m Stack Overflow."
    kd>
    

    或执行 !ca 以获取指向第一页的 FirstMappedVa
    如果内容大于一页边界,则获取它们是
    有点乏味,因为它们可能已被调出并需要执行 操作并因此处理页面错误以使它们进入视图

    kd> !ca poi(0xc36aba20)
    
    ControlArea  @ 85182d08
      Segment      c36aba20  Flink      00000000  Blink        00000000
      Section Ref         1  Pfn Ref           0  Mapped Views        1
      User Ref            2  WaitForDel        0  Flush Count         0
      File Object  00000000  ModWriteCount     0  System Views        0
      WritableRefs        0
      Flags (2000) Commit
    
          Pagefile-backed section
    
    Segment @ c36aba20
      ControlArea       85182d08  ExtendInfo    00000000
      Total Ptes               1
      Segment Size          1000  Committed            1
      CreatingProcess   8605ab28  FirstMappedVa    e0000 <-------------
      ProtoPtes         c36aba50
      Flags (80000) ProtectionMask
    
    Subsection 1 @ 85182d58
      ControlArea  85182d08  Starting Sector        0  Number Of Sectors    0
      Base Pte     c36aba50  Ptes In Subsect        1  Unused Ptes          0
      Flags               8  Sector Offset          0  Protection           4
    kd>
    

    【讨论】:

    • 收到消息 ;)。在阅读“几种类型的部分”后已经投票,并且应该可以多次投票......这对我来说是黄金!
    • 我很高兴知道这个答案很有帮助
    【解决方案2】:

    添加另一个答案以显示另一个页面文件支持的部分内容 您可能需要转到创建进程并查看其虚拟地址而不是当前进程

    你可能知道 shell 在共享部分保留了一些 global counters

    0104: Object: c2255450  GrantedAccess: 00000006 Entry: c5d9b208
    Object: c2255450  Type: (84ec6040) Section
        ObjectHeader: c2255438 (new version)
            HandleCount: 6 PointerCount: 7
            Directory Object: 9d662520  Name: windows_shell_global_counters 
    

    检索它们的代码

    #include <stdio.h>
    #include <windows.h>
    #include <stdlib.h>
    #include <shlwapi.h>
    #pragma comment(lib,"shlwapi.lib")
    
    //add all items in the ... place holder in arrays below
    PCHAR enuname[] = { "GLOBALCOUNTER_SEARCHMANAGER",...};
    int foo [] =  { GLOBALCOUNTER_SEARCHMANAGER,...};
    
    void main (void) {
        long cval = NULL;
        for(int i =0; i < _countof(foo) ;i++) {
            cval = SHGlobalCounterGetValue((SHGLOBALCOUNTER)foo[i]);
            printf ("%65s = %0x\n" ,enuname[i], cval);
        }
    }
    

    编译和执行这个你可能会得到这样的结果(记住计数器是不稳定的,所以你可能需要足够快的速度进行比较)

    C:\secobj\shglob>shglob.exe | head -n 13
                                          GLOBALCOUNTER_SEARCHMANAGER = 0
                                          GLOBALCOUNTER_SEARCHOPTIONS = 0
                                   GLOBALCOUNTER_FOLDERSETTINGSCHANGE = 0
                                                GLOBALCOUNTER_RATINGS = 0
                                          GLOBALCOUNTER_APPROVEDSITES = 0
                                           GLOBALCOUNTER_RESTRICTIONS = 5
                                   GLOBALCOUNTER_SHELLSETTINGSCHANGED = 2
                                       GLOBALCOUNTER_SYSTEMPIDLCHANGE = 0
                                         GLOBALCOUNTER_OVERLAYMANAGER = 0
                                      GLOBALCOUNTER_QUERYASSOCIATIONS = 0
                                             GLOBALCOUNTER_IESESSIONS = 0
                                        GLOBALCOUNTER_IEONLY_SESSIONS = 0
                               GLOBALCOUNTER_APPLICATION_DESTINATIONS = 83
    

    查看当前进程

    kd> ? @$proc
    Evaluate expression: -2033240552 = 86cf3618
    kd> ?? (char *)@$proc->ImageFileName
    char * 0x86cf3784
     "cdb.exe"
    kd> !handle 0 3 @$proc Section
    0164: Object: c2255450  GrantedAccess: 00000006 Entry: c3df32c8
    Object: c2255450  Type: (84ec6040) Section
        ObjectHeader: c2255438 (new version)
            HandleCount: 11 PointerCount: 12
            Directory Object: 9d662520  Name: windows_shell_global_counters
    
    kd> dc @@c++(((nt!_segment *)((nt!_section_object *) 0xc2255450)->Segment)->u2.FirstMappedVa)
    00290000  ???????? ???????? ???????? ????????  ????????????????
    00290010  ???????? ???????? ???????? ????????  ????????????????
    00290020  ???????? ???????? ???????? ????????  ????????????????
    00290030  ???????? ???????? ???????? ????????  ????????????????
    00290040  ???????? ???????? ???????? ????????  ????????????????
    00290050  ???????? ???????? ???????? ????????  ????????????????
    00290060  ???????? ???????? ???????? ????????  ????????????????
    00290070  ???????? ???????? ???????? ????????  ????????????????
    

    可能是当前进程使用 OpenFileMapping 获得了句柄,但尚未映射它,或者页面被分页(livekd 无法使用 pagein)无论我们似乎无法查看此部分内容

    让我们看看是谁创建了这个共享部分

    kd> ? @@c++(((nt!_segment *)((nt!_section_object *) 0xc2255450)->Segment)->u1.CreatingProcess)
    Evaluate expression: -2050635184 = 85c5ca50
    
    kd> !process 85c5ca50 0
    PROCESS 85c5ca50  SessionId: 1  Cid: 0af4    Peb: 7ffd9000  ParentCid: 0704
        DirBase: 7e271420  ObjectTable: c5d873c8  HandleCount: 888.
        Image: explorer.exe
    

    看起来逻辑 explorer.exe 似乎创建了这个共享部分

    让我们通过从创建进程的虚拟地址中转储 0n13 个双字来检查

    kd> .process /p /r 85c5ca50
    
    kd> dc @@c++(((nt!_segment *)((nt!_section_object *) 0xc2255450)->Segment)->u2.FirstMappedVa) l0n13
    00290000  00000000 00000000 00000000 00000000  ................
    00290010  00000000 00000005 00000002 00000000  ................
    00290020  00000000 00000000 00000000 00000000  ................
    00290030  00000083                             ....
    

    【讨论】:

      猜你喜欢
      • 2013-07-30
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多