使用 WinDBG 识别有缺陷的功能

发布于 2024-10-28 12:10:27 字数 5557 浏览 4 评论 0原文

我已经从 7.1 Windows SDK 安装了 WinDBG。然后,我使用 VC++ 2008 创建了一个程序“CleanPayload.exe”,其中只包含“main”和对故意包含缺陷的函数的调用。它是一个包含调试符号的发布版本。我在 WindDBG 中打开该程序,然后

  1. 执行 .sympath+ 来指示该程序的 PDB 所在位置。
  2. 使用 ld * 来加载所有符号
  3. 使用 lm 来验证所有符号是否已加载(我的程序的私有符号,Windows 库的公共符号)。

然后我运行该程序,它抛出了第一次机会异常,这是预料之中的。如下:

(910.12a0): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll32!LdrpDoDebuggerBreak+0x2c:
771e0f2b cc              int     3 

但是当我要求 WinDBG 显示堆栈时,它没有显示我的程序“CleanPayload.exe”的任何内容。相反,它向我显示:

0:000:x86> kb
ChildEBP RetAddr  Args to Child              
004bf5ec 771c122b 7efdd000 7efde000 7724206c ntdll32!LdrpDoDebuggerBreak+0x2c
004bf764 77192187 004bf7d8 77140000 7c185e6a ntdll32!LdrpInitializeProcess+0x132f
004bf7b4 77179e89 004bf7d8 77140000 00000000 ntdll32!_LdrpInitialize+0x78
004bf7c4 00000000 004bf7d8 77140000 00000000 ntdll32!LdrInitializeThunk+0x10

我需要做什么才能向我显示堆栈跟踪,其中 (1) 包括我的程序和 (2) 引发异常的函数?

更新 我按照 Larry 的建议运行了第一个异常,并得到了以下结果:

0:000:x86> g
ntdll!NtTerminateProcess+0xa:
00000000`76faf97a c3              ret
0:000> kb
RetAddr           : Args to Child                                                           : Call Site
00000000`74c6601a : 00000000`00000000 00000000`000de600 00000000`000ddc80 00000000`74c60304 : ntdll!NtTerminateProcess+0xa
00000000`74c5cf87 : 00000000`0030f988 00000000`0030dba8 00000000`7efdb000 00000000`0030f934 : wow64!whNtTerminateProcess+0x46
00000000`74be276d : 00000000`77150190 00000000`74c50023 00000000`00000000 00000000`0030fab8 : wow64!Wow64SystemServiceEx+0xd7
00000000`74c5d07e : 00000000`00000000 00000000`74be1920 00000000`000de820 00000000`76f93501 : wow64cpu!TurboDispatchJumpAddressEnd+0x24
00000000`74c5c549 : 00000000`00000000 00000000`00000000 00000000`74c54ac8 00000000`7ffe0030 : wow64!RunCpuSimulation+0xa
00000000`76faae27 : 00000000`004a3100 00000000`00000000 00000000`7707a1e0 00000000`7efdf000 : wow64!Wow64LdrpInitialize+0x429
00000000`76fa72f8 : 00000000`00000000 00000000`76fa8641 00000000`76fb84e0 00000000`00000000 : ntdll!LdrpInitializeProcess+0x1780
00000000`76f92ace : 00000000`000df1b0 00000000`00000000 00000000`7efdf000 00000000`00000000 : ntdll! ?? ::FNODOBFM::`string'+0x2af20
00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe

因此,不幸的是,我仍然没有看到相关的堆栈跟踪信息。在执行上述步骤之前,我还尝试了 .effmach x86 命令,它似乎没有产生影响。顺便说一句,我还重新执行了整个测试,并为我正在测试的目标程序激活了应用程序验证器。我得到了非常矛盾的结果:

0:000> g
ModLoad: 00000000`76d40000 00000000`76e5f000   WOW64_IMAGE_SECTION
ModLoad: 00000000`74f90000 00000000`75090000   WOW64_IMAGE_SECTION
ModLoad: 00000000`76d40000 00000000`76e5f000   NOT_AN_IMAGE
ModLoad: 00000000`76e60000 00000000`76f5a000   NOT_AN_IMAGE
ModLoad: 00000000`71160000 00000000`711c0000   C:\Windows\syswow64\verifier.dll
Page heap: pid 0x1A54: page heap enabled with flags 0x3.
AVRF: CleanPayload.exe: pid 0x1A54: flags 0x80643027: application verifier enabled
ModLoad: 00000000`71130000 00000000`7115b000   C:\Windows\SysWOW64\vrfcore.dll
ModLoad: 00000000`710d0000 00000000`71128000   C:\Windows\SysWOW64\vfbasics.dll
ModLoad: 00000000`74f90000 00000000`75090000   C:\Windows\syswow64\kernel32.dll
ModLoad: 00000000`76830000 00000000`76876000   C:\Windows\syswow64\KERNELBASE.dll
ModLoad: 00000000`715c0000 00000000`7164e000   C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4926_none_508ed732bcbc0e5a\MSVCP90.dll
ModLoad: 00000000`73dc0000 00000000`73e63000   C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4926_none_508ed732bcbc0e5a\MSVCR90.dll
(1a54.17dc): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll32!LdrpDoDebuggerBreak+0x2c:
771e0f2b cc              int     3

0:000:x86> !avrf
*************************************************************************
***                                                                   ***
***                                                                   ***
***    Your debugger is not using the correct symbols                 ***
***                                                                   ***
***    In order for this command to work properly, your symbol path   ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: wow64!_TEB32                                  ***
***                                                                   ***
*************************************************************************
Application verifier is not enabled for this process.
Use appverif.exe tool to enable it.

上面的执行显示AVRF: Cleanpayload.exe ...应用程序验证程序已启用,这表明它已锁定到目标。但是随后的 !avrf 命令显示调试符号是错误的,即使 lm 命令显示它们都已正确加载!这里到底发生了什么?

I've installed WinDBG from the 7.1 Windows SDK. Then with VC++ 2008 I made a program 'CleanPayload.exe' which contains nothing but a 'main' and an invocation to a function that intentionally contains a defect. It is a release build which includes debug symbols. I opened that program into WindDBG and then

  1. did a .sympath+ to indicate where the PDB was for that program.
  2. did a ld * to load all symbols
  3. did a lm to verify all symbols were loaded (private symbols for my program, public symbols for Windows libraries).

I then ran the program and it threw a first-chance exception, which was rather expected. As follows:

(910.12a0): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll32!LdrpDoDebuggerBreak+0x2c:
771e0f2b cc              int     3 

But when I ask WinDBG to show me the stack, it doesn't show me anything of my program 'CleanPayload.exe'. Instead it shows me this:

0:000:x86> kb
ChildEBP RetAddr  Args to Child              
004bf5ec 771c122b 7efdd000 7efde000 7724206c ntdll32!LdrpDoDebuggerBreak+0x2c
004bf764 77192187 004bf7d8 77140000 7c185e6a ntdll32!LdrpInitializeProcess+0x132f
004bf7b4 77179e89 004bf7d8 77140000 00000000 ntdll32!_LdrpInitialize+0x78
004bf7c4 00000000 004bf7d8 77140000 00000000 ntdll32!LdrInitializeThunk+0x10

What do I need to do so that it will show me a stack trace which (1) includes my program and (2) the function where the exception was thrown?

Update I followed Larry's suggestion, to run past the first exception, and got the following results:

0:000:x86> g
ntdll!NtTerminateProcess+0xa:
00000000`76faf97a c3              ret
0:000> kb
RetAddr           : Args to Child                                                           : Call Site
00000000`74c6601a : 00000000`00000000 00000000`000de600 00000000`000ddc80 00000000`74c60304 : ntdll!NtTerminateProcess+0xa
00000000`74c5cf87 : 00000000`0030f988 00000000`0030dba8 00000000`7efdb000 00000000`0030f934 : wow64!whNtTerminateProcess+0x46
00000000`74be276d : 00000000`77150190 00000000`74c50023 00000000`00000000 00000000`0030fab8 : wow64!Wow64SystemServiceEx+0xd7
00000000`74c5d07e : 00000000`00000000 00000000`74be1920 00000000`000de820 00000000`76f93501 : wow64cpu!TurboDispatchJumpAddressEnd+0x24
00000000`74c5c549 : 00000000`00000000 00000000`00000000 00000000`74c54ac8 00000000`7ffe0030 : wow64!RunCpuSimulation+0xa
00000000`76faae27 : 00000000`004a3100 00000000`00000000 00000000`7707a1e0 00000000`7efdf000 : wow64!Wow64LdrpInitialize+0x429
00000000`76fa72f8 : 00000000`00000000 00000000`76fa8641 00000000`76fb84e0 00000000`00000000 : ntdll!LdrpInitializeProcess+0x1780
00000000`76f92ace : 00000000`000df1b0 00000000`00000000 00000000`7efdf000 00000000`00000000 : ntdll! ?? ::FNODOBFM::`string'+0x2af20
00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe

Thus, unfortunately, I'm still not seeing relevant stack trace information. I also tried the .effmach x86 command, before the steps above, and it didn't seem to have an impact. Incidentally, I also then re-executed the whole test with app verifier activated for the target program I'm testing. I got very conflicting results:

0:000> g
ModLoad: 00000000`76d40000 00000000`76e5f000   WOW64_IMAGE_SECTION
ModLoad: 00000000`74f90000 00000000`75090000   WOW64_IMAGE_SECTION
ModLoad: 00000000`76d40000 00000000`76e5f000   NOT_AN_IMAGE
ModLoad: 00000000`76e60000 00000000`76f5a000   NOT_AN_IMAGE
ModLoad: 00000000`71160000 00000000`711c0000   C:\Windows\syswow64\verifier.dll
Page heap: pid 0x1A54: page heap enabled with flags 0x3.
AVRF: CleanPayload.exe: pid 0x1A54: flags 0x80643027: application verifier enabled
ModLoad: 00000000`71130000 00000000`7115b000   C:\Windows\SysWOW64\vrfcore.dll
ModLoad: 00000000`710d0000 00000000`71128000   C:\Windows\SysWOW64\vfbasics.dll
ModLoad: 00000000`74f90000 00000000`75090000   C:\Windows\syswow64\kernel32.dll
ModLoad: 00000000`76830000 00000000`76876000   C:\Windows\syswow64\KERNELBASE.dll
ModLoad: 00000000`715c0000 00000000`7164e000   C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4926_none_508ed732bcbc0e5a\MSVCP90.dll
ModLoad: 00000000`73dc0000 00000000`73e63000   C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4926_none_508ed732bcbc0e5a\MSVCR90.dll
(1a54.17dc): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll32!LdrpDoDebuggerBreak+0x2c:
771e0f2b cc              int     3

0:000:x86> !avrf
*************************************************************************
***                                                                   ***
***                                                                   ***
***    Your debugger is not using the correct symbols                 ***
***                                                                   ***
***    In order for this command to work properly, your symbol path   ***
***    must point to .pdb files that have full type information.      ***
***                                                                   ***
***    Certain .pdb files (such as the public OS symbols) do not      ***
***    contain the required information.  Contact the group that      ***
***    provided you with these symbols if you need this command to    ***
***    work.                                                          ***
***                                                                   ***
***    Type referenced: wow64!_TEB32                                  ***
***                                                                   ***
*************************************************************************
Application verifier is not enabled for this process.
Use appverif.exe tool to enable it.

The above execution saysAVRF: Cleanpayload.exe ... application verifier enabled, which indicates that it is locked-on to the target. But then the subsequent !avrf command reveals that debug symbols are bad, even though the lm command shows they are all properly loaded! What on earth is happening here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风透绣罗衣 2024-11-04 12:10:27

您正在运行 64 位版本的 Windbg 和 32 位应用程序。初始断点在 64 位代码中运行。

如果您点击“g”,您应该点击 32 位应用程序的初始断点,您应该能够从那里开始。

要从 64 位调试切换到 32 位调试(例如,如果按 CTRL-C),请输入:

.effmach x86

这会将调试器从 64 位模式切换到 32 位模式。

You're running the 64bit version of windbg and a 32bit application. The initial breakpoint is running in 64bit code.

If you hit "g" you should hit the initial breakpoint for the 32bit application, you should be able to go from there.

To switch from 64bit debugging to 32bit debugging (if you hit CTRL-C for example), type in:

.effmach x86

which will switch the debugger from 64bit mode to 32bit mode.

莫相离 2024-11-04 12:10:27

当您的软件打包并发送给质量检查或客户后,您是否试图弄清楚如何调试实际问题?如果是,您可以使用另一个工具,adplus。 Adplus 在后台启动调试器,只有一个目的(实际上有两个目的,如果您在挂起模式下运行,但这不是您想要的),那就是等待异常。当异常发生时,它会生成一个进程内存转储文件,该文件可以加载到WinDbg中。

使用这种方法,您不必依赖 QA 或您的客户来了解如何使用 WinDbg。您只需向他们指示如何运行一个命令行即可。运行后,他们只是压缩整个输出目录并将其发送给您进行分析。

一旦加载到 WinDbg 中,内存转储文件将向您显示异常的确切位置以及当时的所有本地/成员变量(尽管如果您的代码经过优化,您可能需要稍微查找一下这些值)。

Are you trying to figure out how to debug real problems once your software is packaged up and sent to QA or customers? If yes, there's another tool you could use, adplus. Adplus launches the debugger under the hood and has only one purpose (actually two, if you ran in hang mode, but that's not what you want here), which is to wait for exceptions. When an exception happens, it will generate a process memory dump file which can be loaded into WinDbg.

Using this approach, you don't have to rely on QA or your customers to know how to work with WinDbg. You simply give them instructions how to run one command line. After they run it, they just zip up the entire output directory and send it to you for analysis.

Once loaded into WinDbg, the memory dump file will show you the exact place of the exception and all local/member variables at the time (although you may have to fish a bit for those values if your code is optimized).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文