首页
社区
课程
招聘
[原创]windbg分析explorer崩溃之迷
发表于: 2014-10-7 21:29 28208

[原创]windbg分析explorer崩溃之迷

2014-10-7 21:29
28208

1.初识敌情:   
    放假归来,打开电脑连上网,提示有几封未读邮件,尽是一些工作相关的内容,处理完成之后放在一个文件夹之中,并随手将文件夹命名为a,随即准备压缩回复邮件。本来想右键点击文件然后进行缩,这时状况出现了,只要在文件夹上点击右键,explorer就崩溃,然后自动重启。接连几次之后,我的第一感是难道电脑中有病毒了?就试着点击桌面上其它的文件夹,可以弹出右键菜单,能够进行压缩。只要点击刚才我新建的文件夹a,explorer就崩溃。这样看来病毒的可能性就小了,如果有问题,应该都有问题才对。
    2上windbg
    为了把问题搞清楚,只有请出电脑中的“抓虫大师”来帮忙了,因为平常电脑中出现问题也没少请他,但不知这次能否药到病除。为了能够在explorer崩溃的时候windbg自动跳出来为我分析敌情,首先要将windbg设置为jit调试器。一切准备好之后,就等bug自动上钩了。
    再次右键点击文件夹1,崩溃如期而至,此时windbg也兴奋的跳出来向我报告发现情况,请求我处理。在命令行中输入kvn查看一下栈回溯。
# ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 000adb24 04ee468d 000adb44 04efffcc 1d00d4ac WinMTExt!DllUnregisterServer+0xa879
01 000adb94 04edd3b8 000ae240 0722e13c 000ae0bc WinMTExt!DllUnregisterServer+0xa50d
02 000adc4c 77253b27 77253b2c 7738d40c 000add8c WinMTExt!DllUnregisterServer+0x3238
03 000adc80 769297b4 000000e2 000adca4 769da1d4 ntdll!RtlNtStatusToDosError+0x3b (FPO: [Non-Fpo])
04 000adca4 769da06e 000adcc4 00000044 000adcf0 0x769297b4
05 000add98 851b850d 0722e13c 000addf0 000ae240 kernel32!BaseRegGetKeySemantics+0x24e (FPO: [Non-Fpo])
06 000addc0 769f7609 04ed1284 1d00c0b0 000ae77c 0x851b850d
07 000ade74 77253b27 77253b2c 7738d624 00000000 kernel32!lstrcatW+0x73
08 000adea8 769df6f2 769df722 851b87e5 000ae0c8 ntdll!RtlNtStatusToDosError+0x3b (FPO: [Non-Fpo])
09 000adf2c 769e1040 76a565c0 00000000 000adf94 kernel32!LocalBaseRegOpenKey+0x159 (FPO: [Non-Fpo])
0a 000adf3c 0795e328 000adf58 769dc748 0795e328 kernel32!CLOSE_LOCAL_HANDLE_INTERNAL+0x48 (FPO: [Non-Fpo])
0b 000adfb8 7555e916 00000010 000ae08c 00000004 0x795e328
0c 000adff4 75b365ff 1d00d2d0 04edb2c5 002301ef shlwapi!SHRegGetValueW+0xbc
0d 000ae01c 002301ef 00000000 0000796d 00007afa shell32!SHRegGetDWORDW+0x26 (FPO: [Non-Fpo])

    通过shell32!SHRegGetDWORDW可以知道,这正是我弹出右键菜单时发生的动作,继续向上找可以知道,出事故的地方是在WinMTExt这个模块中。然后通过lm vm WinMTExt查看一下这个dll文件的来历。
start    end        module name
04ed0000 04f14000   WinMTExt   (export symbols)       WinMTExt.dll
    Loaded symbol image file: WinMTExt.dll
    Image path: C:\Program Files\WinMount\WinMTExt.dll
    Image name: WinMTExt.dll
    Timestamp:        Wed Oct 20 13:22:47 2010 (4CBE7CA7)
    CheckSum:         00048B03
    ImageSize:        00044000
    File version:     3.3.1.20
    Product version:  3.3.1.20
    File flags:       0 (Mask 3F)
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0009.03a8
    CompanyName:      WinMount International Inc.
    ProductName:      WinMTExt.dll
    InternalName:     WinMTExt.dll
    OriginalFilename: WinMTExt.dll
    ProductVersion:   3.4.1015
    FileVersion:      3.4.1015
    FileDescription:  WinMount Explorer Extension
    LegalCopyright:   (C) WinMount International Inc. All Rights Reserved
    原来是winMount软件的Explorer扩展dll。它怎么出错了呢?现在我们就回到事故现场看看发生了什么?使用windbg的反汇编命令ub WinMTExt!DllUnregisterServer+0xa879,得到结果如下:
WinMTExt!DllUnregisterServer+0xa866:
04ee49e6 83ec20          sub     esp,20h
04ee49e9 8b4508          mov     eax,dword ptr [ebp+8]
04ee49ec 56              push    esi
04ee49ed 57              push    edi
04ee49ee 6a08            push    8
04ee49f0 59              pop     ecx
04ee49f1 be54b5ef04      mov     esi,offset WinMTExt!DllUnregisterServer+0x213d4
04ee49f6 8d7de0          lea     edi,[ebp-20h]
0:000> u
WinMTExt!DllUnregisterServer+0xa879:
04ee49f9 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
    这段汇编只要内容为在栈中开辟32字节的区域来存放esi所指向的内容,一共复制8次(ecx=8),那么来看看esi中的值是什么:通过r esi可以看到esi=ccefb554,然后查看ccefb554所指的内容。使用db ccefb554查看,
ccefb554  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
ccefb564  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
    ?表示没有内容,所以导致rep movs dword ptr es:[edi],dword ptr [esi]这条件指令在执行时引发内存读取错误。通过 ub WinMTExt!DllUnregisterServer+0xa50d查看其父函数,是什么原因导致这个问题。
WinMTExt!DllUnregisterServer+0xa4f3:
04ee4673 8d45d8          lea     eax,[ebp-28h]
04ee4676 50              push    eax
04ee4677 8d4db0          lea     ecx,[ebp-50h]
04ee467a e851b6ffff      call    WinMTExt!DllUnregisterServer+0x5b50 (04edfcd0)
04ee467f 68ccffef04      push    offset WinMTExt!DllUnregisterServer+0x25e4c (04efffcc)
04ee4684 8d45b0          lea     eax,[ebp-50h]
04ee4687 50              push    eax
04ee4688 e854030000      call    WinMTExt!DllUnregisterServer+0xa861 (04ee49e1)
    看了半天也没发现什么有价值的内容,还是把眼光放长远一点,继续它的函数 ub winMTExt!DllUnregisterServer+0x3238 L10
WinMTExt!DllUnregisterServer+0x3201:
04edd381 a810            test    al,10h
04edd383 0f84ab000000    je      WinMTExt!DllUnregisterServer+0x32b4 (04edd434)
04edd389 bb01000000      mov     ebx,1
04edd38e 895c2410        mov     dword ptr [esp+10h],ebx
04edd392 85ff            test    edi,edi
04edd394 752c            jne     WinMTExt!DllUnregisterServer+0x3242 (04edd3c2)
04edd396 e8ba8a0000      call    WinMTExt!DllUnregisterServer+0xbcd5 (04ee5e55)
04edd39b 33c0            xor     eax,eax
04edd39d 8b74241c        mov     esi,dword ptr [esp+1Ch]
04edd3a1 8d4efc          lea     ecx,[esi-4]
04edd3a4 3b4810          cmp     ecx,dword ptr [eax+10h]
04edd3a7 7205            jb      WinMTExt!DllUnregisterServer+0x322e (04edd3ae)
04edd3a9 e8a78a0000      call    WinMTExt!DllUnregisterServer+0xbcd5 (04ee5e55)
04edd3ae 395e10          cmp     dword ptr [esi+10h],ebx//ebx=1,从上面mov ebx,1可知。esi+10h处内容为文件夹名字的长度
04edd3b1 7705            ja      WinMTExt!DllUnregisterServer+0x3238 (04edd3b8)
04edd3b3 e89e720000      call    WinMTExt!DllUnregisterServer+0xa4d6 (04ee4656)//导致explorer崩溃的元凶
    由于最下面的call很关键,是导致explorer崩溃的元凶。而看一下上面的那个判断,esi+10h处的内容与1相比,如果<=1就执行这个call,而>1则执行call后面的内容。分析到这里突然想自己的文件夹的名字a,长度为1,所以导致问题的发生。于是大胆猜esi+10h内容很可能是文件夹名字的长度。那么下面就试一下。首先将文件夹的名字命名为leochao,一个7个字节,下面看看esi+10h外的内容是否为7。关掉windbg,等桌面恢复以后重新启动一个windbg,然后附加到explorer进程中,点击break中断下来,在命令行中输入:bu WinMTExt!DllUnregisterServer+0x3201,然后输入g, 点击刚才的文件夹,单步执行到cmp     dword ptr [esi+10h],ebx这句,查看esi+10h的内容,dd esi+10,内容果然为00000007。
    3.解决问题
    分析到这里可以看到,程序在判断出现了错误。原意为如果文件夹名字的长度<1,则程序走向失败,而这里写误写为了<=1,从而导致文件夹名称长度为1时,程序也走向失败。现在明白了原因之后,只需将ja改为jge即可,将内存地址04edd3b1的77改为7D。使用命令eb 04edd3b1 7d。
    现在将dll文件在内容的数据修改了,如何保存到文件呢,windbg给我们准备了一个命令:.writemem。首先知道dll加载的内存地址:lm m WinMTExt,得到dll文件在内存加载的地址。
start    end        module name
04ed0000 04f14000   WinMTExt   (export symbols)       WinMTExt.dll
    然后到文件大小:? 04f14000-04ed0000,
    Evaluate expression: 278528 = 00044000
    如何想把dll文件保存到C:\winMTExt.dll, 现在可以执行.writemem C:\winMTExt.dll 04ed0000 L44000。
    将修改好的winMTExt.dll替换原来的dll文件,重启explorer之后,右键点击文件名长度为a的文件夹,explorer就不再崩溃了。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 3
支持
分享
最新回复 (20)
雪    币: 116
活跃值: (26)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
赞!
难道explorer是个实习生写的? 似乎问题不少。。。
2014-10-7 21:38
0
雪    币: 333
活跃值: (161)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
膜拜大神
2014-10-7 21:42
0
雪    币: 200
活跃值: (38)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
是第三方扩展出的问题。我一向是尽量不安装explorer的三方扩展,从没出过问题
2014-10-7 22:04
0
雪    币: 185
活跃值: (416)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
explorer的第三方插件经常看到导致它假死的情况
2014-10-8 08:06
0
雪    币: 234
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
explorer本身还是很健壮的,出问题的可能不大,一般的崩溃现象基本都是第三方导致的。
2014-10-8 08:39
0
雪    币: 35
活跃值: (86)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
赞一个!!!
2014-10-8 23:48
0
雪    币: 56
活跃值: (34)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
我还要多熟悉windbg,学习了!
2014-10-9 08:25
0
雪    币: 3
活跃值: (10)
能力值: ( LV4,RANK:43 )
在线值:
发帖
回帖
粉丝
9
厉害,向楼主学习遇到问题时解决问题的思路
2014-10-9 17:24
0
雪    币: 563
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
收藏 学习
2014-10-9 19:10
0
雪    币: 23
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
学习了  实例讲解
2014-10-10 13:03
0
雪    币: 2291
活跃值: (938)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
12
学以致用,赞楼主!
2014-10-10 16:05
0
雪    币: 58
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
13
赞,有时候思路就在一瞬
2014-10-11 15:59
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jmp
14
有料好文!
2014-10-12 14:41
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
赞一下分析思路
2014-10-12 14:49
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
回帖不看贴。。。
2014-10-13 01:36
0
雪    币: 1450
活跃值: (848)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
liutaotao有人找你,学习writemem命令。
2014-10-13 14:09
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
感觉不科学呀。 问题原因似乎应该出在esi=ccefb554这里,这是个内核地址,这是有问题的。 楼主似乎偏离了方向?
2014-10-14 14:15
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
赞一个,学习中
2014-11-13 11:32
0
雪    币: 6953
活跃值: (2833)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
winmount 文件夹名称1个字符的时候右击报错很早有遇到过,后来就直接F2重命名没细分析,向楼主这精神学习啊
2014-11-13 18:57
0
雪    币: 9
活跃值: (175)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
21
2017-12-12 20:56
0
游客
登录 | 注册 方可回帖
返回
//