winlogon iirc 分配more than 9 RWX页面,但在9 pages创建转储之前不会仅释放这些页面
你在转储中观察这些页面,因为转储是过早的死亡
如果您在关闭/注销路径中等待足够长,您可能会捕获 VirtualFree() 的
我已经在您链接的上一篇文章中发布了几乎所有这些页面都包含使用 pushf pushad 序列保存标志和寄存器并通过 jmp eax 跳转到某个地址的代码
下面是一个实时堆栈,其中从 RWX 页面执行代码(当您创建转储时,此页面将被释放将不可用)
在您的设置中找出地址的一种方法可能是搜索转储中显示的特定内容DWORD!vad 在 winlogon 内存中输出一个 RWX 页面,其示例也粘贴在下面
kd> kb
ChildEBP RetAddr Args to Child
01e8f8b8 01010cf0 00000000 000080fd 00004000 winlogon!RmvpOpenNtDeviceFromWin32Path+0x23b
01e8f904 01010bd8 000002a4 000002a4 00000000 winlogon!RmvpOpenNtDeviceFromWin32Path+0x1ea
01e8f91c 0100e477 000002a4 000002a4 00000000 winlogon!RmvpOpenNtDeviceFromWin32Path+0xd2
01e8fc04 01058b0a 00000001 01058c00 01e8fc4c winlogon!CheckForUserObjectUpdates+0xb3
01e8fc70 02f7179d 000002a4 01049efc 00000000 winlogon!AutoPtrBase<_SECURITY_DESCRIPTOR>::AutoPtrBase<_SECURITY_DESCRIPTOR>+0x20
WARNING: Frame IP not in any known module. Following frames may be wrong.
01e8fef8 7c92796d 000002a4 7c97e460 000cfb20 0x2f7179d
01e8ff40 7c9279ab 01049efc 000002a4 00000000 ntdll!RtlpWorkerCallout+0x70
01e8ff60 7c927a6d 00000000 000002a4 000cfb20 ntdll!RtlpExecuteWorkerRequest+0x1a
01e8ff74 7c927a44 7c927991 00000000 000002a4 ntdll!RtlpApcCallout+0x11
01e8ffb4 7c80b713 00000000 00000000 00000000 ntdll!RtlpWorkerThread+0x87
01e8ffec 00000000 7c910250 00000000 00000000 kernel32!BaseThreadStart+0x37
调用堆栈中的一页不在任何已知模块中,反汇编并查看
kd> ub 02f7179d
02f71789 0000 add byte ptr [eax],al
02f7178b 0000 add byte ptr [eax],al
02f7178d 0000 add byte ptr [eax],al
02f7178f 0000 add byte ptr [eax],al
02f71791 53 push ebx
02f71792 52 push edx
02f71793 e8f8ca09fe call winlogon!DeleteRasConnections+0x3c (0100e290)
02f71798 e8d78a0efe call winlogon!CreateAndHoldWPAGlobalMutex (0105a274)
kd> u 02f7179d
02f7179d 9c pushfd
02f7179e 60 pushad
02f7179f 56 push esi
02f717a0 57 push edi
02f717a1 6a08 push 8
02f717a3 e854cb09fe call winlogon!DeleteRasConnections+0xa8 (0100e2fc)
02f717a8 ffe0 jmp eax
02f717aa 90 nop
所以 winlogon!CreateAndHoldWPAGlobalMutex (0105a274) 正在我们的访问断点中断时从未知页面执行
kd> r
eax=968dab54 ebx=00010000 ecx=000080fd edx=0000ffff esi=00000000 edi=00010000
eip=01010d41 esp=01e8f8b0 ebp=01e8f8b8 iopl=0 nv up ei ng nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000282
winlogon!RmvpOpenNtDeviceFromWin32Path+0x23b:
001b:01010d41 c1f810 sar eax,10h <--- eip is +1 when hardware bp is hit
kd> ub @eip
winlogon!RmvpOpenNtDeviceFromWin32Path+0x21f:
01010d25 03c6 add eax,esi
01010d27 5e pop esi
01010d28 5d pop ebp
01010d29 c20800 ret 8
01010d2c a1042b0701 mov eax,dword ptr [winlogon!MMX_available+0x39c (01072b04)] < read access not hit
01010d31 69c0fd430300 imul eax,eax,343FDh
01010d37 05c39e2600 add eax,269EC3h
01010d3c a3042b0701 mov dword ptr [winlogon!MMX_available+0x39c (01072b04)],eax < we hit write access here match eax with data
并且 72b0c 还保存执行发生的页面地址 try !vad on winlogon 并确认它是否是 RWX 并搜索 winlogon 内存
kd> dd 01072b04 l4
01072b04 968dab54 00000002 02f70000 00000000
kd> !process 0 0 winlogon.exe
PROCESS 81167cf8 SessionId: 0 Cid: 0218 Peb: 7ffdf000 ParentCid: 0168
DirBase: 088f5000 ObjectTable: e14a0600 HandleCount: 185.
Image: winlogon.exe
kd> !grep -i -c "!vad @@c++(((nt!_EPROCESS *) 0x81167cf8)->VadRoot)" -e "execute_readwrite"
812287d8 ( 9) 2f70 2f73 4 Private EXECUTE_READWRITE
kd> dd 01072b04
01072b04 968dab54 00000002 02f70000 00000000
01072b14 00000000 00000000 00000000 00000000
01072b24 00000000 00000000 00000000 00000000
01072b34 00000000 00000000 00000000 00000000
01072b44 00000000 00000000 00000000 00000000
01072b54 00000000 00000000 00000000 00000000
01072b64 00000000 00000000 00000000 00000000
01072b74 00000000 00000000 00000000 00000000
kd> lm m winlo*
start end module name
01000000 01081000 winlogon (pdb symbols)
kd> s -d winlogon l?81000 02f70000
01072b0c 02f70000 00000000 00000000 00000000 ................
您可以在转储中搜索 rwx 页面地址而不是 72b0c,如果它显示为 68900,您将能够在 winlogon 地址空间中找到该地址的交叉引用
(windbg 命令#(搜索程序集模式)
kd> # 72b0c 1008000 l?11000
winlogon!CheckForUserObjectUpdates+0x49:
0100e40d 8b04c50c2b0701 mov eax,dword ptr winlogon!MMX_available+0x3a4 (01072b0c)[eax*8]
winlogon!MprLogonNotify+0xda:
01010812 8b04f50c2b0701 mov eax,dword ptr winlogon!MMX_available+0x3a4 (01072b0c)[esi*8]
winlogon!RmvpOpenNtDeviceFromWin32Path+0x157:
01010c5d 8934fd0c2b0701 mov dword ptr winlogon!MMX_available+0x3a4 (01072b0c)[edi*8],esi
最后一个是写位置,edi 包含计数
这是 xp sp3 中的 RWX VirtualAlloc 您应该也可以在 sp2 中找到类似的模式
01010CDC PUSH 40 ; /Protect = PAGE_EXECUTE_READWRITE
01010CDE PUSH 3000 ; |AllocationType = MEM_COMMIT|MEM_RESERVE
01010CE3 PUSH 4000 ; |Size = 4000 (16384.)
01010CE8 PUSH ESI ; |/Arg2 = FFFFFFFF
01010CE9 PUSH 0 ; ||Arg1 = 00000000
01010CEB CALL winlogon.01010D05; |\winlogon.01010D05
01010CF0 IMUL EAX, EBX ; |
01010CF3 ADD EAX, EDI ; |ntdll.7C910228
01010CF5 PUSH EAX ; |Address = NULL
01010CF6 CALL K32.VirtualAlloc]; \VirtualAlloc