首页
社区
课程
招聘
[原创]对调试模式卡死的一处分析
发表于: 2013-7-11 13:58 7015

[原创]对调试模式卡死的一处分析

2013-7-11 13:58
7015
无意中的按下了print键,包括开一些游戏,系统立刻卡在那里,偏偏又不蓝给你看。
在各位友人帮助下,连接好了串口间的调试传送。
调试环境:win7 x32旗舰版/vm  系统:.iso安装

虽用同样iso安装,vm下的却正确,于是我移植了ntkrlpa过去,果然又卡住了。
nt!RtlpBreakWithStatusInstruction:
83ea3834 cc              int     3

不像是一个异常,而是个硬断,继续:
0: kd> kv
8b8fc728 83e77a6d 85f1c000 86572020 8b8fc754 i8042prt!I8042KeyboardInterruptService+0x431 (FPO: [Non-Fpo])

0: kd> u i8042prt!I8042KeyboardInterruptService+0x431
i8042prt!I8042KeyboardInterruptService+0x431:
8e6bf8cb c745fcfeffffff  mov     dword ptr [ebp-4],0FFFFFFFEh

这是什么?->I8042KeyboardInterruptService,[ebp-4]有问题吗?继续往下看:
0: kd> r
eax=00000002 ebx=00000000 ecx=83f9cc07 edx=00000002 esi=865720d8 edi=8e6c1298
eip=83ea3834 esp=8b8fc6e8 ebp=8b8fc728 iopl=0         nv up ei pl nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000202

0: kd> !irql
Debugger saved IRQL for processor 0x0 -- 6

0: kd> u i8042prt!I8042KeyboardInterruptService+420
i8042prt!I8042KeyboardInterruptService+0x420:
8e6bf8ba 1038            adc     byte ptr [eax],bh
8e6bf8bc 1d11216c8e      sbb     eax,offset i8042prt!Globals+0x51 (8e6c2111)
8e6bf8c1 7408            je      i8042prt!I8042KeyboardInterruptService+0x431 (8e6bf8cb)
8e6bf8c3 6a02            push    2
[COLOR="red"]8e6bf8c5 ff15bc106c8e    call    dword ptr [i8042prt!_imp__DbgBreakPointWithStatus (8e6c10bc)]8e6bf8cb c745fcfeffffff  mov     dword ptr [ebp-4],0FFFFFFFEh[/COLOR]8e6bf8d2 eb15            jmp     
i8042prt!I8042KeyboardInterruptService+0x44f (8e6bf8e9)
8e6bf8d4 33c0            xor     eax,eax

看来只是一个断点,上面DbgBreakPointWithStatus就是了。下面代码很长
[COLOR="red"]8e6bf85b 8b0dc4106c8e    mov     ecx,dword ptr [i8042prt!KdDebuggerNotPresent (8e6c10c4)]8e6bf861 3819            cmp     byte ptr [ecx],bl[/COLOR]8e6bf863 0f8580000000    jne     i8042prt!I8042KeyboardInterruptService+0x44f (8e6bf8e9)
8e6bf869 0fb79604020000  movzx   edx,word ptr [esi+204h]
0: kd> 
i8042prt!I8042KeyboardInterruptService+0x3d6:
8e6bf870 f6c201          test    dl,1
8e6bf873 7574            jne     i8042prt!I8042KeyboardInterruptService+0x44f (8e6bf8e9)
8e6bf875 8a8e7c010000    mov     cl,byte ptr [esi+17Ch]
8e6bf87b 80f902          cmp     cl,2
8e6bf87e 7424            je      i8042prt!I8042KeyboardInterruptService+0x40a (8e6bf8a4)
8e6bf880 80f904          cmp     cl,4
8e6bf883 741f            je      i8042prt!I8042KeyboardInterruptService+0x40a (8e6bf8a4)
8e6bf885 80f907          cmp     cl,7
0: kd> 
i8042prt!I8042KeyboardInterruptService+0x3ee:
8e6bf888 741a            je      i8042prt!I8042KeyboardInterruptService+0x40a (8e6bf8a4)
8e6bf88a 80f908          cmp     cl,8
8e6bf88d 7415            je      i8042prt!I8042KeyboardInterruptService+0x40a (8e6bf8a4)
8e6bf88f 6683f854        cmp     ax,54h
8e6bf893 7554            jne     i8042prt!I8042KeyboardInterruptService+0x44f (8e6bf8e9)
8e6bf895 c745fc01000000  mov     dword ptr [ebp-4],1
8e6bf89c eb14            jmp     i8042prt!I8042KeyboardInterruptService+0x418 (8e6bf8b2)
8e6bf89e 33c0            xor     eax,eax
0: kd> 
i8042prt!I8042KeyboardInterruptService+0x406:
8e6bf8a0 40              inc     eax
8e6bf8a1 c3              ret
8e6bf8a2 eb34            jmp     i8042prt!I8042KeyboardInterruptService+0x43e (8e6bf8d8)
8e6bf8a4 6683f837        cmp     ax,37h
8e6bf8a8 753f            jne     i8042prt!I8042KeyboardInterruptService+0x44f (8e6bf8e9)
8e6bf8aa f6c202          test    dl,2
8e6bf8ad 743a            je      i8042prt!I8042KeyboardInterruptService+0x44f (8e6bf8e9)
8e6bf8af 895dfc          mov     dword ptr [ebp-4],ebx
0: kd> 
i8042prt!I8042KeyboardInterruptService+0x418:
8e6bf8b2 a1c0106c8e      mov     eax,dword ptr [i8042prt!KdDebuggerEnabled (8e6c10c0)]
8e6bf8b7 3818            cmp     byte ptr [eax],bl 
8e6bf8b9 7410            je      i8042prt!I8042KeyboardInterruptService+0x431 (8e6bf8cb)                       // je        offset:上面的call dbgbrak

原因就这里了,先检测是否开启调试,再读取扫描码(ebp-1Dh)?进行判断。
一步步下断,在这里8e6bf8a4 cmp     ax,37h发现;按下截图键ax为37h,跳去执行断点。
显示37h不是扫描码,asm从端口和中断都读不到这个键的信息。
这里记住edx(dl)总是为0,esi与第二个参数有关(虽然没公开这类function,但我觉得会是个链表,存放着许多调用地址,其他用到这参数的都没公开,很难分析)

最后加个补丁,打完收工了
0: kd> e 8e6bf85b E9 89 00 00 00 8B FF 8B FF 8B FF 8B FF 90
0: kd> u 8e6bf85b l0x20
i8042prt!I8042KeyboardInterruptService+0x3c1:
8e6bf85b e989000000      jmp     i8042prt!I8042KeyboardInterruptService+0x44f (8e6bf8e9)
8e6bf860 8bff            mov     edi,edi
8e6bf862 8bff            mov     edi,edi
8e6bf864 8bff            mov     edi,edi
8e6bf866 8bff            mov     edi,edi
8e6bf868 90              nop
8e6bf869 0fb79604020000  movzx   edx,word ptr [esi+204h]

不清楚微软的意图,也不清为什么别的系统不会这样。

第一篇分析作品,也不知道花这些心思值不值,也许以后接触了计算机课程,会发现现在都是徒劳的,我会后悔?

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

收藏
免费 5
支持
分享
最新回复 (8)
雪    币: 1711
活跃值: (516)
能力值: ( LV12,RANK:200 )
在线值:
发帖
回帖
粉丝
2
开了debug mode按printscreen是会断下来
2013-7-12 13:02
0
雪    币: 115
活跃值: (46)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
貌似有的系统不会
2013-7-12 13:46
0
雪    币: 5143
活跃值: (363)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
4
网上问这个问题的人挺多的,一按print screen 键就死机,估计都是开了调试模式导致的
2013-7-12 14:56
0
雪    币: 115
活跃值: (46)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5
想问问如果我要修改这个模块文件作为补丁,因为该处位置它有重定位所以出错,那可以通过什么办法呢?注:loadpe的重建pe无效。
2013-7-12 15:06
0
雪    币: 28
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
试试直接用十六进制编辑器改,然后setcsum呢
2013-7-12 15:29
0
雪    币: 115
活跃值: (46)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
7
就是这么改的,重启后发现jmp的立即数和几个nop被改成起的其他的,原始的地址有dword[KdDebuggerNotPresent]
2013-7-12 15:39
0
雪    币: 28
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
[QUOTE=IDGHOST;1198241]就是这么改的,重启后发现jmp的立即数和几个nop被改成起的其他的,原始的地址有dword[KdDebuggerNotPresent][/QUOTE]

那就是sys文件会检查签名的吧?
2013-7-12 15:41
0
雪    币: 115
活跃值: (46)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
9
没有检查签名,只是因为有重定位在。
2013-7-12 15:55
0
游客
登录 | 注册 方可回帖
返回
//