`
v5browser
  • 浏览: 1133409 次
社区版块
存档分类
最新评论

windbg调试命令4(用户层.dump)

 
阅读更多
Windbg生成dump文件的方法:
程序崩溃(crash)的时候, 为了以后能够调试分析问题, 可以使用WinDBG要把当时程序内存空间数据都保存下来,生成的文件称为dump 文件。 步骤:
1) 打开WinDBG并将之Attach 到crash的程序进程
2) 输入产生dump 文件的命令
WinDBG产生dump 文件的命令是 .dump ,可以选择不同的参数来生成不同类型的dump文件。
选项(1): /m
命令行示例:.dump /m C:\dumps\myapp.dmp
注解: 缺省选项,生成标准的minidump, 转储文件通常较小,便于在网络上通过邮件或其他方式传输。 这种文件的信息量较少,只包含系统信息、加载的模块(DLL)信息、 进程信息和线程信息。
选项(2): /ma
命令行示例:.dump /ma C:\dumps\myapp.dmp
注解: 带有尽量多选项的minidump(包括完整的内存内容、句柄、未加载的模块,等等),文件很大,但如果条件允许(本机调试,局域网环境), 推荐使用这中dump。
选项(3):/mFhutwd
命令行示例:.dump /mFhutwd C:\dumps\myapp.dmp
注解:带有数据段、非共享的读/写内存页和其他有用的信息的minidump。包含了通过minidump能够得到的最多的信息。是一种折中方案

那怎么自动生成dump文件呢,比如对方的电脑没有windbg,这里用到一个window系统自带工具,Dr.Watson

运行方式很简单:

直接run-输入drwtsn32 -i就可以了,会提示这样的:

这个命令真难记,实话,记华生医生吧,福尔摩斯中的

如果有程序崩溃,会自动生成dump,这时再输入drwtsn32就会运行这个程序:

找到对应路径的DMP文件就行了,一般放在如下路径:
C:\Documents and Settings\All Users\Application Data\Microsoft\Dr Watson

以下实例来自AWD

代码:

/*++
  1. Copyright(c)AdvancedWindowsDebugging(ISBN0321374460)fromAddison-WesleyProfessional.Allrightsreserved.
  2. THISCODEANDINFORMATIONISPROVIDED"ASIS"WITHOUTWARRANTYOFANY
  3. KIND,EITHEREXPRESSEDORIMPLIED,INCLUDINGBUTNOTLIMITEDTOTHE
  4. IMPLIEDWARRANTIESOFMERCHANTABILITYAND/ORFITNESSFORAPARTICULAR
  5. PURPOSE.
  6. --*/
  7. #include"stdafx.h"
  8. #include<windows.h>
  9. #include<stdio.h>
  10. #include<conio.h>
  11. VOIDSimulateMemoryCorruption();
  12. classCAppInfo
  13. {
  14. public:
  15. CAppInfo(LPWSTRwszAppName,LPWSTRwszVersion)
  16. {
  17. m_wszAppName=wszAppName;
  18. m_wszVersion=wszVersion;
  19. }
  20. VOIDPrintAppInfo()
  21. {
  22. wprintf(L"\nFullapplicationName:%s\n",m_wszAppName);
  23. wprintf(L"Version:%s\n",m_wszVersion);
  24. }
  25. private:
  26. LPWSTRm_wszAppName;
  27. LPWSTRm_wszVersion;
  28. };
  29. CAppInfo*g_AppInfo;
  30. int__cdeclwmain(intargc,WCHAR*args[])
  31. {
  32. wint_tiChar=0;
  33. g_AppInfo=newCAppInfo(L"MemoryCorruptionSample",L"1.0");
  34. if(!g_AppInfo)
  35. {
  36. return1;
  37. }
  38. wprintf(L"Press:\n");
  39. wprintf(L"1Todisplayapplicationinformation\n");
  40. wprintf(L"2Tosimulatedmemorycorruption\n");
  41. wprintf(L"3Toexit\n\n\n>");
  42. while((iChar=_getwche())!='3')
  43. {
  44. switch(iChar)
  45. {
  46. case'1':
  47. g_AppInfo->PrintAppInfo();
  48. break;
  49. case'2':
  50. SimulateMemoryCorruption();
  51. wprintf(L"\nMemoryCorruptioncompleted\n");
  52. break;
  53. default:
  54. wprintf(L"\nInvalidoption\n");
  55. }
  56. wprintf(L"\n\n>");
  57. }
  58. return0;
  59. }
  60. VOIDSimulateMemoryCorruption()
  61. {
  62. char*pszWrite="Corrupt";
  63. BYTE*p=(BYTE*)g_AppInfo;
  64. CopyMemory(p,pszWrite,strlen(pszWrite));
  65. }
/*++
Copyright (c) Advanced Windows Debugging (ISBN 0321374460) from Addison-Wesley Professional.  All rights reserved.

    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
    KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
    PURPOSE.

--*/
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>

VOID SimulateMemoryCorruption ( ) ;

class CAppInfo
{
public: 
    CAppInfo(LPWSTR wszAppName, LPWSTR wszVersion)
    {
        m_wszAppName=wszAppName;
        m_wszVersion=wszVersion;
    }

    VOID PrintAppInfo()
    {
        wprintf(L"\nFull application Name: %s\n", m_wszAppName);
        wprintf(L"Version: %s\n", m_wszVersion);
    }

private:
    LPWSTR m_wszAppName ;
    LPWSTR m_wszVersion ;
} ;

CAppInfo* g_AppInfo ;

int __cdecl wmain (int argc, WCHAR* args[])
{
    wint_t iChar = 0 ;
    g_AppInfo = new CAppInfo(L"Memory Corruption Sample", L"1.0" );
    if(!g_AppInfo)
    {
        return 1;
    }

    wprintf(L"Press: \n");
    wprintf(L"    1    To display application information\n");
    wprintf(L"    2    To simulated memory corruption\n");
    wprintf(L"    3    To exit\n\n\n>");

    while((iChar=_getwche())!='3')
    {
        switch(iChar)
        {
            case '1':
               g_AppInfo->PrintAppInfo();
               break;

            case '2':
              SimulateMemoryCorruption();
              wprintf(L"\nMemory Corruption completed\n");
              break;

            default:
              wprintf(L"\nInvalid option\n");
        }
        wprintf(L"\n\n> ");
    }
    return 0;
}


VOID SimulateMemoryCorruption ( )
{
    char* pszWrite="Corrupt";
    BYTE* p=(BYTE*) g_AppInfo;
    CopyMemory(p, pszWrite, strlen(pszWrite));
}

编译,生成Release,运行,选1再选2再选1,程序崩溃,打开Dump:

0:000> lm
start end module name
00400000 00406000 test1 (deferred)
62c20000 62c29000 lpk (deferred)
73fa0000 7400b000 usp10 (deferred)
76300000 7631d000 imm32 (deferred)
76d70000 76d92000 apphelp (deferred)
77bd0000 77bd8000 version (deferred)
77d10000 77da0000 user32 (deferred)
77da0000 77e49000 advapi32 (deferred)
77e50000 77ee3000 rpcrt4 (deferred)
77ef0000 77f39000 gdi32 (deferred)
77fc0000 77fd1000 secur32 (deferred)
78520000 785c3000 msvcr90 (private pdb symbols) c:\mysymbol\msvcr90.i386.pdb\3ADD2E755BC041BC9149BFBE7C33387C1\msvcr90.i386.pdb
7c800000 7c91e000 kernel32 (deferred)
7c920000 7c9b6000 ntdll (pdb symbols) c:\mysymbol\ntdll.pdb\CEFC0863B1F84130A11E0F54180CD21A2\ntdll.pdb

加载符号文件:
0:000> .sympath+ D:\Project1\test1\Release
Symbol search path is: C:\WINDOWS\Symbols;SRV*c:\mysymbol* http://msdl.microsoft.com/download/symbols ;D:\Project1\test1\Release
WARNING: Whitespace at end of path element
0:000> .reload /f
..............
Loading unloaded module list
.........
0:000> lm
start end module name
00400000 00406000 test1 (private pdb symbols) D:\Project1\test1\Release\test1.pdb
62c20000 62c29000 lpk (pdb symbols) C:\WINDOWS\Symbols\dll\lpk.pdb
73fa0000 7400b000 usp10 (pdb symbols) c:\mysymbol\usp10.pdb\D4BA2952809F469BB6D1D3AF6B956E6B1\usp10.pdb
76300000 7631d000 imm32 (pdb symbols) C:\WINDOWS\Symbols\dll\imm32.pdb
76d70000 76d92000 apphelp (pdb symbols) C:\WINDOWS\Symbols\dll\apphelp.pdb
77bd0000 77bd8000 version (pdb symbols) C:\WINDOWS\Symbols\dll\version.pdb
77d10000 77da0000 user32 (pdb symbols) C:\WINDOWS\Symbols\dll\user32.pdb
77da0000 77e49000 advapi32 (pdb symbols) c:\mysymbol\advapi32.pdb\F759D3F1C6614313B07C84BC33F02E4D2\advapi32.pdb
77e50000 77ee3000 rpcrt4 (pdb symbols) c:\mysymbol\rpcrt4.pdb\1A465C67828242F28A8C70E3B9D5C4772\rpcrt4.pdb
77ef0000 77f39000 gdi32 (pdb symbols) c:\mysymbol\gdi32.pdb\372C0F0E08FB456EAB7B4CB2B53E27952\gdi32.pdb
77fc0000 77fd1000 secur32 (pdb symbols) c:\mysymbol\secur32.pdb\7867B3F28B5C41CE847895E3FC013DC52\secur32.pdb
78520000 785c3000 msvcr90 (private pdb symbols) c:\mysymbol\msvcr90.i386.pdb\3ADD2E755BC041BC9149BFBE7C33387C1\msvcr90.i386.pdb
7c800000 7c91e000 kernel32 (pdb symbols) c:\mysymbol\kernel32.pdb\072FF0EB54D24DFAAE9D13885486EE092\kernel32.pdb
7c920000 7c9b6000 ntdll (pdb symbols) c:\mysymbol\ntdll.pdb\CEFC0863B1F84130A11E0F54180CD21A2\ntdll.pdb

查看堆栈:

0:000> kb
ChildEBP RetAddr Args to Child
0012ff20 78556215 785b73c8 004020f4 00000000 msvcr90!_woutput_l+0x94c [f:\dd\vctools\crt_bld\self_x86\crt\src\output.c @ 1624]
0012ff64 004010ba 004020f4 72726f43 00403380 msvcr90!wprintf+0x73 [f:\dd\vctools\crt_bld\self_x86\crt\src\wprintf.c @ 63]
0012ff7c 00401252 00000001 00392940 00392998 test1!wmain+0xba [d:\project1\test1\test1\test1.cpp @ 58]
0012ffc0 7c817077 00300031 0032002d 7ffdc000 test1!__tmainCRTStartup+0x10f [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 583]
0012fff0 00000000 0040139a 00000000 78746341 kernel32!BaseProcessStart+0x23

看下58行代码,使用了g_AppInfo->PrintAppInfo();

我们猜测,g_AppInfo的两个成员无效,因为wprintf调用的就是它们

找到g_AppInfo,列出它的成员:

0:000> x test1!*g_*
00403374 test1!g_AppInfo = 0x00395b10
004022f0 test1!_load_config_used = struct IMAGE_LOAD_CONFIG_DIRECTORY32_2
00402098 test1!_imp___amsg_exit = <no type information>
004014fa test1!_amsg_exit = <no type information>
0:000> dt CAppInfo 0x00395b10
test1!CAppInfo
+0x000 m_wszAppName : 0x72726f43 "--- memory read error at address 0x72726f43 ---"
+0x004 m_wszVersion : 0x00747075 "???"

注意,这里dt要用CAppInfo告诉它解析的地址类型

那我们再来看看这两个局变量的内容:

0:000> dt CAppInfo 0x00395b10
test1!CAppInfo
+0x000 m_wszAppName : 0x72726f43 "--- memory read error at address 0x72726f43 ---"
+0x004 m_wszVersion : 0x00747075 "???"
0:000> !address 0x72726f43
62c29000 : 62c29000 - 11377000
Type 00000000
Protect 00000001 PAGE_NOACCESS
State 00010000 MEM_FREE
Usage RegionUsageFree
0:000> !address 0x00747075
005f0000 : 005f0000 - 001be000
Type 00020000 MEM_PRIVATE
Protect 00000004 PAGE_READWRITE
State 00001000 MEM_COMMIT
Usage RegionUsageIsVAD

我们发现第一个变量竟然是不可访问的,找到问题了,

0:000> dc 0x00395b10
00395b10 72726f43 00747075 00020201 000801c2 Corrupt.........
00395b20 6c75460a 7061206c 63696c70 6f697461 .Full applicatio
00395b30 614e206e 203a656d 64657465 4320790a n Name: eted.y C
00395b40 7572726f 6f697470 6153206e 656c706d orruption Sample
00395b50 0000000a 00000000 00000000 00000000 ................
00395b60 00000000 00000000 00000000 00000000 ................
00395b70 00000000 00000000 00000000 00000000 ................
00395b80 00000000 00000000 00000000 00000000 ................

原来第一个变量竟然成了字符串Corrupt,查看代码,我们发现在按2时,程序强行把字符串"Corrupt"写入了

一些的指导性的建议和策略:

1通过命令dc将指针的内存内容转储出来,dc可以将内存内容以双字形式转储出来,如果在输出中看到有任何的字符串,那么可以通过命令da或du把字符串转储出来

2通过!address收集关于内存的信息,!address可以告诉你内存的类型(如私有内存),保护级别(读取和写入),状态(已提交或保留)和用途(栈或堆)

3.通过dds命令将内存转储为双字或者符号,这有助于将内存和特定的类型关联起来,

4.通过dpp命令对指针解引用,并且以双字形式转储出内存的内容,如果有任何一个双字匹配某个符号,那么这个符号也会被显示,如果在指针指向的内存中包含了一个虚函数表,那么

这种技术是非常有用的

5.通过dpa和dpu将指针指向的内存分别显示为ASII格式和Unicode格式

6.如果内存的内容是个很小的数值(4的值数)那么它可能是一个句柄,可以通过!handle来转储这个句柄的信息.

分享到:
评论

相关推荐

    windbg调试命令大全

    windbg调试命令大全 Windbg是在windows平台下,强大的用户态和内核态调试工具。相比较于Visual Studio,它是一个轻量级的调试工具,所谓轻量级指的是它的安装文件大小较小,但是其调试功能,却比VS更为强大。它的...

    windbg调试工具安装和使用说明.doc

    WinDbg是微软发布的一款源码级(source-level)调试工具,可以用于Kernel内核模式调试和用户模式调试,还可以调试Dump文件。 本文档主要介绍了WinDbg工具的安装和配置方法,以及WinDbg常用命令和使用说明。

    Windbg调试32位.net程序产生的64位dump的扩展soswow64.dll

     用windbg打开dump后,依次执行以下命令:.loadby sos clr\!wow64exts.sw\.load soswow64即可。更详细的说明,可去Gibhub的源码目录查看。 BLOG地址:http://write.blog.csdn.net/postedit/52635628

    WinDbg 工具

    虽然windbg也提供图形界面操作,但它最强大的地方还是有着强大的调试命令,一般情况会结合GUI和命令行进行操作,常用的视图有:"thread","stack" 和"command",其中command视图是默认打开的。 下面简单介绍常用的...

    windbg的两个chm教程,一个是入门教程,另外一个是提高教程

    WinDbg是微软开发的免费源码级调试工具。Windbg可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件. 文章主要介绍了WINDBG的主要功能以及相关的命令和WINDBG的基本调试技术

    神器windbg最新版

    虽然windbg也提供图形界面操作,但它最强大的地方还是有着强大的调试命令,一般情况会结合GUI和命令行进行操作,常用的视图有:"thread","stack" 和"command",其中command视图是默认打开的。 下面简单介绍常用的...

    WinDbg6.12

    虽然windbg也提供图形界面操作,但它最强大的地方还是有着强大的调试命令,一般情况会结合GUI和命令行进行操作,常用的视图有:"thread","stack" 和"command",其中command视图是默认打开的。 下面简单介绍常用的...

    windbg资料集合

    Windbg可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件。在DotNet方面WinDbg是调试分析SSCLI的最佳工具,同时可以和SOS扩展一起调试分析.net程序。最近一段时间项目需要学习了一下,有感于WinDbg功能的...

    WinDebug用法详解

    WinDBG 是个非常强大的调试器,它设计了极其丰富的功能来支持各种调试任务,包括用户 态调试、 内核态调试、 调试转储文件、 远程调试等等。 WinDBG 具有非常大的灵活性和可扩展性, 用来满足各种各样的调试需求,...

    Accelerated-Windows-Memory-Dump-Analysis-Public

    windbg常见调试命令学习和分析调试技巧。

    wdbgark:WinDBG Anti-RootKit扩展

    WinDBG Anti-RootKit扩展 前言 是的扩展(动态库)。 它的主要目的是使用内核调试器查看和分析Windows内核中的异常。 可以查看各种系统回调,系统表,对象类型等。 对于更用户友好的视图扩展,请使用DML。 对于...

    Windows驱动开发技术详解的光盘-part1

     从Windows最基本的两类驱动程序的编译、安装、调试入手讲解,非常容易上手,用实例详细讲解PCI、USB、虚拟串口、虚拟摄像头、SDIO等驱动程序的开发,归纳了多种调试驱动程序的高级技巧,如用WinDBG和VMWARE软件对...

    windows驱动开发技术详解-part2

    用WinDBG和VMWARE软件对驱动进行源码级调试,深入Windows操作系统的底层和内核,透析Windows驱动 开发的本质。 本书是作者结合教学和科研实践经验编写而成的,不仅详细介绍了Windows内核原理,而且介绍了编程技 巧...

    pwndbg:使用GDB轻松进行开发和逆向工程

    那是2020年,GDB仍然缺少hexdump命令! GDB的语法很神秘,很难处理。 当Windbg用户偶尔需要进入GDB时,他们会完全迷路。什么? Pwndbg是直接加载到GDB中的Python模块,并提供了一套实用程序和拐杖来破解GDB的所有残

Global site tag (gtag.js) - Google Analytics