首页
社区
课程
招聘
[旧帖] [原创]使用windbg分析安装程序hang问题 附windbg入门须知 申请邀请码 0.00雪花
发表于: 2010-6-22 14:04 3523

[旧帖] [原创]使用windbg分析安装程序hang问题 附windbg入门须知 申请邀请码 0.00雪花

2010-6-22 14:04
3523
前两天用windbg分析的一个应用程序安装过程中hang住,无法完成, 和大家分享一下,顺便希望能够换取邀请码。

解决的过程比较曲折, 当然也花了很多时间去研究,最后从安装文件生成的log file看出,安装在即将进行某一项操作时停止了,安装程序要调用一个自身的程序来对系统进行清理,这个过程首先由msi安装工具初始化之后再调用该程序,经过分析发现安装停止时该程序并不在进程列表中,但是里面多了一个msie1a7.tmp, 分析发现每次问题重现,都会出现一个类似的临时进程,所以着手对该进程进行了分析:

lkd> !process 0 2 msie1a7.tmp
PROCESS 87810d40  SessionId: 1  Cid: 13d4    Peb: 7ffdf000  ParentCid: 1624
    DirBase: cea9d7e0  ObjectTable: 890bb130  HandleCount: 126.
    Image: MSIE1A7.tmp

        THREAD 8710b030  Cid 13d4.0568  Teb: 7ffde000 Win32Thread: ffa51538 WAIT: (UserRequest) UserMode Non-Alertable
            86dd8cf8  Thread
            8682d5a0  Semaphore Limit 0x1

        THREAD 8780a620  Cid 13d4.13dc  Teb: 7ffdd000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
            875950b0  NotificationEvent
            86e09490  NotificationEvent

        THREAD 873244e8  Cid 13d4.137c  Teb: 7ffdc000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Alertable
            871ebc80  SynchronizationTimer
            870e8030  SynchronizationTimer
            86f27f68  SynchronizationTimer

        THREAD 86dd8cf8  Cid 13d4.1358  Teb: 7ffd8000 Win32Thread:fe6e1bc0 WAIT: (WrLpcReply) UserMode Non-Alertable
            86dd8f2c Semaphore Limit 0x1

        THREAD 86a906f0  Cid 13d4.1350  Teb: 7ffd7000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
            86eb7170  Semaphore Limit 0x7fffffff

        THREAD 86d92d48  Cid 13d4.13e8  Teb: 7ffda000 Win32Thread: 00000000 WAIT: (WrQueue) UserMode Alertable
            8634ccf8  QueueObject

经过研究发现线程 86dd8cf8 肯能对我们的帮助最大(其实就是分析了其他线程,但是没有得到有用的结果):

lkd> !thread 86dd8cf8
THREAD 86dd8cf8  Cid 13d4.1358  Teb: 7ffd8000 Win32Thread: fe6e1bc0 WAIT: (WrLpcReply) UserMode Non-Alertable
    86dd8f2c  Semaphore Limit 0x1
Waiting for reply to  ALPC Message8897ae78 : queued at port 855a1e48 : owned by process 85581d40
Not impersonating
DeviceMap                 95f9f640
Owning Process            87810d40       Image:         MSIE1A7.tmp
Attached Process          N/A            Image:         N/A
Wait Start TickCount      222754         Ticks: 5148713 (0:22:18:40.437)
Context Switch Count      59            
UserTime                  00:00:00.015
KernelTime                00:00:00.062
Win32 Start Address 0x6502c3e0
Stack Init a15cbfd0 Current a15cbad0 Base a15cc000 Limit a15c9000 Call 0
Priority 9 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Kernel stack not resident.

让我们来看看是谁在占用着 8897ae78:

lkd> !alpc /m 8897ae78

Message @ 8897ae78
  MessageID             : 0x00AC (172)
  CallbackID            : 0x319A4 (203172)
  SequenceNumber        : 0x00000004 (4)
  Type                  : LPC_REQUEST
  DataLength            : 0x00C8 (200)
  TotalLength           : 0x00E0 (224)
  Canceled              : No
  Release               : No
  ReplyWaitReply        : No
  Continuation          : Yes
  OwnerPort             : 8785f038 [ALPC_CLIENT_COMMUNICATION_PORT]
  WaitingThread         : 86dd8cf8
  QueueType             : ALPC_MSGQUEUE_PENDING
  QueuePort             : 855a1e48 [ALPC_CONNECTION_PORT]
  QueuePortOwnerProcess : 85581d40 (IssueApplication)
  ServerThread          : 86fa0d48
  QuotaCharged          : No
  CancelQueuePort       : 00000000
  CancelSequencePort    : 00000000
  CancelSequenceNumber  : 0x00000000 (0)
  ClientContext         : 002d1a68
  ServerContext         : 00000000
  PortContext           : 0023b938
  CancelPortContext     : 00000000
  SecurityData          : 00000000
  View                  : 00000000
  
最后我们在看看86fa0d48是哪个进程里面的:

lkd> !thread 86fa0d48
THREAD 86fa0d48  Cid 10b8.0da0  Teb: 7ffd4000 Win32Thread: fe959008 WAIT: (UserRequest) UserMode Non-Alertable
    872a3cc8  NotificationEvent
Not impersonating
DeviceMap                 8c4050a8
Owning Process            85581d40       Image:         IssueApplication.exe
Attached Process          N/A            Image:         N/A
Wait Start TickCount      5372828        Ticks: 9932 (0:00:02:34.940)
Context Switch Count      1114            
UserTime                  00:00:00.000
KernelTime                00:00:00.000
Win32 Start Address ntdll!TppWorkerThread (0x7713d63e)
Stack Init a077bfd0 Current a077bbc8 Base a077c000 Limit a0779000 Call 0
Priority 9 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Kernel stack not resident.

最后我们发现是IssueApplication.exe占用了安装进程里面需要的一个kernel 级的句柄,并且IssueApplication.exe自身也存在hang,所以无法释放给句柄。

最后我们用windbg attach到IssueApplication.exe上用,!analyze -hang -v 命令分析,直到原来IssueApplication.exe里面某个线程创建了一个event,CreateEvent(...), 另一个线程调用了WaitForSingleObject(...)等待该创建出来的event,但是SetEvent(...)的动作由于某些原因不会被执行并最终导致了安装程序无法正常运行。

IssueApplication.exe的分析由于种种原因就不给大家看了, 很简单 !analyze -hang 之后就知道在的那个handle,之后分析代码,得出了最终的结论。

谢谢,不知道能不能换取一邀请码,哈哈

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 188
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
放便需要使用vmware进行kernel debug的朋友,
使用步骤详见:http://virtualkd.sysprogs.org/

如果有问题,可以跟帖,我可以做简单翻译,或者介绍。
毕竟对虚拟机内核调试应用比较少,在此就不翻译了,需要可以联系
附件中文件解压后都在放在同一文件夹
上传的附件:
2010-6-23 11:14
0
雪    币: 188
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
闲着没事儿,写点最近用的东西吧,也算给自己个交待

Windbg是微软 提供的应用程序,可以在http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx#b下载,Windbg 提供了usermode和kernelmode的调试支持,免费,支持源码级调试。

第一步首先要配置windbg的符号文件路径:

对于microsoft的公共符号文件可以从ms的官方服务器上获得,并且只能由调试器获得:.sympath SRV*f:\localsymbols*http://msdl.microsoft.com/download/symbols,对于你自己的符号文件(*.pdb),也要告诉windbg,加在上一个对话框中即可,如果指定了多个路径,彼此之间用分号分隔。如果调试过程中更新符号文件,需要用 .reload命令重新加载符号文件。

pdb文件即符号文件之所以重要是因为它里面包含了所有的调试信息,没有符号文件调试器的输出结果对于开发人员基本是不可读的。

其实基本上配置完符号文件之后就可以进行调试了,调试分两种:实时调试和事后调试两种:实时调试就和平时用的VS studio进行调试一样,VS能进行的调试功能它都具备,只是不能编译工程,事后调试就是对问题出现时抓取得内存转储文件(dump file)进行调试,事后调试一般仅适用于两种问题crash 和 hang。

抓取dump文件的工具有很多,例如windbg自带的adplus,个人比较喜欢用k2xmon.exe,这时一个专门抓取内存转储文件的工具,并且是带有gui界面的小工具,支持目标程序启动自行监听功能,被监听的程序一旦发生first chance exception,就会被该工具截获,并且对其占用内存进行转储,共开发人员时候调试。

上图就是用k2xmon监听qq,qq发生first chance exception时,k2xmon正在转储其内存镜像。对于first chance exception应用程序好像并不会真正crash,系统只是将这一次处理机会交给调试器,让其决定是否允许程序继续执行,如果调试器放行,应用程序处理了该exception,将正常运行下去; 如果应用程序不处理,将发生2nd chance exception,首先还是被调试器截获,如果应用程序独立运行就会直接弹出windows用户都非常熟悉的对话框。

上面这个图太TM杯具了,白白辛苦了半个小时(可怜没有鼠标,04年的本子,输入法切换让人蛋疼), 有兴趣的看help吧, 顺便给喜欢看书的童鞋推荐 advanced windows debugging, 嗷嗷厚,和C++ primer差不多,就是介绍windbg的高级应用。

一个不完整的例子:

前一段时间遇到的,如果系统频繁调用OutputDebugString(...), 程序会不定期hang,

分析步骤:

开始使用windbg usermode 分析问题,发现我们的程序在等待一个kernel level的句柄,其实应该就是访问OutputDebugString(...)所必需的,尽管知道了解在等谁,但是usermode 下并不能知道该handle被谁占用,所以考虑kernel debug.

windbg对于kernel debug 支持有两种模式,一是真正的kernel 模式,即需要两台电脑,一台做debugger,另一台就是debuggee,在debuggee 上面配置windows的启动参数,启动debuggee系统是选择支持调试的模式,然后用串口/usb/1394连接host主机进行调试。

这样可以调试windows著名的蓝屏问题以及各种驱动程序。

我们的问题不需要这么复杂,只需要分析一下各进程之间的关系就可以,所以选择live kernel debug.

首先用 !process 命令分析出问题的进程:

lkd>!process 0 2 App.exe

然后发现众多线程中,0460.045c 是我们关心的,其实就是usermode 下分析过的那个。

THREAD 88511da8  Cid 0460.045c  Teb: 7ffdf000 Win32Thread: e7154008 WAIT: (UserRequest) UserMode Non-Alertable
            889fdd68  Mutant - owning thread 889a5308

and

        THREAD 88437020  Cid 0460.16f8  Teb: 7ff9b000 Win32Thread: e82424f8 WAIT: (UserRequest) UserMode Non-Alertable
            889fdd68  Mutant - owning thread 889a5308

从上两个线程可以了解到他们都在等待889a5308 所占用的889fdd68

接下来便可以通过命令看看县城889a5308到底是什么背景了,

lkd>!thread 889a5308

输出结果类似下面的: 实际下面输出是我 事后用 !process命令的结果

PROCESS 889a5788  SessionId: 0  Cid: 01c4    Peb: 7ffdd000  ParentCid: 072c
    DirBase: 0a4c0280  ObjectTable: e115c828  HandleCount:  54.
    Image: ngtray.exe

        THREAD 889a5308  Cid 01c4.01c8  Teb: 7ffdf000 Win32Thread: e1136ca0 WAIT: (Suspended) KernelMode Non-Alertable
SuspendCount 1
            889a54a4  Semaphore Limit 0x2

        THREAD 8899eda8  Cid 01c4.01e0  Teb: 7ffde000 Win32Thread: e1337870 WAIT: (UserRequest) UserMode Non-Alertable
            889fdd68  Mutant - owning thread 889a5308

从上面可以看出:889a5308是ngtray.exe的一个线程,其共有两个线程,另一个线程也在等待他所占用的句柄889a5308, 而他自己在等待一个信号量,至于那个信号量我就不关心了,不是我的问题就好了,我们只要向symantec反映该问题就OK,实际上这个问题早就解决了,只是我们没有相应的更新而已。

http://www.symantec.com/connect/forums/ngtray-cause-other-application-hang

由几幅图显示不出来,不会处理图片

这篇文章是自己在校内上发表的一篇日志,可惜挂了1周还是0个读者,甚是悲哀,所以删除并转贴此处,希望能在自己kx攒够100之前就能换取一个邀请码。
2010-6-23 22:55
0
雪    币: 191
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
写得还是很清楚的
有个问题:“我们的问题不需要这么复杂,只需要分析一下各进程之间的关系就可以,所以选择live kernel debug”,调试内核如果是双机调试,也应该选择live kernel debug吧?
2011-5-6 09:11
0
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
分析出IssueApplication之后,安装的问题是怎么解决的?是Kill IssueApplication嘛?
2011-5-6 09:37
0
雪    币: 188
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
  
对不起,我没进行过真正的内核调试, live kernel debug本地调试只能分析,不能真正将操作系统
停下来。
如果双机的话,可以选择通过 com/1394/usb/net的方式进行真正的kernel调试

live kernel debug 我这里指的是local那个, 这个不需要双机就能进行

希望对你有用
2011-6-11 10:36
0
雪    币: 188
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
对了,我的做法就是kill
2011-6-11 10:37
0
雪    币: 191
活跃值: (130)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
8
通过Process找找相关的线程,通过遍历线程来获取其他相关信息。
这里是lpc,通过lpc来获取线程对于的信息,这里是ImageName,来获取关联信息
有个工具ProcXp有个findHandle功能不知道是不是也是类似这么遍历的,猜测。
mark下,下次需要可能会摘取需要的信息,

kd> !alpc

!alpc [05/31/2007]

  !alpc /m MessageAddress
    Dumps the message at the specified address.

  !alpc /p PortAddress
    Dumps the port at the specified address.
2011-6-11 11:57
0
雪    币: 1644
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
学习思路和方法。
2011-6-14 23:15
0
雪    币: 188
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
10
注册码已发, 但我的标题修改不了了, 请斑竹修改
2011-10-19 08:44
0
游客
登录 | 注册 方可回帖
返回
//