来自3Party供应商的section对象被命名为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
所有这些对我来说都是正确的,但是我怎样才能find这个部分的内容呢?
需要注意的是在前面的答案机器是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> $$注意最后一个成员不是SEGMENT_OBJECT,而是
nt!_segment或者实际上是一个指向这个Section的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> $$,您可以展开联合u2并转储联合的FirstMappedVa以查看此部分的内容
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>
或者do!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>
添加另一个答案来显示另一个页面文件备份部分内容,您可能需要去创建过程并查看其虚拟地址,而不是当前进程
你可能知道shell将一些全局计数器保存在共享部分中
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 ....