境界
发布于 2025-09-19 / 2 阅读 / 0 评论 / 0 点赞

Windows程序崩溃到dll的一种问题查找方法

1. 问题

本文介绍一种借助IDA反汇编工具来查看Windows程序崩溃日志的方法。

在长时间压测Windows应用程序时,如果使用Release版本直接运行,而非使用debug模式运行,则在程序崩溃的时候,往往能留下的信息就只有程序本身自己输出的日志文件(如果有的话),以及Windows日志内的相关的程序错误。

这时我们往往感觉无从下手。本文给出一种方法,根据Windows日志内的信息寻找崩溃的蛛丝马迹。

2. 工具

IDA:反汇编工具,可以读取dll文件,加载其对应的pdb文件,分析dll文件内的所有函数,并绘制出调用流程,帮助理解分析dll本身的代码结构。

下载:(免费版就够用)

https://hex-rays.com/ida-free

symChk.exe: 微软官方的符号文件检查及下载工具。可用来下载Windows系统自带的dll对应的pdb符号文件。

安装方法:安装WinDbg工具,附带这个工具。

安装WinDbg(免费):参考:https://learn.microsoft.com/zh-cn/windows-hardware/drivers/debugger/

3. 步骤

以一个例子来说明怎么处理Windows日志内的程序崩溃信息。

假设有个程序崩溃,被Windows日志记录了一次错误:

错误类型:Application Error

出错模块名称:ntdll.dll

异常代码:0xc0000374

错误偏移:0x000000000011a3b5

好,就根据这些信息来分析。

3.1 解析错误码

可以在网上直接搜索上面这个异常代码。经搜索,此错误码的意思是堆被损坏。通常是因为缓冲区溢出(被写冒)、访问了已经被释放的内存区域、多线程访问未保护等原因引起。主要错误就是错误的写入操作破坏了某些函数入口所在的内存区域,造成了对这个函数的访问发生错误。

3.2 查看错误偏移位置对应的函数

给出的错误偏移位置,是相对于这个dll加载到内存之后,在dll加载的起始位置之后的偏移量。所以,我们得先能打开这个dll,找到这个偏移量对应的dll内的函数是什么。

我们用IDA工具加载这个dll,过程中,IDA会提示是否要加载对应pdb。如果没有pdb,那IDA只能猜测一些函数的名字,或者用记号来表示,很多时候并不能明确知道这个函数是干什么的。有了pdb,就可以直接拿到这个函数的名字,能方便理解。

我们再使用symchk工具去下载ntdll.dll对应的函数表。

symchk工具的默认的安装位置(必须在安装了windbg工具之后才有):

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64

可以把它放到系统环境变量的Path里面,这样就可以不用带全路径使用这个工具。

(1)以管理员身份打开“命令提示符”窗口,cd 到 ntdll.dll所在的目录:C:\Windows\System32

(2)命令:symchk.exe /v ntdll.dll。 只要网络正常,稍等片刻,ntdll.dll的pdb文件就放到了 C:\WINDOWS\SYMBOLS\ntdll.pdb\ 下面。

然后,用IDA工具加载ntdll.dll,并从上述pdb目录加载ntdll.pdb。

IDA工具会加载ntdll.dll内的所有段及函数表,以及函数之间的调用关系图:

注意,这个ntdll.dll的加载基地址不是0,是 0x0000000180001000。那我们要找的偏移位置对应的dll的位置就是:

0x0000000180001000 + 0x000000000011a3b5 = 0x18011B3B5

使用菜单:Jump--Jump to Address... ,输入上述地址,会在右侧的框图上定位到对应的指令位置。可以上下查看框图来梳理这个位置的调用关系。

在左侧函数列表中,可以查看各个函数对应的地址段。我们可以发现这个地址位置对应的函数是:RtlpLookupSafeCurDirList ,这时就可以去网上或者AI中去搜索这个函数是干什么的了。

3.3 用于自己的程序

上面这个方法也同样可以用于自己程序的dll的查找。是一样的部署。使用IDA工具加载报错的dll,通过偏移位置找到报错的指令以及函数。如果有pdb和原代码,还可以定位到代码行。然后再利用AI去帮忙分析代码中可能存在的问题并进行修改。


评论