调试实战 | 通过转储文件分析程序无响应之使用 windbg + IDA 逆向篇

本文介绍了如何通过windbg和IDA分析远程机器上抓取的dump文件,解决一个由死锁导致的界面无响应问题。作者详细展示了分析主线程和工作线程调用栈的过程,以及如何定位和修复问题,强调了windbg的强大支持在整个分析过程中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

缘起

最近,接连在项目中遇到了两个界面无响应的问题。都只发生在客户特定机器上,不方便直接调试,只能抓取 dump 进行事后分析了。

抓取 dump

远程连上可以重现问题的机器,使用 process explorer 初步观察卡死的进程,发现 CPU 占用率很低,经过一段时间的观察,基本确定是一个死锁问题。在卡死的进程上右键,保存完整转储,压缩,发回本地进行分析。

使用 windbg 进行分析

双击抓取的 dump 文件,因为之前已经执行过 windbg.exe -IA,所以默认会通过 windbg 打开 dump 文件。先使用 ~*kvn 粗略浏览一下每个线程的调用栈(因为比较长,这里就不截图了)。经过观察,很快锁定了两个值得进一步查看的线程:一个是主线程(界面线程),因为是界面无响应,肯定要关注界面线程。另外一个是 7 号工作线程。分别看一下这两个线程的调用栈。

主线程的调用栈如下图所示:

注意上图红色高亮部分,主线程通过 SleepConditionVariableCS() 进入等待。

看完主线程,再看 7 号工作线程的调用栈,如下图所示:

7 号线程对 SendMessage() 的调用非常值得怀疑。

猜测整个流程是这样的:主线程不知由于什么原因进入等待状态,而工作线程由于各种各样的原因也进入了等待状态。其中 7 号线程最明显,因为它正在发消息,而主线程此时是无论如何也不会响应这个消息的。

于是,典型的死锁再一次发生了。

加载 AssemblyDesign_Tools.dll 的符号后,查看对应的源码,消除对 SendMessage() 的调用,问题解决!so easy!

说明:工作线程中并没有直接调用 SendMessage(),而是调用了操作界面的相关 API,间接调用了 SendMessage()  给界面线程发消息。

死锁的问题解决了,但是为什么向主线程发个消息就死锁了呢?秉着打破砂锅问到底的原则,我又开始折腾了。下面的内容适合喜欢调试逆向的极客阅读。

深入调查

最开始的思路是:查看主线程在等待的条件变量,然后再调查哪个工作线程会唤醒这个条件变量。奈何 64 位下,前四个参数通过寄存器 RCX, RDX, r8, r9 进行传递,如果这些寄存器没有在栈上存储一份的话&

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值