通行证│用户名: 密码: 验证码: 验证码,看不清楚?请点击刷新验证码 电信网通铁通移动   在线
文章搜索:
热门搜索:红客 黑鹰 红客技术 安全动画 红客培训
首页 文章 软件 动画 资源 励志 论坛 邮箱 会员 军事 科技 博客 爱心红客 最近更新 800g资源
 业内新闻 漏洞公告 病毒公告 电脑知识 网络知识 菜鸟入门 攻防教程 黑客攻防 安全编程 工具使用 综合安全 个人安全 安全相关 Q Q安全 原创精华 红客人物 站内事件
您现在的位置: 爱国者安全网 >> 文章类 >> 红客教程 >> 网络编程 >> 文章正文
加密解密:小议ring 3虚拟机调试器
责任编辑:水土不服   更新日期:2007-10-28
 
【  标题  】 小议ring 3虚拟机调试器
【  作者  】 linxer
【  声明  】 俺系初级选手,高手略过。失误之处敬请诸位大侠赐教!


其实虚拟机调试器已经并不是什么新鲜玩意了,估计很多高人都玩烂了,但一直没有看到这方面的文章,今天写代码写的郁闷,决定瞎掰篇文章发上来。

长假漫漫,远离家乡,不能回家,真的很羡慕那些能回家的人,也羡慕那些能趁着长假出去玩耍旅游的人……唉,一个人孤苦伶仃的窝在家里,除了睡觉就是写代码,终日与电脑为伴,研究了下ring 3的虚拟机调试器。原本计划现在应该可以支持调试多进程了,但梦想再度被现实强奸,目前只能勉强跑单任务程序。都怪自己有奢求完美主义的癖好,研究过程中想的东西太多。下面简单介绍下这个东西,高手就请飘过了。

虚拟机调试器,是虚拟机和调试器的结合,代码的执行权限在虚拟机和调试器之间来回切换,这样带来的好处就是程序基本上是步步可控的,程序的行为也一目了然,还有一个好处就是它已经摆脱了传统的下断点方法,只要代码是在虚拟机里面执行,一切断点都是逻辑的虚拟的,这样可以避开一些反调试手段(比如占据硬件断点,CRC效验,API的0xcc断点检,改写内存属性取消内存断点等),总之,它带来的好处是很可观的,但是缺点是速度慢,虚拟机的仿真能力也很重要,要考虑的东西比较多,毕竟虚拟CPU不是真实CPU,利用这个弱点就可以写出针对这种调试器的anti-debug,还有就是虚拟机和调试器的结合地方也可能是新的anti-debug的众矢之的。

下面大致说下这个东西的实现过程,由于水平有限,目前我做的也还不是太好,本可以做好了在写这个的,估计等我弄好了,我就没激情写这个了,我的文章一般都是激情 + 无知的时候写出来的,错误在所难免,凑合着看吧。

一.  X86虚拟机
关于这个,目前论坛上有几篇帖子在讲这个,以前是讲虚拟机脱壳,这个x86虚拟机应该比用来脱壳的简单一些,我们只要仿真基本的寄存器,x86指令识别,寻址系统,指令解析系统就可以了,其它的可以不管,不过为了程序很多时间的执行机会都在虚拟机上,虚拟机的执行系统最好仿真的多些,对那些没有仿真的执行,交给真实CPU去执行。这种执行权限的交替是很费时间的,这也势必要求我们指令解析系统比较强大。
另外虚拟机还必须支持异常的捕获,否则的话,要不会程序流程错乱,要不会虚拟机以后拿不到执行权限。

二.  传统调试器
唉,这个没有什么可讲的,我巨菜,在论坛混的兄弟,都是这方面高手,我就不说了,免得出丢人现眼。

三.  程序执行权限的更替
调试器建立调试进程,断在入口点或者TLS入口上,把真实CPU的状态告知虚拟机,唤醒虚拟机线程,虚拟机开始执行代码,这个时候系统中被调试的线程被调试器设置成阻塞。当发生异常或者要调用系统API(或者要进入内核),这个时候在合适的位置设置个断点,把虚拟机的状态同步到真实CPU上,虚拟机线程阻塞,唤醒被调试线程,让其进行异常处理或者进入内核去工作,工作返回后,会触发进入时设置的断点,这个时候,把断点及时取消,阻塞被调试线程,同步真实CPU状态到虚拟机中,唤醒虚拟机线程开始执行代码。就这样来回进行执行权限的更替。
当然以上是单线程情况下的权限更迭,对多线程多任务的调试,原理和上面一样,但是虚拟机线程基本上不会有休息的时候,它的休息情况由任务调度模块决定。

四.  异常处理
虚拟机中要支持ring 3能出现的所有异常捕获,否则一切都空谈。这也需要对win的异常处理机制比较熟悉,当捕获到异常时,按win的异常处理机制,在马上要执行的第一个异常处理回调函数入口下断点,把权限交给真实CPU,让它进行异常处理,这样当执行到虚拟机下的断点的时候,虚拟机又可以获得控制权了,取出这个异常处理回调函数的返回地址,这个要用来判定什么时候异常处理退出的,在退出的地方要把执行权限再次交给真实CPU的,在退出的地方,虚拟机也要获得下条用户空间代码的位置,设置一个断点,保证异常处理彻底结束时,虚拟机又可以拿到执行权限。当然,上面说的是最简单的情况,比如SEH的展开之类的,会比较复杂,但是处理过程是一样的,关键是要对异常处理流程熟悉。
内存属性导致的异常比较特殊,这里特说下,由于我是在虚拟机上引入了缓存,缓存以页为单位,把进程的内存属性要反映到这些缓存上,我们访问的时候,就会导致同样的异常,虚拟机调试器对这种异常进行捕获,然后它也就O了。

五.  API调用
这个地方一言难尽,说简单很简单,说复杂比有点,关键是虚拟机策略问题。要保证用户空间代码绝大多数都在虚拟机里执行,要看这个。如果一发现API调用,就把执行权限交给真实CPU,这个方法最省事,但是有时候会很无奈,API传回调函数进去了怎么办,像MFC这种恶心的东西咋办。还有一种方法就是对API也放入虚拟机里执行,直到其要进入内核,才让把执行权限交给真实CPU,虚拟机本来就慢,在这样搞,会死人的。
API调用时,如果采用第一种方法,涉及到CPU权限的更迭,如果采用第二种方法,某些API也涉及CPU权限的更迭。这种更迭还是依靠在返回处第一条执行上下断点。

六.  虚拟CPU没有仿真指令的执行问题
对虚拟机里目前搞不定的指令,一律交给真实CPU去执行,比如一些MMX指令,使用频率很低,加上指令仿真特别体力活,去仿真它们需要很大的勇气,还是让真实CPU解决它们吧,这里要注意一点就是,跳转指令还是要全部仿真的,否则执行权限的更替会比较复杂,不复杂的话会没有安全感,把那些乱蹦的指令仿真完了,我们就可以安心的在其紧挨的指令上下断点了,来实现虚拟机和真实CPU执行权限的交互。

七.  虚拟机缓存
这个东西搞的我不行了,如果不从效率考虑,它完全是多余的,没用它的话,每次执行指令,包括指令,操作数都要从被调试进程空间去,执行完后,如果更改了数据,在把数据写回去,系统调用是巨耗CPU时间的,为了不让频繁调用ReadProcessMemory/WriteProcessMemory,最好还是拿点空间出来cache吧,这里面有几个算法要实现,比如怎么cache,cache的边界问题,脏数据的避免等等都是要考虑的,唉,一言难尽,不说了。这几天我很多时间都在排除它的错误,调试虚拟机里运行的程序比较要人命。

八.  对多线程多任务的支持(这块我还没实现,纯属胡说八道)
调试器对进程/线程事件进行处理,当收到创建事件的时候,阻塞之,把它放入活动任务队列,等待虚拟机虚拟执行,被虚拟执行的线程在处理异常或者调用API的时候,这个时候可以选择新的线程进行执行,把原来的线程放入阻塞任务队列中,只要是工作良好的进程线程,按这种方式调度执行应该不会出现问题,因为同步互斥都是win的任务,与虚拟机无关。但是光用上面的方式任务切换是不行的。有些程序会用轮循方式来进行同步,这就要求虚拟调试器有自己的任务调度模块,对活动任务队列中的线程进行调度执行。

好了,就说到这里,吃饭去了。

BTW:伟大的致敬给***大哥,虽然只跟他聊过两次天,他说的很多东西我都听不明白。但是他对调试器的理解让我受益匪浅。当然要说明一点,虽然他跟国内某款虚拟机调试器有着一些关系,但是我们并没有说过这个东西,也没有谈论它的技术问题,他给我灌输的是更高级别的调试器思想。谢谢!
  • 上一篇文章:
  • 下一篇文章:
  • 最近更新
    固顶文章 爱国者安全网2007年度优秀版主评选
    普通文章 瑞星公司01月11日发布 每日计算机病毒及木马播报
    普通文章 破解博彩神助(专注彩票) V2.8.01
    推荐文章 推荐:跨站脚本执行漏洞代码的六点思路
    普通文章 Windows系统下的远程堆栈溢出 实战篇
    普通文章 Windows系统下的远程堆栈溢出 原理篇
    普通文章 MsSQLServer是如何加密口令的
    普通文章 浅谈国内的渗透评估过程
    普通文章 Dvbbs8.1 0DAY(通杀Access和mssql版本)
    普通文章 微软:我们的代码比赛门铁克更安全
    热门文章
    普通文章REAL蛀虫利用播放器漏洞下载恶意程序
    普通文章李彦宏:中国要在互联网领域逐渐超越美国
    普通文章马云:阿里巴巴的成功是一个生态链的成功
    普通文章Ingres用户认证非授权访问漏洞
    普通文章TCPreen FD_SET()函数远程栈溢出漏洞
    普通文章Winace UUE文件解压堆溢出漏洞
    普通文章Pclxav木马猎手第一代特征码引擎源代码
    普通文章IE收藏夹管理小精灵算法分析
    普通文章Extra Drive Pro算法分析历程
    普通文章雨过天晴自我注册
    精彩专题