XTrap保护中的IDTHOOK恢复
最近比较懒什么东西都没学。研究了两天传说中的三大游戏保护中的一个,叫XTrap.据说是三个保护
中最弱的一个。但是能力有限,还是没有过掉保护。哎,失败。
不过从中学到了点知识。留个记录。
XTrap保护在驱动里用SSTD HOOK了NtDeviceIoControlFile,NtOpenProcess,NtOpenSection
NtProtectVirtualMemory 等几个API. Shadow SSDT也HOOK了 NtUserFindWindowex
NtUserSetWindowsHookEx等几个API。他还在应用层也HOOK了一些仿调试函数。这些防护可以通过简单
的恢复来绕过。网上也有很多这方面的介绍。本以为绕过这些防护就完事了。可惜太天真了。
里面还有一个IDT HOOK 只要一调试就蓝屏。网上搜索了一下没有找到恢复IDT的资料。
于是自己想了一个办法。
先来说说IDT,IDT = Interrupt Descriptor Table 中断描述表。
这个中断描述表有什么用呢?我说的白话一点。如果你看过有关汇编的教程一定有所了解。
比如我们常用的DEBUG的T命令。他就是通过int 1中断来执行的。当我们执行这个中断的时候
CPU会在执行完一条指令之后,如果检测到TF为1则产生单步中断。
那么系统怎么知道那些中断对应什么操作呢。在系统里有一个中断描述符。它里面就记录了这些对应信
息。
如果我们把IDT里的地址改成我们自己的函数地址。呵呵那么可想而知,在发生相关中断操作的时候就
会执行我们的函数。
XTrap就HOOK了IDT里的int1来阻止调试。幻影壳也用到了这种技术。
有了上面的介绍,下面我们来说说怎么恢复。
首先我们要先把原始的IDT地址保存下来。代码如下
//这条汇编操作是获取IDT __asm sidt idt_info idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase); //这里是保存我们需要恢复的中断操作指令我这里的NT_INT_TIMER为#define NT_INT_TIMER 0x01 old_ISR_pointer = MAKELONG(idt_entries[NT_INT_TIMER].LowOffset,idt_entries [NT_INT_TIMER].HiOffset);
保存好了原始地址 那么当IDT被改变时我们就可以根据这个原始地址来恢复了
恢复代码如下
//获取现在的中断地址 __asm sidt idt_info idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase); //表示将处理器标志寄存器的中断标志为清0,不允许中断 __asm cli //用我们保存的地址来替换掉 idt_entries[NT_INT_TIMER].LowOffset = (unsigned short) old_ISR_pointer; idt_entries[NT_INT_TIMER].HiOffset = (unsigned short)((unsigned long)old_ISR_pointer >> 16); //表示将处理器标志寄存器的中断标志置1,允许中断 __asm sti
到这里恢复就完成了。
呵呵,可是XTrap没有我想像的那么单纯。当我恢复的时候立马蓝屏。估计是有线程在不停的检测这个
地址是否被恢复。如果被恢复那就给你一个蓝屏的钙。于是我把除主线程以外的其它线程都挂起。然后
再恢复。
终于不蓝了。上调试器可以进行附加搜索能操作。但是只要执行中断操作程序立马挂掉。不知道是什么
原因。估计是还HOOK了其它地方。还是多学点调试吧以后直接逆向它的代码来看看。
