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发出的调试事件了。但是事实上是不是真的这样呢?
因此,我写了一个实验的程序如下:
这个程序如果正常的情况下中断到调试器,如果没有调试就Crash了。但是如果int 3的中断处理的例程被干掉了,就是顺利的执行下来。
上图中可以看到int 3断点没有起作用。
不过,这样一来原先下断点的地方得不到恢复,这种方法不行啊!
对于复杂的断点列表只能手工导出,再导入了,这个方法有点拙!
不过,这样一搞倒是有反调试的效果了!
ring3层的调试器就下了软件断点反而会crash,ring3层的调试会被干扰。
严格的说这种方法是反下软件断点,而且效果还不错!
真是无心插柳柳真荫啊!!!