Patch Intel int 3断点指令的功能

    今天在调试一个程序时候遇到一个问题,我下了很多的软件断点就是int 3,这当中有的被Enable,有的被Disable,因为断点太多了,我不想一个个手动把Enable的断点,设置成Disable,然后在需要的时候,还要再还原回去太麻烦了,我想有没有什么快捷的手段呢,一下禁用所有的int 3断点,而不要去改windbg里面的断点列表?

    我想到了一个方法。

    int 3 指令是一个单字节的指令就是0xCC,当CPU执行到这条指令之后相对应的中断例程,在Windows中就是KiTrap03。在这个例程中会去调用CommonDispatchException,这个函数去做分发并最终通知到调试器。我的做法很简单就是直接patch这个中断例程的处理函数让它直接返回就可以了!

 

我在windbg里面我执行如下命令:

kd> !idt -a

Dumping IDT:

00:    804df50e nt!KiTrap00
01:    804df68d nt!KiTrap01
02:    Task Selector = 0x0058
03:    804dfaa1 nt!KiTrap03  ;---> int 3的中断处理例程
04:    804dfc24 nt!KiTrap04
05:    804dfd89 nt!KiTrap05
06:    804dff0a nt!KiTrap06
07:    804e0583 nt!KiTrap07
08:    Task Selector = 0x0050
09:    804e0988 nt!KiTrap09
0a:    804e0aa6 nt!KiTrap0A
0b:    804e0be3 nt!KiTrap0B
0c:    804e0e40 nt!KiTrap0C

----------------------------------

kd> u 804dfaa1
nt!KiTrap03:
804dfaa1 6a00            push    0
804dfaa3 66c74424020000  mov     word ptr [esp+2],0
804dfaaa 55              push    ebp
804dfaab 53              push    ebx
804dfaac 56              push    esi
----------------------------------

kd> eb 804dfaa1 CF

kd> u 804dfaa1
nt!KiTrap03:
804dfaa1 cf              iretd    ;呵呵,我在这儿直接返回了相当于没有断点功能了
804dfaa2 0066c7          add     byte ptr [esi-39h],ah
804dfaa5 44              inc     esp
804dfaa6 2402            and     al,2
804dfaa8 0000            add     byte ptr [eax],al
804dfaaa 55              push    ebp

----------------------------------

现在应该是没有软件断点的功能了,调试器不会收任何int 3发出的调试事件了。但是事实上是不是真的这样呢?

因此,我写了一个实验的程序如下:

Untitled

 

    这个程序如果正常的情况下中断到调试器,如果没有调试就Crash了。但是如果int 3的中断处理的例程被干掉了,就是顺利的执行下来。

Untitled1111

 

上图中可以看到int 3断点没有起作用。

 

不过,这样一来原先下断点的地方得不到恢复,这种方法不行啊!

对于复杂的断点列表只能手工导出,再导入了,这个方法有点拙!

不过,这样一搞倒是有反调试的效果了!

 

ring3层的调试器就下了软件断点反而会crash,ring3层的调试会被干扰。

严格的说这种方法是反下软件断点,而且效果还不错!

 

真是无心插柳柳真荫啊!!!

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2011-05-08 21:34  Russinovich`s Blog  阅读(2580)  评论(5编辑  收藏  举报