大家都知道 driver studio 带一个 drivermonitor 的工具能显示程序里面由 dbgprint 输出的字符串这里说说他的工作原理本人也是初学者不对的地方请指教
先说自己的平台环境使用 win build rtm 版这个很重要dbgprint 的实现在各个平台上是有差异的这里只是说以上平台的实现因为我也没有在其他平台上试过所有下面的程序如果您想运行的话请您先看完这个文章再动手否则遇到 bugcheck 别怪我没有提醒
先说 dbgprint 的实现呼出 si bpx ntoskrnl!dbgprint 然后自己随便写个程序只要能断点到 dbgprint 函数就ok可以看到他调用了 vDbgPrintExWithPrefix 函数fstep into 看到这个函数把输入的字符串 vnprintf 到一个 local buffer 里面然后调用了 DebugPrint 调用这个 DebugPrint 函数的参数有 个后两个可以不去研究第一个参数是一个 STRING 变量的指针这个变量构造在 kernel 栈里面他字符串的 buffer 也是构造在 kernel 栈里面 step into DebugPrint 函数他也是简单的调用 DebugService 函数这个函数同样是个参数第一个 表示了 调用类型 = debugprint还有其他的数值比如用于 image load 等等这里我没有详细的研究只是了解 = debugprint第二个参数是 STRING 变量的实际字符串指针第三个参数是字符串的长度记好这几个参数step into DebugService里面这个函数就是真正的实现所在了可以看到他把 调用类型放到了 eax 里面字符指针放入 ecx 里面字符长度放入 edx 里面然后执行了一个 int d idt 看看 d 这个中断指向的是 dbgmsgsys再看看这个文件是属于 driverstudio 的看到这里你应该明白了如果我们要获取dbgprint输出字符串只用替换掉 d 这个中断就ok了这个也是 dbgmsgsys 的做法如果没有安装 driverstuido的话这个中断指向的是 ntoskrnlexe 的 _KiDebugService
总结下我们要写一个新的中断句柄替换掉原来的中断处理(当然要记得 jmp 到原来的处理函数里面)在这个处理函数里面当 eax= 的时候表示 这次是由 dbgprint 引起的这个时候 ecx 指向了字符串的首地址edx 为字符串的长度(这个数据基本可以不使用)这样我们就截获到了 dbgprint 的输出了剩下的就只是实现而已至于中断的修改无非是 sidt 到 idtr 的值索引 到 d 中断的入口保存修改而已
这里我们就已经获取到了输出的字符串剩下一个问题怎么把这个显示出来这个也简单了也就是一个驱动和应用程序通讯的问题实现方式多种多样用一个最普通的方式就行了用 event object每当驱动获取到了一个字符串他就把一个 event 设置成 signaled应用程序 wait 在这个 event 上面如果 event 变成 signaled应用程序就 readfile 一下驱动驱动就返回读取到的字符串这里的实现都是细节问题了做成什么样子的完全看你自己的发挥
到这里就写完了放上源代码
编译环境 + winifsddk
运行环境 windows
首先用 drivermonitor 加载编译出来的 dbgviewsys 文件
然后运行 dbgmonitor就行了
代码写得很简陋我也是初学者难免有错的地方请包涵
再次声明代码的运行环境入上任何非以上环境的朋友请亲自跟蹤 dbgprint 函数明白 传人到 int d 的参数以后再修改本代码以适合你自己的操作系统切记否则 bugcheck 引起的后果自负起码在 windows 下面这个代码是不能运行的 xp 下面没有测试过