反调试杂谈

作者:mengwuji

 

第二十三课   反调试杂谈

 

反调试总结如下:

第一类     钩子

目前很多保护都是采用以钩子为主,其他方式为否的反调试手段。比如对NtOpenProcess挂钩来达到反调试效果。其他还有很多函数可以达到反调试效果,在这里不一一列举。

处理方式可以想办法恢复hook,或者重载内核便能绕过这些钩子。

第二类     数值修改

1,目标进程EPROCESS下面的ProtectedProcess成员为TRUE,并且调试器进程EPROCESS下面的ProtectedProcess为FALSE时,可以达到反调试效果。症状是调试器无法打开你的进程。

2,目标进程EPROCESS下面的ProcessDelete成员为TRUE,可以达到反调试效果,症状是调试器无法附加你的进程。但是在进程退出时,要把ProcessDelete改变成FALSE,否则系统不会释放进程。

3,对DbgkpProcessDebugPortMutex全局变量的修改,可以使调试器调试某进程时卡死。

4,因为调试器和目标进程建立调试关系后,会创建一个DebugObject用于通信,所以对此DebugObject内部的锁进行改写可以使某调试事件产生时,目标进程会卡死。和第三种方式有异曲同工之妙。当然也可以对DebugObject的其他成员动手脚也可进行反调试,请大家自行测试。

5,可以创建一个DebugObject,填写到EPROCESS下面,由于DebugObject已经存在,所以调试器附加会失效。

6,改写目标进程对象的对象头内的TypeIndex为一个其他值,这会导致调试器无法打开目标进程,从而达到反调试目的。注意在进程退出时要把TypeIndex值更改回来,否则会产生蓝屏。

7,改写内核全局指针变量DbgkDebugObjectType指向的内容,可以阻止调试器附加进程。症状是调试器无法附加进程。

8,改写目标进程线程对象ETHREAD的HideFromDebugger成员为TRUE。当被调试时,当有调试事件产生,目标进程会崩溃。

9,改写调试对象类型TypeInfo成员下ValidAccessMask的值,可以达到反调试作用。

第三类     回调函数钩子

1,object 钩子,此方法已进行过多讲解,这里不再叙述。

2,对内核pIofCallDriver内容进行修改,使其指向一个我们定义好的函数。如果产生IRP下发操作,就可以被我们拦截到,以此达到反调试目的。

 

检测调试总结:

1,对一些出名的调试器进程进行检测,比如od,ce等。

2,对一些窗口进行检测,发现是否有调试器的窗口。

3,对调试对象类型的TotalNumberOfObjects和TotalNumberOfHandles进行检测,判断系统是否有调试器存在。

4,设置调试对象类型TypeInfo成员的MaintainTypeList为TRUE,然后监控调试对象类型的TypeList链表,如果有调试器创建调试对象,那么该调试对象会生成一个结构_OBJECT_HEADER_CREATOR_INFO并加入到此链表,这时就可以判定是否有调试目标进程。(未完成)

5,针对硬件断点的检测,可以判定目标进程的线程KTHREAD下Header成员的DebugActive是否有值,有值的话就代表当前线程存在硬件断点。(硬件断点被windows设计为针对某线程的)

6,针对硬件断点的检测,可以获取目标进程的线程KTHREAD下InitialStack成员,然后这个值减去0x29C得到的是一个陷阱帧_KTRAP_FRAME结构的指针,其中的DRX系列成员如果有值,就代表当前线程存在硬件断点。

7,对系统所有进程的句柄表进行检测,看看目标进程的进程对象、线程对象、或者一些调试对象是否存在,存在的话就代表目标进程已经被别的进程打开,可以选择关闭相关句柄,也可根据情况退出进程。

8,对目标线程对象KTHREAD下SuspendCount成员进行改写,使之不等于零。当调试器调试目标进程,被中断时,由于目标进程线程的SuspendCount不为零,所以目标进程的线程就无法被暂停。那么调试器实际就等于没有中断目标进程,这会使调试器产生错误行为。

posted @ 2015-06-04 15:25  紫旭  阅读(479)  评论(0编辑  收藏  举报