[原创]对双机调试下KdDebuggerNotPresent标志位的研究
2022-11-18 17:50:0 Author: bbs.pediy.com(查看原文) 阅读量:13 收藏

[原创]对双机调试下KdDebuggerNotPresent标志位的研究

2022-11-18 17:50 6774

[原创]对双机调试下KdDebuggerNotPresent标志位的研究

本人第一次发帖,不足之处请大佬们海涵

虚拟机:Windows7 x64

物理机:Windows10

研究时间:2022年7月-8月

在研究过双机调试的时候,在各大论坛看过许多高手们发的帖子,其中有不少总结了双机调试下的标志位,也给出了相应的越过检测的方法。但是对于KdDebuggerNotPresent这个标志位的处理方法我并没有找到。同时,自己在使用大佬们给出的方法处理之后,仍然被检测出来,直接蓝屏。这让我确定现在版本的某游戏驱动一定检测了KdDebuggerNotPresent这个标志位。

      全局变量nt!KdDebuggerNotPresent来标识是否存在内核调试器,在未启动调试模式下此值为1。

在对其他标志位处理好的情况下,直接在物理机的windbg中执行eb KdDebuggerNotPresent  1指令后运行,发现还是被检测到发生了蓝屏。重新启动挂上双机调试再次修改一遍看一下修改有没有成功


发现修改并没有成功。在Windows7中使用windbg启动本地内核调试,执行eb KdDebuggerNotPresent  1 查看发现修改成功了

但当我们在物理机的windbg执行break中断下来,在我物理机中的windbg中查看时发现KdDebuggerNotPresent为0。同时在Windows7的本地内核调试下查看也为0,说明这个值在双机通信的过程中被修改成0了。

通过查阅《软件调试》这本书,当接受到复位数据包后,目标机会自动将KdDebuggerNotPresent设置为0,现在我们彻底明白为什么第一次在物理机中清除KdDebuggerNotPresent 时失败了。

kdcom.dll是Windows 操作系统内核的调试模块,里面包含了大量的内核调试函数,例如:KdD0Transition 、KdD3Transition、KdDebuggerInitialize0、KdReceivePacket、KdRestore 、KdSave 等函数,这个DLL在系统引导时会被ntoskrnl.exe加载,还可用于Windows驱动开发调试。

用IDA加载kdcom,搜索KdDebuggerNotPresent,在KdReceivePacket这个函数中找到。F5查看KdReceivePacket的伪代码发现确实将KdDebuggerNotPresent清零了。

既然KdDebuggerNotPresent会在收到复位包的时候清零,收到复位包肯定先中断之后冻结内核,那有没有种情况,我们可以不管通信过程中KdDebuggerNotPresent的值,因为这是冻结内核状态,我们只关注运行内核状态时KdDebuggerNotPresent的值。所以我们可以加载驱动的时候将KdDebuggerNotPresent置为1,中断内核通信过程我们不管,在结束通信恢复内核的时候我们将KdDebuggerNotPresent改为1。这样在内核运行过程中KdDebuggerNotPresent永远为1,而且还不会影响正常的通信。

回头看退出内核调试的执行流程,现在很明确了,我们可以hook MyKeThawExecution 加一句将KdDebuggerNotPresent 置为1的代码就完成了。

最后附上我的所有处理过程,方法有点笨,请大佬海涵。

  • 对KdDebuggerNotPresent的检测这个标志在接收到复位包的时候 由KdReceivePacket这个函数清零。这个标志不管在登录游戏的时候还是游戏中一直在检测,我们可以通过Hook MyKeThawExecution恢复运行时 将标志改为1。

  •        KdEnteredDebugger的检测是通过mdl映射的方式,所以我们只要hook IoAllocateMdl 过滤掉KdEnteredDebugger地址就可以了。

  •        KdPitchDebugger这个标志检测 ,我们需要在KeUpdateSystemTime,KeUpdateRunTime,KdPollBreakIn函数中将KdPitchDebugger替换成别的恒为0的地址

  •        KdDebuggerEnabled这个检测在登录游戏的时候会通过SharedUserData->KdDebuggerEnabled检测 进入游戏后也一直检测,但在游戏中的时候会一直清零KdDebuggerEnabled这个标志,我们需要在KeUpdateSystemTime,KeUpdateRunTime,KdPollBreakIn函数中将KdDebuggerEnabled替换成别的恒为1的地址。

  •        KiDebugRoutine没有检测

  •        隐藏kdcom.dll

  •        Hook KdpTrap过滤TASLogin.exe制造的r3异常。只有在调试模式下 KiDebugRoutine 才指向 KdpTrap这个异常处理函数,所以无论怎么创造异常对非调试模式都没有作用。

    附上成果图

[原创]某驱动的内核调试检测学习内核调试引擎加载机制-软件逆向-看雪论坛-安全社区|安全招聘|bbs.pediy.com

[原创]win10 x64双机调试处理方法-软件逆向-看雪论坛-安全社区|安全招聘|bbs.pediy.com

《软件调试》

注:

       源码因为是针对自己的虚拟机,地址我也基本是根据自己虚拟机的硬编码找的,所以肯定没有通用性,但是方法可以参考。写的很粗糙,研究的时候也没想着公布。但既然都发帖了,还是分享一下,希望多多见谅。

[2022冬季班]《安卓高级研修班(网课)》月薪两万班招生中~

最后于 2022-11-20 20:10 被DriverUnload编辑 ,原因:

上传的附件:
  • img.png (1.80MB,4次下载)
  • main.c (11.05kb,21次下载)
  • func.h (13.97kb,17次下载)

文章来源: https://bbs.pediy.com/thread-275226.htm
如有侵权请联系:admin#unsafe.sh