Here are some general steps that will get you on your way:
First, you must change your compiler's settings so that it creates PDB files, even for release builds. Later versions of the Visual C++ compiler do this by default, but in many versions of Visual C++ you must do this yourself. Create program database files, and then keep an archive of those files along with each build of your application. It is critical that every build of your applications has its own set of PDBs. You can't just reuse the same ones you made with build 10 to examining the dumps generated by build 15, for example. Over the life of your project, you will end up with a ton of PDBs, so be prepared for that.
Next, you need to be able to identify the exact version of your application which generated the dump file. If you are creating your own MiniDumps (by calling MiniDumpWriteDump() for example), probably the easiest way to do this is to simply make part of the filename of the MiniDump the complete version number of your application. You'll need to have a reasonable version numbering scheme in place for this to work. In my shop, we increment the build number across all branches by one every time the autobuilder creates a build.
Now that you have received the dump file from the customer, you know the precise version of the application that created the dump, and you have found the PDB files for this build.
Now you need to go through your source control's history and find the source code for this exact version of the software. The best way to do this is to apply 'labels' to your branches every time you make a build. Set the value of the label to the exact version number, and it becomes easy to find in the history.
You're almost ready to fire up WinDbg/Visual C++:
Get the complete source tree for that version of your application. Put it in a separate place on your hard drive, say c:\app_build_1.0.100 for application version 1.0 build #100.
Get the binaries for that exact version of your application and put them somewhere on your hard drive. It might be easiest simply to install that version of your application to get the binaries.
Put the PDB files in the same location as the binaries in step 2.
Now you have two options for viewing the dump file. You can use Visual Studio or WinDbg. Using Visual Studio is easier, but WinDbg is much more powerful. Most of the time the functionality in Visual Studio will suffice.
To use Visual Studio, all you have to do is open the dump file like it is a project. Once opened, "run" the dump file (F5 by default) and if all the paths are set correctly it will take you right to the code that crashed, give you a call stack, etc.
To use WinDbg, you have to jump through a couple of hoops:
Start WinDbg
Open the dump file. (Ctrl + D by default)
Tell WinDbg to go get the correct MicroSoft symbol files. Type .symfix. This may take a few moments as it will pull a ton of stuff down from the Internet.
Tell WinDbg where the symbols (PDB files) are. Type .sympath+ c:\pdblocation, substituting wherever you put the PDB files for the pathname. Make sure you get the plus sign in there with no whitespace between .sympath and the + sign or else you'll screw up step 3.
Tell WinDbg where the source code is. Type .srcpath c:\app_build_1.0.100 substituting the path where you got code from source control for this version of the software.
Tell WinDbg to analyze the dump file. Type !analyze -v
After a few moments, if everything is configured correctly, WinDbg will take you right to the location of your crash. At this point you have a million options for digging deep into your application's memory space, the state of critical sections, windows, etc. But that is way beyond the scope of this post.
$ Include a directory to search for extensions
$ (point to a source controlled or UNC common directory so that all developers get access)
.extpath+"c:\svn\DevTools\WinDBG\Extensions"
$ When debugging a driver written with the Windows Driver Framework/KMDF
$ load this extension that comes from the WinDDK.
!load C:\WinDDK\7600.16385.1\bin\x86\wdfkd.dll
!wdftmffile C:\WinDDK\7600.16385.1\tools\tracing\i386\wdf01009.tmf
$ load some extensions
.load msec.dll
.load byakugan.dll
.load odbgext.dll
.load sosex
.load psscor4
$ Make commands that support DML (Debugger Markup Language) use it
.prefer_dml 1
.dml_start
$ Show NTSTATUS codes in hex by default
.enable_long_status 1
$ Set default extension
.setdll psscor4
$ Show all loaded extensions
.chain /D
$ Load some command trees
.cmdtree c:\svn\DevTools\WinDBG\cmdtree\cmdtree1.txt
.cmdtree c:\svn\DevTools\WinDBG\cmdtree\cmdtree2.txt
$ Show some help for the extensions
!wdfkd.help
!psscor4.help
.help /D
A "cmdtree" allows you to define a "menu" of debugger commands for easy access to frequently used commands without having to remember the terse command names.
You don't have to put all the command definitions into the same cmdtree text file....you can keep them separate and load multiple ones if you wish (they then get their own window).
You can use the -c option on the command line to automatically run a WinDBG script when you start WinDBG.
Gives opportunity to turn on DML (Debugger markup language) mode, load particular extensions, set .NET exception breakpoints, set kernel flags (e.g. when kernel debugging you might need to change the DbgPrint mask so you see tracing information....ed nt!Kd_DEFAULT_Mask 0xffffffff), load cmdtrees, etc.
$ Include a directory to search for extensions
$ (point to a source controlled or UNC common directory so that all developers get access)
.extpath+"c:\svn\DevTools\WinDBG\Extensions"
$ When debugging a driver written with the Windows Driver Framework/KMDF
$ load this extension that comes from the WinDDK.
!load C:\WinDDK\7600.16385.1\bin\x86\wdfkd.dll
!wdftmffile C:\WinDDK\7600.16385.1\tools\tracing\i386\wdf01009.tmf
$ load some extensions
.load msec.dll
.load byakugan.dll
.load odbgext.dll
.load sosex
.load psscor4
$ Make commands that support DML (Debugger Markup Language) use it
.prefer_dml 1
.dml_start
$ Show NTSTATUS codes in hex by default
.enable_long_status 1
$ Set default extension
.setdll psscor4
$ Show all loaded extensions
.chain /D
$ Load some command trees
.cmdtree c:\svn\DevTools\WinDBG\cmdtree\cmdtree1.txt
.cmdtree c:\svn\DevTools\WinDBG\cmdtree\cmdtree2.txt
$ Show some help for the extensions
!wdfkd.help
!psscor4.help
.help /D
leaktrap - GDI/USER handle tracker to aid in leak detection
Mona (requires PyKD) - set of commands to aid in advanced analysis/find exploits
MSEC - provides automated crash analysis and security risk assessment
narly - lists info about loaded modules such as if using SafeSEH, ASLR, DEP, /GS (Buffer Security Checks)
netext (Rodney Viana) - (!wservice - list WCF service objects, !wconfig - show .config lines, !whttp - list HttpContexts, !wselect/!wfrom - support SQL like queries on arrays)
PowerDBG - allows control of WinDBG via Powershell scripts
Pykd - allows control of WinDBG via Python scripts
windbglib - python wrapper library around the pykd extension for WinDBG, mimicking immlib (so you can use scripts originally written for Immunity Debugger)
Debuggers/Tools that use the dbgeng.dll API/WinDBG Tools
cr4zyserb - huge collection of plugins and other debugging tools
How to Write a Windows Debugger References (Devon Straw) - large collection of links giving you detailed information that you would need if you wanted to write your own debugger e.g. PDB file format, .DMP file formats, PE File structure, how to record stack traces, etc, etc.
Tuts4You - unpackers, IDA, OllyDBG, Immunity Debugger plugins, etc.
The first step is to load the dump file into a WinDbg instance.
Next, you need to make sure you have a symbols setup.
Finally, you can run the command !analyze -v to get a basic analysis performed on it. You need to have symbol information available for your code to make dump files worthwhile.
发布评论
评论(3)
以下是一些可以帮助您入门的常规步骤:
首先,您必须更改编译器的设置,以便它创建 PDB 文件,即使对于发布版本也是如此。 更高版本的 Visual C++ 编译器默认执行此操作,但在许多版本的 Visual C++ 中,您必须你自己做吧。 创建程序数据库文件,然后将这些文件与应用程序的每个构建一起存档。 至关重要的是,应用程序的每个构建都有自己的一组 PDB。 例如,您不能仅仅重复使用在构建 10 中创建的相同内容来检查构建 15 生成的转储。 在项目的整个生命周期中,您最终将得到大量的 PDB,因此请为此做好准备。
接下来,您需要能够识别生成转储文件的应用程序的确切版本。 如果您要创建自己的 MiniDump(例如,通过调用 MiniDumpWriteDump() ),最简单的方法可能是简单地将 MiniDump 文件名的一部分作为应用程序的完整版本号。 您需要有一个合理的版本编号方案才能使其发挥作用。 在我的商店中,每次自动构建器创建构建时,我们都会将所有分支的构建号加一。
现在您已收到客户发来的转储文件,您知道创建转储的应用程序的精确版本,并且您已找到此构建的 PDB 文件。
现在,您需要浏览源代码管理的历史记录并找到该软件的确切版本的源代码。 最好的方法是在每次构建时将“标签”应用到您的分支。 将标签的值设置为准确的版本号,就可以很容易在历史记录中查找。
您几乎已准备好启动 WinDbg/Visual C++:
c:\app_build_1.0.100
。现在您有两个选项用于查看转储文件。 您可以使用 Visual Studio 或 WinDbg。 使用 Visual Studio 更容易,但 WinDbg 更强大。 大多数时候,Visual Studio 中的功能就足够了。
要使用 Visual Studio,您所要做的就是像打开项目一样打开转储文件。 您提供调用堆栈等。
打开后,“运行”转储文件(默认情况下为 F5),如果所有路径设置正确,它将带您直接到达崩溃的代码,为 WinDbg,您必须跳过几个环节:
.symfix
。 这可能需要一些时间,因为它会从互联网上下载大量内容。.sympath+ c:\pdblocation
,将路径名替换为 PDB 文件所在的位置。 确保在.sympath
和+
符号之间添加加号,否则您将搞砸第 3 步。.srcpath c:\app_build_1.0.100
替换您从该版本软件的源代码管理中获取代码的路径。!analyze -v
几分钟后,如果一切配置正确,WinDbg 将带您直接到达崩溃的位置。 此时,您有一百万个选项可以深入了解应用程序的内存空间、关键部分的状态、窗口等。但这方式超出了本文的范围。
祝你好运!
Here are some general steps that will get you on your way:
First, you must change your compiler's settings so that it creates PDB files, even for release builds. Later versions of the Visual C++ compiler do this by default, but in many versions of Visual C++ you must do this yourself. Create program database files, and then keep an archive of those files along with each build of your application. It is critical that every build of your applications has its own set of PDBs. You can't just reuse the same ones you made with build 10 to examining the dumps generated by build 15, for example. Over the life of your project, you will end up with a ton of PDBs, so be prepared for that.
Next, you need to be able to identify the exact version of your application which generated the dump file. If you are creating your own MiniDumps (by calling MiniDumpWriteDump() for example), probably the easiest way to do this is to simply make part of the filename of the MiniDump the complete version number of your application. You'll need to have a reasonable version numbering scheme in place for this to work. In my shop, we increment the build number across all branches by one every time the autobuilder creates a build.
Now that you have received the dump file from the customer, you know the precise version of the application that created the dump, and you have found the PDB files for this build.
Now you need to go through your source control's history and find the source code for this exact version of the software. The best way to do this is to apply 'labels' to your branches every time you make a build. Set the value of the label to the exact version number, and it becomes easy to find in the history.
You're almost ready to fire up WinDbg/Visual C++:
c:\app_build_1.0.100
for application version 1.0 build #100.Now you have two options for viewing the dump file. You can use Visual Studio or WinDbg. Using Visual Studio is easier, but WinDbg is much more powerful. Most of the time the functionality in Visual Studio will suffice.
To use Visual Studio, all you have to do is open the dump file like it is a project. Once opened, "run" the dump file (F5 by default) and if all the paths are set correctly it will take you right to the code that crashed, give you a call stack, etc.
To use WinDbg, you have to jump through a couple of hoops:
.symfix
. This may take a few moments as it will pull a ton of stuff down from the Internet..sympath+ c:\pdblocation
, substituting wherever you put the PDB files for the pathname. Make sure you get the plus sign in there with no whitespace between.sympath
and the+
sign or else you'll screw up step 3..srcpath c:\app_build_1.0.100
substituting the path where you got code from source control for this version of the software.!analyze -v
After a few moments, if everything is configured correctly, WinDbg will take you right to the location of your crash. At this point you have a million options for digging deep into your application's memory space, the state of critical sections, windows, etc. But that is way beyond the scope of this post.
Good luck!
(请参阅下面的“转储”部分)
使用 WinDbg 的基本教程和演示
“启动”/附加 WinDBG 的不同方式
工作区
了解工作区的工作原理...
Cmdtree
“cmdtree”允许您轻松定义调试器命令的“菜单”访问常用命令而无需记住简洁的命令名称。
您不必将所有命令定义放入同一个 cmdtree 文本文件中...您可以将它们分开并根据需要加载多个命令(然后它们会获得自己的窗口)。
启动脚本
您可以在命令行上使用 -c 选项启动 WinDBG 时自动运行 WinDBG 脚本。
提供打开 DML(调试器标记语言)模式、加载特定扩展、设置 .NET 异常断点、设置内核标志的机会(例如,当内核调试时,您可能需要更改 DbgPrint 掩码,以便看到跟踪信息....ed nt !Kd_DEFAULT_Mask 0xffffffff),加载cmdtree等
示例脚本:
命令备忘单
扩展
“扩展”允许您扩展 WinDBG 内部支持的命令/功能的范围。
- 程序集语法突出显示和驱动程序映射工具)< br>
- 检测反调试方法、vista 堆可视化/模拟、跟踪内存中的缓冲区
- 记录您在调试会话中执行的每个命令,以便您可以轻松地重新执行
- 检查堆结构是否损坏,检测线程共享的对象等
-(!stlpvector、!idt、!unhex、!grep 等)
- 从内存中转储 PE 文件
< br>
- 调试 UEFI 固件
- GDI/USER 句柄跟踪器,有助于泄漏检测
- 帮助高级分析/查找漏洞的命令集
- 提供自动崩溃分析和安全风险评估
- 列出有关已加载模块的信息,例如是否使用 SafeSEH、ASLR、DEP、/GS(缓冲区安全检查)
- (!wservice - 列出 WCF 服务对象, !wconfig - 显示 .config 行,!whttp - 列出 HttpContext,!wselect/!wfrom - 支持数组上的 SQL 查询)
- 打开调试器扩展
- 将调试对象传递给另一个调试器,无需重新启动
- SOS 的超集,用于协助调试 .NET 2.0 托管代码
- SOS 的超集,用于协助调试 .NET 4 托管代码
- 允许使用 python 脚本
- 允许使用 Python 编写 WinDBG 脚本
-(!valloc, !vallocrwx, !heapalloc, !heapfree, !remotecall, !remotecall64, !loaddll, !unloaddll, !close、!killthread、!adjpriv、!ret)
-旧版扩展...现已内置到 WinDBG 的 ext.dll 中
- 用于帮助调试托管 NET 2.0 或 4.0 代码的更多命令
- ( !DumpHttpContext、!DumpASPNetRequests、!DumpSqlConnectionPools、!DumpThreadPool 等)
- 调试器扩展的源代码(需要 OSR Online 帐户才能访问它)
- 代码覆盖率图表
- 显示应用程序线程的等待链(帮助查找死锁)
- 集成 Wireshark 协议分析器以实现虚拟机流量操作和分析
- Tracer、WCT、heap_stat、bkb、traverse_map、traverse_vector)
- asm 语法高亮
编写自己的扩展
使用 WinDBG 调试托管代码
脚本(C#、PS、Python、WinDBG)
- WinDBG 脚本集合
- WinDBG 脚本的集合
- 允许托管代码编写托管调试器 (MDBG) 和 DbgEng 的脚本
- 允许通过 C# 脚本控制 WinDBG
- 允许控制 WinDBG通过 Powershell 脚本
- 允许通过 Python 脚本控制 WinDBG
- WinDBG 的 pykd 扩展的 python 包装库,模仿 immlib (因此您可以使用最初为 Immunity 调试器编写的脚本)
使用 dbgeng.dll API/WinDBG 工具的调试器/工具
- Windows 调试引擎的 python 包装器
生成故障转储文件以进行事后分析的不同方法
- 包括如何从 Hyper-V、VMWare ESX 和 XenServer VM 生成转储。
-(通过应用程序内的 WIN32 API 调用)。 (C# 应用程序示例)
(用于生成 NMI 的基于硬件的功能...通常在高端服务器上找到,例如 HP 或者您可以获得附加 PCI 卡 "通用 PCI 转储开关")。 Microsoft NMI 技术背景。
(注册表信息),
(如何配置完整(完整)内存转储),
(如何启用完整内存转储),
(当 PC 有大量内存时,如何在 Windows 7 上启用完整内存转储...内存超过 2GB 时通常不可用)
转储分析工具
转储相关工具
内核调试虚拟机
视频
(以及 Pluralsight 上的各种其他调试)
博客
一些博客(本机和托管代码调试的混合)。
高级文章和教程资源
替代调试器
其他链接
- 大量调试器和系统级工具
- 大量插件和其他调试工具
- unvackers,iDA,ollydbg,Immellity Debugger插件等。
(see the "Dump" sections below)
Basic Tutorials and Demonstrations of Using WinDbg
Different Ways to "Start"/Attach WinDBG
Workspaces
Understanding how Workspaces work...
Cmdtree
A "cmdtree" allows you to define a "menu" of debugger commands for easy access to frequently used commands without having to remember the terse command names.
You don't have to put all the command definitions into the same cmdtree text file....you can keep them separate and load multiple ones if you wish (they then get their own window).
Startup Script
You can use the -c option on the command line to automatically run a WinDBG script when you start WinDBG.
Gives opportunity to turn on DML (Debugger markup language) mode, load particular extensions, set .NET exception breakpoints, set kernel flags (e.g. when kernel debugging you might need to change the DbgPrint mask so you see tracing information....ed nt!Kd_DEFAULT_Mask 0xffffffff), load cmdtrees, etc.
An example script:
Command Cheat Sheets
Extensions
"Extensions" allow you to extend the range of commands/features supported inside WinDBG.
- assembly syntax highlighting and a driver mapping tool)
- detect antidebugging methods, vista heap visualization/emulation, track buffers in memory
- records every command you executed in your debug session so you can re-execute easily
- check heap structures for corruption, detect objects shared by threads, etc
- (!stlpvector, !idt, !unhex, !grep, etc)
- dumps PE file from memory
- debug UEFI firmware
- GDI/USER handle tracker to aid in leak detection
- set of commands to aid in advanced analysis/find exploits
- provides automated crash analysis and security risk assessment
- lists info about loaded modules such as if using SafeSEH, ASLR, DEP, /GS (Buffer Security Checks)
- (!wservice - list WCF service objects, !wconfig - show .config lines, !whttp - list HttpContexts, !wselect/!wfrom - support SQL like queries on arrays)
- open debugger extensions
- pass debuggee to another debugger without restarting
- a superset of SOS for assisting in debugging .NET 2.0 managed code
- a superset of SOS for assisting in debugging .NET 4 managed code
- allows python scripting to be used
- allows Python to be used to script WinDBG
-(!valloc, !vallocrwx, !heapalloc, !heapfree, !remotecall, !remotecall64, !loaddll, !unloaddll, !close, !killthread, !adjpriv, !ret)
-legacy extension...now built into WinDBG in ext.dll
- more commands for helping to debug managed NET 2.0 or 4.0 code
- (!DumpHttpContext, !DumpASPNetRequests, !DumpSqlConnectionPools, !DumpThreadPool, etc)
- source to a debugger extension (need an OSR Online account to access it)
- code coverage graph
- display wait chains of application threads (helps find deadlocks)
- integrates Wireshark protocol analyser to enable VM traffic manipulation and analysis
- Tracer, WCT, heap_stat, bkb, traverse_map, traverse_vector)
- asm syntax highlighting
Write your own extension
Using WinDBG to Debug Managed Code
Scripting (C#, PS, Python, WinDBG)
- a collection of WinDBG scripts
- a collection of WinDBG scripts
- allows managed code to script the Managed Debugger (MDBG) and the DbgEng
- allows control of WinDBG via C# scripts
- allows control of WinDBG via Powershell scripts
- allows control of WinDBG via Python scripts
- python wrapper library around the pykd extension for WinDBG, mimicking immlib (so you can use scripts originally written for Immunity Debugger)
Debuggers/Tools that use the dbgeng.dll API/WinDBG Tools
- python wrapper for Windows Debugging Engine
Different Ways to Generate Crash Dump Files for Post-Mortem Analysis
- includes how to generate dump from Hyper-V, VMWare ESX, and XenServer VMs.
- (via WIN32 API call inside your application). (Example for C# applications)
(hardware based feature to generate an NMI...usually found on high-end servers e.g. HP or you can obtain an add-in PCI card "Universal PCI Dump Switch"). Microsoft NMI technology background.
(registry info),
(how to configure a Complete (Full) Memory Dump),
(how to enable Complete Memory Dump),
(how to enable Complete Memory Dump on Windows 7 when PC has lots of memory...normally not available when more than 2GB of memory)
Dump Analysis Tools
Dump related Tools
Kernel Debugging Virtual Machines
Videos
(plus various other ones at Pluralsight)
Blogs
Some blogs (mixture of native and managed code debugging).
Advanced Articles and Tutorial Resources
Alternative Debuggers
Other Links
- huge collection of debugger and system level tools
- huge collection of plugins and other debugging tools
- large collection of links giving you detailed information that you would need if you wanted to write your own debugger e.g. PDB file format, .DMP file formats, PE File structure, how to record stack traces, etc, etc.
- unpackers, IDA, OllyDBG, Immunity Debugger plugins, etc.
这是一个非常广泛的问题。
!analyze -v
对其进行基本分析。 您需要为您的代码提供可用的符号信息,以使转储文件有价值。网站内存转储、软件跟踪、调试、恶意软件、受害者软件和情报分析门户 对我来说信息非常丰富。 我也非常喜欢这本书,高级 Windows 调试 作者:马里奥·休沃特和丹尼尔·普拉瓦特。
This is a really broad question.
!analyze -v
to get a basic analysis performed on it. You need to have symbol information available for your code to make dump files worthwhile.The website Memory Dump, Software Trace, Debugging, Malware, Victimware and Intelligence Analysis Portal has been very informative for me. I also really enjoyed the book, Advanced Windows Debugging by Mario Hewardt and Daniel Pravat.