注意点,如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>