Windows环境下基于Hook技术的调试器及其实现


    稍微了解Windows调试机制的朋友都知道,调试是受操作系统直接支持的,因而调试器在系统中就奠定了其特殊地位。这种调试事件的采集和分发都是由系统完成的。调试器正是通过系统定义的标准接口与调试子系统通信,达到调试的目的。

    众所周知,为了支持调试,在建立调试会话期间,系统会在内核和应用层启用各种公开和未公开的与调试相关的标志,而对这些标志的掌握情况将会直接影响调试器检测技术的效果(反调效果)。也因而,围绕这些调试和反调之间的较量便一发不可收拾了。甚至为了检测或隐藏标志,各种特定的内核驱动都被开发出来并投入使用(比如游戏保护等)。

    基于这样的现状,一个调试爱好者最希望的是什么呢?我是这样想的:“要是系统可以关闭所有调试相关的标志,但仍然可以支持调试就好了!”我想应该多数调试爱好者都有和我一样的心愿吧。然而,这样的美梦做做还可以,要想使这样的梦成为现实,还请劳烦您坚持看下去,我的废话是多了点,呵呵。

    然而,既要要系统支持调试,又要其不开启任何调试相关的标志是不可能的,因为系统正常的调试机制就需要这些标志(比如调试端口一类的)。因而为了实现我们的设想,我们得自己实现一个小型的调试子系统。这个子系统必须实现系统提供给调试器的标准接口API,这样一来,目前我们用到的调试器(本文指的都是三环调试器)几乎不用改动就可以正常的工作。

    实现一个小型调试子系统,关键点在于以下几个方面。一、捕获各类调试事件。二、构造相关的调试数据包。三、对目标进程实施有效而实时的控制。四、解决与调试器进程的同步以及通信问题。下面,我将对每个方面用到的原理做个简单的介绍。

    在调试事件采集部分,是主要的是异常捕获,其次是捕获模块加载/卸载,线程创建/结束事件。通过hook技术,SHE,VEH,我们可以捕获异常事件。特别指出,由于未启用系统调试会话,int 2D异常会分发给异常处理器,进而我们就可以捕获这个事件并传给目标的异常处理程序,达到躲避检测的目的。对于模块的加载/载事件,我们可以通过注册一些回调函数或是hook有关的函数(比如LdrLoadDll或ZwMapViewOfSection等)并做些处理达到目的。至于线程的创建/结束,和捕获模块事件类似,这里不详细介绍了。细节请参考源码。

    在数据包的构造环节,最主要的是认真阅读MSDN文档,严格按照说明构造相关的调试数据包,力求能够精确模仿原系统调试子系统构造的数据包。

    在对目标进程的控制方面,主要采用了我刚不久发的“再谈Dll隐藏”一文中所用到的方法,这里对其进行了一些改进。因为之前的前辈们的事迹知之甚少,所以自己想出这么一个方法来还兴奋不已,并在这时投入使用了。呵呵,坐井观天,让大家见笑了。求个原创原来是这么难啊!在目标进程中有我们的服务线程为调试器进程提供相关情报。如果要挂起目标进程,则必须挂起除我们的服务线程以外的所有其它线程(如果我们的服务线程挂起了,那可就全线冻结了)。

    最后一个让人头疼的问题便是与调试器进程的同步和通信问题了。原理是非常简单的,用事件内核对象进行同步。至于进程通信,方法有很多种。这里我是采用了一组内存映射文件进行数据交换的。至于这样使用是否合适,还坐等有经验的朋友们给指点一下。然而,虽说原理是这样简单,实现起来确没有想象的顺利。我目前上的一个“求助贴”就是这里给引出来的。构建多线程程序(再加上一堆hook)确实是件头疼的事情。目前,我的代码里还有不少bug,希望在大家的帮助下能够渐渐得到修正。

    以上是针对我们自己构建的调试子系统的简单介绍,接下来,我还想对本文提到的这个小项目再嗦几句。该项目主要由两大部分组成,一个是调试子系统的引擎birdengine,它是被植入到目标进程中执行的。另一部分为一个OD插件strawberrybird,该插件内含相关标准调试接口(API)的实现以及对OD的一些补丁操作。特别指出,birdengine生成的dll文件是以资源的形式包含在插件dll中的;开发编译以及测试环境为win7系统,在xp下的表现和win7略有不同,原因我也在探索中,如果有程序载入失败,建议试下附加功能;访插件针对的是OD标准1.10版,我不能保证与现在的OD改进版可以兼容,因为有内存补丁,大家在编译和测试的时候一定要注意,。此外,为了辅助调试,插件中增加了“断点内存保护”功能,防止在目标运行期间代码自修改恢复断点,插件还解决了OD设置硬件断点有时不能应用到所有线程的问题。下图是本插件工作框架示意图。



    再说明一点,本插件只是展示一种调试方法,它距完全实用还有一段很长的路要走。里边还有好多问题需要解决。由于本人也是菜鸟,水平实在有限,一些问题仍然无法得到理想的解决方案。这里我完全开源了,希望对调试爱好者们有所帮助,也希望这个东东在大家的努力下功能更加强大起来!

    最后,感谢仙果和教主在百忙中对我的点拨。正是他们的帮助才使我坚持把这个项目弄到这个程度。虽然还很不完善,不过我还是挺兴奋的。过程中学到了不少知识。仍然写上这句话,作为本文的结尾“好好学习,天天向上”。

上传的附件 hook based debugger.rar