首页 > 解决方案 > 如何使用 Windbg 从程序开始进行调试?

问题描述

我正在通过windbg在主机PC上的vmware中调试windows7。(内核版本 7601)

现在一切顺利,我想调试内核中运行程序的部分。换句话说,我想在我双击桌面上的任何程序运行它的那一刻调试内核中的交互。

许多指南告诉我如何附加到正在运行的进程。但是,我找不到在实际内核中创建进程之前进行调试的方法。

有谁知道如何做到这一点?或者,如果您有任何相关文件,请告诉我。

标签: windowsoperating-systemkernelwindbgwindows-kernel

解决方案


先决条件 2) 对进程创建的基本了解(如果不是数十亿的话,在双击和 GUI 出现之间至少有数百万次操作,只有极少部分发生在内核中)

  1. vmware 或任何虚拟环境作为目标正确设置,带有用于内核调试的串行或网络调试
  2. 正确安装windbg的主机
  3. 以管理员身份在主机中运行windbg

--------例如,如果你有一个管道作为串行连接,它应该看起来像这样

在此处输入图像描述

windbg 应该启动并等待这样的连接

Microsoft (R) Windows Debugger Version 10.0.17763.132 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

Waiting for pipe \\.\pipe\vmwpipe
Waiting to reconnect...

启动您的虚拟环境并选择调试配置屏幕截图是串行配置

在此处输入图像描述

vm 应该启动并在 windbg 中生成一个初始断点,需要使用 g->enter 或 f5 确认

在此之后离开几分钟以完成登录到 vm在 windbg
按 alt+delete 或 ctrl+break 以中断
f5 或 g->enter以放弃对 vm 的控制数次

现在您已准备好检查您的进程创建,正如我在先决条件中提到的那样,您需要有一个通用的进程创建基本概念
您应该知道双击是由 shell (explorer.exe) 处理的,它会处理双击并通过调用 CreateProcess() CreateProcess 来启动进程创建 以前在 kernel32 中是一个完整的 api,现在它是一个将调用转发到 kernelbase.dll 的存根,该调用将其转发到 ntdll 及其内核对应物 ntexecutive (ntoskrnl,ntkrnlmp) 。

do !process 0 0 explorer.exe tofetch the _EPROCESS of explorer.exe

do .process /p /P /r _EPROCESS fetched earlier 

.reload /f explorer.exe

在 explorer.exe 中的 CreateProcess Import 上设置一个特定于进程的断点,如下所示,然后在您的 vm 中双击 calc.exe 以获得如下中断

0: kd> bp /p ffff9509`0b03b300 poi(Explorer!_imp_CreateProcessW)
0: kd> g
Breakpoint 4 hit
KERNEL32!CreateProcessWStub:
0033:00007ffb`21dfc020 4c8bdc          mov     r11,rsp
1: kd> k
 # Child-SP          RetAddr           Call Site
00 00000000`1732e8f8 00007ffb`2103ec10 KERNEL32!CreateProcessWStub
01 00000000`1732e900 00007ffb`20fed0ee windows_storage!CInvokeCreateProcessVerb::CallCreateProcess+0x124
02 00000000`1732ebb0 00007ffb`20f8fde8 windows_storage!CInvokeCreateProcessVerb::_PrepareAndCallCreateProcess+0x1c2
03 00000000`1732ec30 00007ffb`20f8fbc7 windows_storage!CInvokeCreateProcessVerb::_TryCreateProcess+0x84
04 00000000`1732ec60 00007ffb`20f8f82d windows_storage!CInvokeCreateProcessVerb::Launch+0xfb
05 00000000`1732ed00 00007ffb`20feb31d windows_storage!CInvokeCreateProcessVerb::Execute+0x5d
06 00000000`1732ed40 00007ffb`20fe6014 windows_storage!CBindAndInvokeStaticVerb::InitAndCallExecute+0x169
07 00000000`1732edc0 00007ffb`20fe7eea windows_storage!CBindAndInvokeStaticVerb::TryCreateProcessDdeHandler+0x68
08 00000000`1732ee40 00007ffb`20fe459d windows_storage!CBindAndInvokeStaticVerb::Execute+0x1ba
09 00000000`1732f150 00007ffb`20fe4495 windows_storage!RegDataDrivenCommand::_TryInvokeAssociation+0xb5
0a 00000000`1732f1c0 00007ffb`22c7880f windows_storage!RegDataDrivenCommand::_Invoke+0x145
0b 00000000`1732f230 00007ffb`22c786ca SHELL32!CRegistryVerbsContextMenu::_Execute+0xcb
0c 00000000`1732f2a0 00007ffb`22c184e7 SHELL32!CRegistryVerbsContextMenu::InvokeCommand+0xaa
0d 00000000`1732f5a0 00007ffb`22c22549 SHELL32!HDXA_LetHandlerProcessCommandEx+0x117
0e 00000000`1732f6b0 00007ffb`22df9a29 SHELL32!CDefFolderMenu::InvokeCommand+0x139
0f 00000000`1732fa10 00007ffb`230b4409 SHELL32!SHInvokeCommandOnContextMenu2+0x1f5
10 00000000`1732fc50 00007ffb`2244c315 SHELL32!s_DoInvokeVerb+0xc9
11 00000000`1732fcc0 00007ffb`21df81f4 shcore!_WrapperThreadProc+0xf5
12 00000000`1732fda0 00007ffb`2461a251 KERNEL32!BaseThreadInitThunk+0x14
13 00000000`1732fdd0 00000000`00000000 ntdll!RtlUserThreadStart+0x21

你可以看到使用这样的东西传递的参数

1: kd> .printf "lpApplicationName = %mu\nlpCommandLine = %mu\nlpProcessAttributes %p\nlpThreadAttributes %p\nbInheritHandles = %x\ndwCreationFlags %x\nlpEnvironment=%p\nlpCurrentDirectory=%mu\nlpStartupInfo=%p\nlpProcessInformation=%p\n" , @rcx,@rdx,@r8,@r9,dwo(@rsp+28),dwo(@rsp+30),dwo(@rsp+38),dwo(@rsp+40),dwo(@rsp+48),dwo(@rsp+50)
lpApplicationName = C:\Windows\System32\calc.exe
lpCommandLine = "C:\Windows\System32\calc.exe" 
lpProcessAttributes 0000000000000000
lpThreadAttributes 0000000000000000
bInheritHandles = 0
dwCreationFlags 4080414
lpEnvironment=0000000000000000
lpCurrentDirectory=C:\Windows\System32
lpStartupInfo=0000000012576758
lpProcessInformation=00000000125767f0

这只是冰山一角,正如您从调用堆栈中看到的那样,双击被 shell32.dll 捕获和处理,并且经过很多时间才能到达这一点,现在它必须在用户模式下旅行更长的时间才能到达 Syscall () 在 ntdll

系统调用 ntdll!ZwCreateProcessEx 是将控制从用户模式转移到内核模式的地方


推荐阅读