【问题标题】:How to do hybrid user-mode/kernel-mode debugging?如何进行混合用户模式/内核模式调试?
【发布时间】:2017-08-04 05:29:33
【问题描述】:

基本上,我有一个调用 kernel32.CreateProcessA() 的用户模式程序,它在内部调用 kernel32.CreateProcessInternalW()。在这个函数中,我对 ntdll.NtCreateSection() 内部发生的事情感兴趣,它试图将可执行文件映射到虚拟内存中。进入该函数后,程序迅速将内核调用设置为 EAX=0x32 并执行 SYSENTER 指令。

显然,我无法在用户模式调试器中看到调用门之外的内容。我有一点调试内核模式驱动程序的经验,所以我在 VMWare 窗口中加载了一份 XP SP3 的副本,并使用 VirtualKD 将管道连接到 WinDbg(我恰好在 IDA 中运行)。连接内核调试器后,我将我的用户模式 ​​EXE 程序和 PDB 复制到虚拟机上,但我对如何在我的用户模式程序中正确设置初始断点有点茫然。我不想拦截对等效 ntdll.ZwCreateSection() 的所有调用,我认为它位于调用门的另一侧。理想情况下,由于我正在使用内核调试器,我想闯入用户模式代码并单步执行调用门,但我不知道第一步是什么。

我做了一些谷歌搜索,并通过在

中设置“ntsd -d”值接近了
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\myprocess.exe

当我启动我的进程时,这会导致内核调试器中断,但我似乎无法在需要向 IDA 发出 WinDbg 提示符的 .breakin 命令之后设置任何断点。我一直在关注这个guide,在那里我使用 !process 定位我的进程,然后切换到上下文,并重新加载符号,但是我在我的进程中设置断点或超过由“ntsd - 设置的初始断点”时遇到问题d"。在收到无法解析断点并添加了延迟断点的消息后,如果这有任何意义,我似乎无法在不清除断点的情况下“进入”进程。这是我在第一次休息时似乎所处的堆栈:

ChildEBP RetAddr  
b2b55ccc 8060e302 nt!RtlpBreakWithStatusInstruction
b2b55d44 8053d638 nt!NtSystemDebugControl+0x128
b2b55d44 7c90e4f4 nt!KiFastCallEntry+0xf8
0007b270 7c90de3c ntdll!KiFastSystemCallRet
0007b274 6d5f5ca6 ntdll!ZwSystemDebugControl+0xc
0007bd48 6d5f6102 dbgeng!DotCommand+0xd0d
0007de8c 6d5f7077 dbgeng!ProcessCommands+0x318
0007dec4 6d5bec6c dbgeng!ProcessCommandsAndCatch+0x1a
0007eedc 6d5bed4d dbgeng!Execute+0x113
0007ef0c 010052ce dbgeng!DebugClient::Execute+0x63
0007ff3c 010069fb ntsd!MainLoop+0x1ec
0007ff44 01006b31 ntsd!main+0x10e
0007ffc0 7c817067 ntsd!mainCRTStartup+0x125
0007fff0 00000000 kernel32!BaseProcessStart+0x23

说实话,我不确定我的 PDB 是否正在加载,但我怀疑这可能不是我的直接问题;我的模块窗格仅显示内核驱动程序模块,而不是用户模式模块。当我过去进行驱动程序调试时,我可以在此窗格中看到我的驱动程序映像以及符号是否已加载,因此我不确定用户模式映像会发生什么。 如果没有图像,我真的不能指望调试器解决任何断点。

我意识到我可能完全错了,但我没有任何运气来寻找如何进行用户模式/内核模式混合调试。有没有人可以为我指明正确的方向,以便我可以从特定的用户模式进程进入这个内核模式功能?或者,至少设置一个适当的内核模式断点,以便它仅作为我的特定用户模式进程的结果触发?

更新: 我在被调试操作系统的用户模式调试器中加载了我的模块(恰好被命名为 runlist.exe)(我碰巧使用了 OllyDbg)。一旦我在用户模式断点处暂停,只有来自 SYSENTER 的几条指令,我使用内核调试器暂停了操作系统。然后我设置流程上下文。 WinDbg 命令窗口内容如下:

WINDBG>!process 0 0 runlist.exe

PROCESS 820645a8  SessionId: 0  Cid: 01b4    Peb: 7ffd7000  ParentCid: 02b0
    DirBase: 089c02e0  ObjectTable: e1671bb0  HandleCount:   8.
    Image: runlist.exe

WINDBG>.process /i /r /p 820645a8
You need to continue execution (press 'g' <enter>) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.
WINDBG>g
This command cannot be passed to the WinDbg plugin directly, please use IDA Debugger menu to achieve the same result.
Break instruction exception - code 80000003 (first chance)
WINDBG>.reload /user
Loading User Symbols
....
Caching 'Modules'... ok
WINDBG>lmu
start    end        module name
00400000 00405000   runlist  C (no symbols)           
7c340000 7c396000   MSVCR71    (private pdb symbols)  g:\symcache\msvcr71.pdb\630C79175C1942C099C9BC4ED019C6092\msvcr71.pdb
7c800000 7c8f6000   kernel32   (pdb symbols)          e:\windows\symbols\dll\kernel32.pdb
7c900000 7c9af000   ntdll      (pdb symbols)          e:\windows\symbols\dll\ntdll.pdb
WINDBG>bp 0x7c90d16a
WINDBG>bl
 0 e 7c90d16a     0001 (0001) ntdll!ZwCreateSection+0xa

虽然我无法使用“.reload”加载我的进程符号(PDB 位于同一目录中 - 可能需要将其复制到我的符号目录),但我关心的断点无论如何都在 ntdll 中,所以我将其设置在调试器识别为在 ntdll.ZwCreateSection() 中的地址 0x7C90D16A 上。对我来说奇怪的是,在用户模式代码中,此地址解析为 ntdll.NtCreateSection(),但无论哪种方式,断点都只是我的用户模式中断处的 2 条指令。当我恢复机器时,我的意图是“运行”用户模式调试进程,这将触发内核模式断点 2 指令。内核断点从未被命中,并且应用程序在此点之后恢复。但是,我可以在 ntdll!ZwCreateSection() 上设置断点,但是当恢复操作系统时,断点会被其他进程反复命中,阻止我返回用户模式调试器,因此我只能将其“运行”到该位置我自己的过程。

更新 合并@conio 提供的提示,以下步骤对我有用:

1> 附加内核调试器并启动目标操作系统后,暂停操作系统并应用一些配置选项:

!gflag +ksl         //allow sxe to report user-mode module load events under kernel debugger
sxe ld myproc.exe   //cause kernel debugger break upon process load
.sympath+ <path>    //path to HOST machine's user-mode app's symbols

2> 运行调试器以恢复目标操作系统

3>在目标上,运行我们要调试的EXE

4> 内核调试器应该中断;现在输入以下命令切换到用户模式上下文:

!process 0 0 myproc.exe                 //get address of EProcess structure (first number on 1st line after "PROCESS")
.process /i /r /p <eprocess*>           //set kernel debugger to process context
g                                       //continue execution to allow the context switch; debugger will break after switch complete
.reload /user                           //reload user symbols
lmu                                     //ensure you have symbols although not really necessary in my particular case

5> 现在,因为我已经知道 ntdll.NtCreateSection() 的用户模式端发生了什么,所以我继续为该函数的内核模式端设置断点,但指定我希望断点仅在我的过程中发生。这样,断点不会在操作系统范围内触发:

bu /p <eprocess*> nt!NtCreateSection        //set breakpoint in kernel side of function
g                                           //run to break

6> 如果一切按计划进行,断点将在 NtCreateSection() 的内核模式端唤醒调试器。感谢所有回复和提示!

【问题讨论】:

  • 此处的链接已断开。
  • @RyanPrescott:链接是this吗?
  • 看起来不错,谢谢!

标签: windbg ida


【解决方案1】:

有两种方法可以将用户模式调试与内核模式调试结合起来,您会混淆并混淆它们。

您尝试的方式是使用内核模式调试器调试内核模式代码,使用用户模式调试器(ntsd)调试用户模式代码,并控制用户模式调试器运行在来自内核调试器的目标机器。这就是 -d 标志到 ntsd 的作用。此方法在 MSDN 上的Controlling the User-Mode Debugger from the Kernel Debugger 页面及其子页面中进行了描述。

这样做(或多或少)是将ntsd 的输入和输出重定向到内核调试器。模块窗格 - 与 WinDbg 中的其余窗口一样 - 属于内核调试器。您与用户模式调试器的唯一交互是通过内核调试器创建的隧道,您只能通过命令窗口访问它。这在-d 标志的文档中有记录:

-d

        将此调试器的控制权传递给内核调试器。如果您正在调试 CSRSS,则此控件重定向始终处于活动状态,即使未指定 -d 也是如此。 (此选项不能在远程调试期间使用 - 请改用 -ddefer。)有关详细信息,请参阅从内核调试器控制用户模式调试器。此选项不能与 -ddefer 选项或 -noio 选项一起使用。

        注意  如果您使用 WinDbg 作为内核调试器,WinDbg 的许多熟悉功能在这种情况下不可用。例如,您不能使用 Locals 窗口、反汇编窗口或 Call Stack 窗口,也不能单步执行源代码。这是因为 WinDbg 仅充当目标计算机上运行的调试器(NTSD 或 CDB)的查看器。

第二种方法,也就是您在链接中使用的方法,是使用内核调试器来调试内核模式代码和用户模式代码。没有用户模式调试器。没有ntsd。你说你遵循了指南,但实际上你没有。如果有,就不会有ntsd

我建议您使用此方法启动,并且仅在您发现需要时才使用用户模式调试器(例如,因为您想使用用户模式扩展)。

为了使内核调试器与用户模式模块一起工作,您必须启用Enable loading of kernel debugger symbols GlobalFlag。使用!gflag +ksl 来做到这一点。

一旦你这样做了,使用sxe ld:runlist中断你的进程的加载,设置断点(可能使用/p选项)并调试你想要的任何东西。

只需这样做,而不是所有 ntsd 混乱。

【讨论】:

  • 感谢您的澄清!特别是。 “sxe ld:”提示在模块加载时中断,允许我绕过目标上的用户模式调试器以及“ntsd -d”注册表设置。现在只有一件事我还无法弄清楚。我现在可以单步执行内核调试器中的用户模式代码,但我想单步执行 SYSENTER 或在内核模式的另一端在中断处理程序或中断处理程序调用的函数处设置断点发挥 NtCreateSection 的魔力。我似乎找不到这种技术的具体例子。
  • 你不能真正“进入”sysenter。最简单的做法是在相应的nt 函数上设置或启用断点。通常它们具有相同的名称。当你进入ntdll!NtCreateSection,做bu nt!NtCreateSection 然后去。您可以尝试将/p/t 选项与bu 一起使用,但请注意它们并不总是有效。
  • @conio ntsd -d 不是一团糟我编辑了我的帖子以展示如何做到这一点
  • @blabb:是的。与直接从内核调试器调试用户模式代码或像普通人一样使用远程调试(nstd -noio -remote可能使用-ddefer而不是-noio)和许多其他功能相比,它实际上没有任何优势的缺点。你的回答很糟糕,现在更糟。像往常一样,它的每个字符的信息比率非常低。请不要使用我答案的 cmets 部分来试图引起人们对您错误答案的注意。
【解决方案2】:

使用 ntsd -d 并使用 kd 连接从目标开始调试可执行文件 您可以将 kd 用作用户模式调试器以及内核调试器 多次阅读文档这并不容易,但经过多次试验,您应该了解它的窍门,了解 .breakin 等

How to break on the entry point of a program when debug in kernel mode with windbg?

编辑添加了使用 ntsd -d 的演示

设置

1 ) a vm running winxp sp3 and windbg version 6.12 installed in it    
2 ) _NT_SYMBOL_PATH in vm is set to z:\   
3 ) z:\ is a mapped network drive that points to e:\symbols in host   
4 ) host running win 7 sp2    
5 ) host windbg 10.0010586      

在ntsd下的vm中启动一个应用并重定向到kd

在vm中打开命令提示符导航到windbg安装目录并发出ntsd -s -d calc-s is to disable lazy symbol loading

0:000> version
version
Windows XP Version 2600 (Service Pack 3) UP Free x86 compatible
Product: WinNt, suite: SingleUserTS
kernel32.dll version: 5.1.2600.5512 (xpsp.080413-2111)
Machine Name:
Debug session time: Thu Mar 16 16:44:29.222 2017 
System Uptime: 0 days 0:10:12.941
Process Uptime: 0 days 0:01:40.980
  Kernel time: 0 days 0:00:01.632
  User time: 0 days 0:00:00.040
Live user mode: <Local>

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

command line: 'ntsd -s -d calc'  Debugger Process 0xA8 
dbgeng:  image 6.12.0002.633, built Tue Feb 02 01:38:31 2010
[path C:\Documents and Settings\admin\Desktop\Debugging Tools for Windows (x86)\dbgeng.dll]

windbg 在 SystemBreakPoint 上中断,调试提示符为 Input:\>
lm 显示符号是从 z:\

加载的
CommandLine: calc
Symbol search path is: z:\
Executable search path is: 
ModLoad: 01000000 0101f000   calc.exe
xxxxx
ntdll!DbgBreakPoint:
7c90120e cc              int     3
0:000> lm
lm
start    end        module name
01000000 0101f000   calc       (pdb symbols)          z:\calc.pdb\3B7D84101\calc.pdb
77c10000 77c68000   msvcrt     (export symbols)       C:\WINDOWS\system32\msvcrt.dll

执行到 AddressOfEntryPoint

0:000> g @$exentry
g @$exentry

calc!WinMainCRTStartup:
01012475 6a70            push    70h

同时在用户模式下设置断点并在内核模式下设置对应的断点

0:000> bp ntdll!ZwCreateSection  <--- user mode bp notice prompt 0:000
bp ntdll!ZwCreateSection


0:000> .breakin  <<---- transferring to kd mode 
.breakin
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
804e3592 cc              int     3


kd> !process 0 0 calc.exe   <<----- looking for our process of interest
Failed to get VAD root
PROCESS ffae2020  SessionId: 0  Cid: 0410    Peb: 7ffde000  ParentCid: 00a8
    DirBase: 04d87000  ObjectTable: e1bd5238  HandleCount:  26.
    Image: calc.exe

kd> bp /p ffae2020 nt!NtCreateSection  << setting a kernel mode bp    
on counterpart that matches with our process of interest notice prompt kd> 


kd> g  <<<---- return to user mode  after setting a breakpoint
0:000> g   <<<<<---------  executing in user mode 
g

现在 calc 进程正在 vm 中的用户模式下运行 单击关于的帮助(这将触发 Loadlib 并且需要一个 Section,因此我们将在内核调试器中中断我们的用户模式 ​​bp)

Breakpoint 0 hit
eax=00000000 ebx=00000000 ecx=00000001 edx=ffffffff esi=0007f368 edi=00000000
eip=7c90d160 esp=0007f22c ebp=0007f2a8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!NtCreateSection:
7c90d160 b832000000      mov     eax,32h

现在我们可以愉快地跟踪 use t trace 而不是 p 或 g 或任何其他执行命令

0:000> t
t
eax=00000032 ebx=00000000 ecx=00000001 edx=ffffffff esi=0007f368 edi=00000000
eip=7c90d165 esp=0007f22c ebp=0007f2a8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!ZwCreateSection+0x5:
7c90d165 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
0:000> 

eax=00000032 ebx=00000000 ecx=00000001 edx=7ffe0300 esi=0007f368 edi=00000000
eip=7c90d16a esp=0007f22c ebp=0007f2a8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!ZwCreateSection+0xa:
7c90d16a ff12    call dword ptr [edx] ds:0023:7ffe0300={ntdll!KiFastSystemCall (7c90e4f0)}
0:000> 

eax=00000032 ebx=00000000 ecx=00000001 edx=7ffe0300 esi=0007f368 edi=00000000
eip=7c90e4f0 esp=0007f228 ebp=0007f2a8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCall:
7c90e4f0 8bd4            mov     edx,esp
0:000> 

eax=00000032 ebx=00000000 ecx=00000001 edx=0007f228 esi=0007f368 edi=00000000
eip=7c90e4f2 esp=0007f228 ebp=0007f2a8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!KiFastSystemCall+0x2:
7c90e4f2 0f34            sysenter
0:000> 

Breakpoint 1 hit
nt!NtCreateSection:
805652b3 6a2c            push    2Ch

在内核的 bp 中 .reload 并查看堆栈跟踪

第二个堆栈跟踪与第一个相同,但带有更正的符号 Shell32.dll(vm没有互联网访问,所以它第一次失败 所以我从 vm 拖放了那个特定的 dll 并使用 windbg -z shell32.dll 和 .reload 从主机获取它的 sumbols (因为主机中的下行存储是在 vm 中的网络映射第二个跟踪正确加载 pdb 并给出正确的堆栈跟踪警告

kd> kb
 # ChildEBP RetAddr  Args to Child              
00 f8bb1d40 804de7ec 0007f368 0000000f 00000000 nt!NtCreateSection
01 f8bb1d40 7c90e4f4 0007f368 0000000f 00000000 nt!KiFastCallEntry+0xf8
02 0007f224 7c90d16c 7c91c993 0007f368 0000000f ntdll!KiFastSystemCallRet
03 0007f228 7c91c993 0007f368 0000000f 00000000 ntdll!NtCreateSection+0xc
04 0007f2a8 7c91c64a 0007f340 00000790 0007f300 ntdll!LdrpCreateDllSection+0x92
05 0007f388 7c91624a 000add00 0007f414 0007f93c ntdll!LdrpMapDll+0x28f
06 0007f648 7c9164b3 00000000 000add00 0007f93c ntdll!LdrpLoadDll+0x1e9
07 0007f8f0 7c801bbd 000add00 0007f93c 0007f91c ntdll!LdrLoadDll+0x230
08 0007f958 7c801d72 7ffddc00 00000000 00000000 kernel32!LoadLibraryExW+0x18e
09 0007f96c 7ca625a3 7ca625ac 00000000 00000000 kernel32!LoadLibraryExA+0x1f
WARNING: Stack unwind information not available. Following frames may be wrong.
0a 0007f990 010057b8 000700ac 000a7c84 00000000 SHELL32!SHCreateQueryCancelAutoPlayMoniker+0x2062d
0b 0007fbc4 010041ac 0000012e 00000111 01006118 calc!MenuFunctions+0x15d
0c 0007fcb4 01004329 0000012e 00000111 01006118 calc!RealProcessCommands+0x1b61
0d 0007fcdc 01006521 0000012e 0007fd6c 01006118 calc!ProcessCommands+0x2d
0e 0007fd04 7e418734 000700ac 00000111 0000012e calc!CalcWndProc+0x409
0f 0007fd30 7e418816 01006118 000700ac 00000111 USER32!InternalCallWinProc+0x28
10 0007fd98 7e4189cd 00000000 01006118 000700ac USER32!UserCallWinProcCheckWow+0x150
11 0007fdf8 7e418a10 0007fee8 00000000 0007ff1c USER32!DispatchMessageWorker+0x306
12 0007fe08 010021a7 0007fee8 7c80b731 000a1ee4 USER32!DispatchMessageW+0xf
13 0007ff1c 010125e9 000a7738 00000055 000a7738 calc!WinMain+0x256
14 0007ffc0 7c817067 00000000 00000000 7ffde000 calc!WinMainCRTStartup+0x174
15 0007fff0 00000000 01012475 00000000 78746341 kernel32!BaseProcessStart+0x23

没有警告的堆栈跟踪

Breakpoint 0 hit
nt!NtCreateSection:
805652b3 6a2c            push    2Ch
kd> kb
 # ChildEBP RetAddr  Args to Child              
00 f8aa0d40 804de7ec 0007f368 0000000f 00000000 nt!NtCreateSection
01 f8aa0d40 7c90e4f4 0007f368 0000000f 00000000 nt!KiFastCallEntry+0xf8
02 0007f224 7c90d16c 7c91c993 0007f368 0000000f ntdll!KiFastSystemCallRet
03 0007f228 7c91c993 0007f368 0000000f 00000000 ntdll!NtCreateSection+0xc
04 0007f2a8 7c91c64a 0007f340 00000790 0007f300 ntdll!LdrpCreateDllSection+0x92
05 0007f388 7c91624a 000add00 0007f414 0007f93c ntdll!LdrpMapDll+0x28f
06 0007f648 7c9164b3 00000000 000add00 0007f93c ntdll!LdrpLoadDll+0x1e9
07 0007f8f0 7c801bbd 000add00 0007f93c 0007f91c ntdll!LdrLoadDll+0x230
08 0007f958 7c801d72 7ffdfc00 00000000 00000000 kernel32!LoadLibraryExW+0x18e
09 0007f96c 7ca625a3 7ca625ac 00000000 00000000 kernel32!LoadLibraryExA+0x1f
0a 0007f97c 7ca62e8e 003800dd 000a7c84 00000000 SHELL32!GetXPSP1ResModuleHandle+0x16
0b 0007f990 010057b8 000900ac 000a7c84 00000000 SHELL32!ShellAboutW+0x1f
0c 0007fbc4 010041ac 0000012e 00000111 01006118 calc!MenuFunctions+0x15d
0d 0007fcb4 01004329 0000012e 00000111 01006118 calc!RealProcessCommands+0x1b61
0e 0007fcdc 01006521 0000012e 0007fd6c 01006118 calc!ProcessCommands+0x2d
0f 0007fd04 7e418734 000900ac 00000111 0000012e calc!CalcWndProc+0x409
10 0007fd30 7e418816 01006118 000900ac 00000111 USER32!InternalCallWinProc+0x28
11 0007fd98 7e4189cd 00000000 01006118 000900ac USER32!UserCallWinProcCheckWow+0x150
12 0007fdf8 7e418a10 0007fee8 00000000 0007ff1c USER32!DispatchMessageWorker+0x306
13 0007fe08 010021a7 0007fee8 7c80b731 000a1ee4 USER32!DispatchMessageW+0xf
14 0007ff1c 010125e9 000a7738 00000055 000a7738 calc!WinMain+0x256
15 0007ffc0 7c817067 00000000 00000000 7ffda000 calc!WinMainCRTStartup+0x174
16 0007fff0 00000000 01012475 00000000 78746341 kernel32!BaseProcessStart+0x23

将参数转储到 NtCreateSection

kd> dds @esp l8
f8bb1d44  804de7ec nt!KiFastCallEntry+0xf8
f8bb1d48  0007f368
f8bb1d4c  0000000f
f8bb1d50  00000000
f8bb1d54  00000000
f8bb1d58  00000010
f8bb1d5c  01000000 calc!_imp__RegOpenKeyExA <PERF> (calc+0x0)
f8bb1d60  00000790

我们知道第七个参数是HANDLE according to prototype of DDI

    NTSTATUS ZwCreateSection(
      _Out_    PHANDLE            SectionHandle,
      _In_     ACCESS_MASK        DesiredAccess,
      _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
      _In_opt_ PLARGE_INTEGER     MaximumSize,
      _In_     ULONG              SectionPageProtection,
      _In_     ULONG              AllocationAttributes,
      _In_opt_ HANDLE             FileHandle
    );

kd> !handle 790

Failed to get VAD root
PROCESS ffae2020  SessionId: 0  Cid: 0410    Peb: 7ffde000  ParentCid: 00a8
    DirBase: 04d87000  ObjectTable: e1bd5238  HandleCount:  29.
    Image: calc.exe

Handle table at e1bd5238 with 29 entries in use

0790: Object: 8124b028  GrantedAccess: 00100020 Entry: e1032f20
Object: 8124b028  Type: (8127b900) File
    ObjectHeader: 8124b010 (old version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \WINDOWS\system32\xpsp1res.dll {HarddiskVolume1}

从内核模式返回用户模式并检查新的部分句柄

kd> g
eax=00000000 ebx=00000000 ecx=00000001 edx=ffffffff esi=0007f368 edi=00000000
eip=7c90d16c esp=0007f22c ebp=0007f2a8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!ZwCreateSection+0xc:
7c90d16c c21c00          ret     1Ch

在用户态检查HANDLE的返回值

0:000> dd 7f368 l1
dd 7f368 l1
0007f368  0000078c
0:000> !handle 78c
!handle 78c
Handle 78c
  Type          Section
0:000> !handle 78c f
!handle 78c f
Handle 78c
  Type          Section
  Attributes    0
  GrantedAccess 0xf:
         None
         Query,MapWrite,MapRead,MapExecute
  HandleCount   2
  PointerCount  3
  Name          <none>
  Object Specific Information
    Section base address 0
    Section attributes 0x1800000
    Section max size 0x2f000
0:000> 

如果不满足,我们可以恢复到 kd 设置进程上下文并在内核模式下检查返回的句柄

kd> !handle 78c f

Failed to get VAD root
PROCESS ffae2020  SessionId: 0  Cid: 0410    Peb: 7ffde000  ParentCid: 00a8
    DirBase: 04d87000  ObjectTable: e1bd5238  HandleCount:  30.
    Image: calc.exe

Handle table at e1bd5238 with 30 entries in use

078c: Object: e1088f30  GrantedAccess: 0000000f Entry: e1032f18
Object: e1088f30  Type: (8128b900) Section
    ObjectHeader: e1088f18 (old version)
        HandleCount: 1  PointerCount: 1

现在,如果您继续执行,您可以在 windbg 中看到加载的库 dbgprint 和在 vm 中的 about 对话框 :)

kd> g
0:000> g
g
ModLoad: 10000000 1002f000   C:\WINDOWS\system32\xpsp1res.dll

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 1970-01-01
    相关资源
    最近更新 更多