本文是对 从3环调试器工作流程的实现看反调试 的一个补充和扩展,主要从异常分发的流程的实现来看怎么反调试。
后面还有一篇链接:[原创]从异常分发流程的实现看反双机调试【有码】
后面顺变会附带上写满注释的wrk代码,方便大家对照着看。
由于本人水平有限,错误之处难免,请大神们不吝指正哈!
一个INT 3被执行的时候关键数据结构变化
栈的变化:
INT 3刚被执行的时候堆栈的情况:
说明:
1. 从tss段中取出对应权限的esp
2. 把用户空间的ss寄存器压入HardwareSegss
3. 把用户空间的esp寄存器压入HardwareEsp
4. 把标志寄存器压入到EFLAGS
5. 把用户空间的cs寄存器压入到SegCs中
6. 把用户空间的eip压入到Eip中
填充TrapFrame结构:
说明:
1. V8 6Gs、V86Fs、V86Ds、V86Es,这些寄存器现在仅仅作为保留,不必研究
2. HardwareSegSs、HardwareEsp、Eflags、SegCs、Eip,这些在中断的时候cpu会帮我保存
3. 其他的寄存器操作系统在中断例程保存
异常结构相关:
异常结构体
说明:
1. 在学习阶段只需要关注ExceptionCode和ExceptionAddress即可,其他的参数如果不写调试器暂时用不到
异常结构体在什么阶段被填充(以INT 3为例):
说明:
1. 从上图可以看到在CommonDispatchException中被填充
2. 但是我们也可以看到我们分析的重点会在KiDispatchException中,是的我们的分析的重点就是他,但是分析它之前我们得做一些准备工作
异常结构体具体是如何被填充的
这个问题只能贴代码了,就贴CommonDispatchException代码,这块的代码已经有很详细的注释了,等会全部的代码放到附件中提供下载
为什么讲异常分发流程会讲下核心数据结构:
1. 后面我会把详细注释过的wrk的源代码作为附录,大家可以对照注释去看异常分发的源代码
2. 根据我的经验,阻碍看源代码就是对这些数据结构不了解,特别是TrapFrame、异常时候的堆栈、在异常中怎么返回这类问题
异常分发全流程:
1. 如果你看到这张图不想看了,你的感觉是对的,我第一次看到这张图也是一脸懵逼,感觉好复杂啊,幸好我们今天仅仅只学习其中的一块,就是图的左半部分
2. 如果你看到这里有什么第一次、第二次XX,先不用纠结这个问题,我们只讨论第一次的话题,因为男人的第一次是难以忘怀的,不对是第一次分发才和3环调试器有密切关系,第二次分发以后专门开个帖子对着源代码讲下
3. 忽略图中的内核调试器
第一次分发且有用户调试器:
先来个流程图:
说明:
1. 可以看到核心的函数是 DbgkForwardException
2. 把调试事件发送到调试对象的核心函数是DbgkSendApiMessage
核心代码的分析:
KiDispatchException 的分析:
主要调用了DbgkForwardException,这个是用户调试的主要函数
DbgkForwardException的分析:
先检查 CrossThreadFlags 的 PS_CROSS_THREAD_FLAGS_HIDEFROMDBG 标志位是否被设置,如果被设置代表不会被调试。
调用 DbgkpSendapiMessage 发送异常信息给调试器
DbgkpSendApiMessage 的分析:
说明:
1. 这个函数主要调用了 DbgkpQueueMessage 函数
DbgkpQueueMessage 的分析:
这里会获取一个全局锁,这个是一个反调试的好地方
把调试事件插入DebugObject的EventList里面去:
等待调试器处理这个调试事件
从异常分发流程中总结出来的反3环调试:
1. 直接对idt做hook,比如3号中断,这样就没法使用软件断点了
2. 对需要保护的进程的每个线程的的 Ethread 结构体的CrossThreadFlag 设置 PS_CROSS_THREAD_FLAGS_HIDEFROMDBG,有一个专门的api是:ZwSetInformationThread(hThread, ThreadHideFromDebugger, NULL, NULL)
3. DbgkpSendApiMessage 进行挂钩,直接返回STATUS_UNSUCCESSFUL
4. DbgkpQueueMessage 进行挂钩,直接返回STATUS_UNSUCCESSFUL
5. 这个就比较比较猥琐了:ExAcquireFastMutex (&DbgkpProcessDebugPortMutex),直接锁住这个全局变量,所有的调试器都会卡死,并且没有钩子
6. DbgkpSuspendProcess和DbgkpResumeProcess 挂钩,向0x64端口写入0xFE,让机器重启
谢谢大家观看!
本文由看雪论坛 又出bug了 原创
转载请注明来自看雪社区
原文链接:
[原创]从异常分发流程的实现看反用户调试器-『软件逆向』-看雪安全论坛bbs.pediy.com
更多干货请关注看雪学院公众号 ikanxue!