WindbgPreview 分析dmp 文件

实现一个可以生成dmp文件的代码

代码可直接复制、编译

#include <iostream>
#include <windows.h>
#include <dbghelp.h>
#pragma comment (lib, "dbghelp.lib")
#include <conio.h>
#include <tchar.h>
using namespace std;

/* 未捕获异常过滤函数 */
LONG WINAPI ExpFilter(struct _EXCEPTION_POINTERS* pExp) {

    HANDLE hFile = CreateFile(
        _T("C:\\Users\\win10\\Desktop\\test.dmp"),/* 自定义 生成dmp文件的路径 */
        GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (INVALID_HANDLE_VALUE != hFile) {

        MINIDUMP_EXCEPTION_INFORMATION einfo;
        einfo.ThreadId = GetCurrentThreadId();
        einfo.ExceptionPointers = pExp;
        einfo.ClientPointers = FALSE;

        MiniDumpWriteDump(	/* 需包含头文件#include <dbghelp.h> 与链接文件#pragma comment (lib, "dbghelp.lib") */
            GetCurrentProcess(),
            GetCurrentProcessId(),
            hFile,
            MiniDumpWithFullMemory,/* 获取所有内存dmp */
            &einfo,
            NULL,
            NULL);

        CloseHandle(hFile);
    }

    return EXCEPTION_EXECUTE_HANDLER;
}

/* 开启未捕获异常过滤函数 修改_XcptFilter硬编码,直接返回EXCEPTION_CONTINUE_SEARCH */
void StartUnhandledExceptionFilter() {

    /* 
        替换调用进程中所有已有线程和所有将来新创建线程的顶级异常过滤函数
        调用此函数后,如果在未调试的进程中发生异常,并且这些异常没有被捕获时,
        系统就会调用SetUnhandledExceptionFilter设置的函数
    */
    SetUnhandledExceptionFilter(ExpFilter);

    /*
        链接器在链接可执行文件时,选择正确的C/C++运行库运行函数
        在此运行库函数中调用的main函数
        查看调用堆栈 可以看到 此运行库函数为 mainCRTStartup
        调用main函数相关代码如下:

        try {
            ...
            调用main函数
            ...
        }
        __except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation())) {
            _exit( GetExceptionCode() );
        }

        产生异常时,首先会调用_XcptFilter,之后才会被 ExpFilter 处理,堆栈可能会产生变动
        修改_XcptFilter,让其直接返回 EXCEPTION_CONTINUE_SEARCH(0),
        表示异常没有被识别到,异常继续往上层抛,直到SetUnhandledExceptionFilter设置的未捕获异常过滤函数
    */
    HMODULE hModule = LoadLibrary(_T("msvcrt.dll"));

    if (NULL != hModule) {
        void* _XcptFilter = (void*)GetProcAddress(hModule, "_XcptFilter");

        if (NULL != _XcptFilter) {
            DWORD dwOldProtect;
            VirtualProtect(_XcptFilter, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
            VirtualProtect(_XcptFilter, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
            *(char*)_XcptFilter = 0x33;
            *((char*)_XcptFilter + 1) = 0xc0;
            *((char*)_XcptFilter + 2) = 0xc2;
            *((char*)_XcptFilter + 3) = 0x00;
            *((char*)_XcptFilter + 4) = 0x00;
            VirtualProtect(_XcptFilter, 5, dwOldProtect, &dwOldProtect);
        } 
    }    
}


int main() {

    cout << "begin" << endl;

    StartUnhandledExceptionFilter();

    int i = 0;
    i = i / i;	/* 产生一个未处理的除零异常 */

    cout << "end" << endl;

    return 0;
}

在这里插入图片描述

WindbgPreview 分析dmp 文件

WindbgPreview —> 左上角 文件 —> Start debugging —> Open dump file —> 找到dmp文件 —> 打开
在这里插入图片描述

正常打开完毕,应该是这样的界面:
正常打开后,应该是这样的界面

设置pdb符号路径 与 源码路径
设置pdb符号路径 与 源码路径
这里需要注意到一个问题:
如果源代码并不是当初编译此程序的那份源代码,WindbgPreview展示的异常位置可能有误。

WindbgPreview的自动化分析

  1. 进入符号模糊匹配模式:!sym noisy on
  2. 加载pdb:.reload /i
  3. 自动化分析:!analyze -v
    在这里插入图片描述

排查问题

  1. 阅读附近代码,我们会发现 i = i / i 被除数为0,修改代码解决问题
  2. 用WindbgPreview继续排查
    1. 切换到异常线程:.ecxr
    2. 打印异常堆栈:kvn
      在这里插入图片描述
      进入到了刚才的问题现场,这时我们再输入 r 命令,接着输入u命令(目的是为了多打印一些崩溃点代码上下文),看崩溃现场详细信息:
      在这里插入图片描述
      在这里插入图片描述
      我们可以看到 idiv eax,dword ptr [ebp-8] 有符号除法,这里为 eax 除以 ebp - 8 位置的值
      可以看到 [ebp-8] ss:002b:0114f97c=00000000
      被除数为0,所以出错

参考

https://zhuanlan.kanxue.com/article-364.htm
https://blog.csdn.net/u010588861/article/details/41350647
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要使用WinDbg Preview分析dmp文件,你可以在Microsoft Store中下载并安装WinDbg Preview应用程序\[1\]。安装Windows SDK时,也可以选择只安装WinDbg这个组件\[2\]。以下是简单分析dmp文件的步骤: 1)打开WinDbg Preview应用程序。 2)通过菜单“File”->“Open Crash Dump”打开dmp文件。 3)文件打开后,WinDbg Preview会列出产生dump文件的设备的系统版本和运行时间等相关信息\[2\]。 请注意,使用WinDbg Preview分析dmp文件可能需要一些基本的调试知识和经验。如果你在使用过程中遇到问题,建议与你周围的同事交流并请教,因为不同版本的WinDbg界面可能略有差异\[3\]。 #### 引用[.reference_title] - *1* *3* [WinDbg:入门分析 dmp 文件『一』](https://blog.csdn.net/qq_33154343/article/details/123563647)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [使用WinDbg分析Windows dump文件方法](https://blog.csdn.net/jetliu05/article/details/122467974)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值