首 页文章中心黑客软件黑客动画绿色软件私服技术私服下载本站论坛
您当前的位置:黑客之 家文章中心脱壳破解软件破解 → 文章内容 退出登录 用户管理
本类热门文章
相关文章
站内广告
11.4.8 回到入口点(图)
作者:佚名  来源:不详  发布时间:2008-9-25 2:16:15

减小字体 增大字体

11.4.8  回到入口点

在我们刚剖析完的这个巨大的函数返回之后,入口点子程序又例行地调用了一次NtDelayExecution函数,然后调用了另一个在404202处的内部函数。下面是这个函数的的全部内容:

 

 

这个函数又一次执行了我们所熟悉的拷贝导出表的搜索,不过这次是在拷贝的KERNEL32内存块(指向这块内存的指针存储在406004中)上搜索。然后立即调用那个找到的函数。你还得用前边使用过的函数索引的小技巧来确定这次调用的是哪个API函数。为此,在404227上设置一个断点,并观察加载到ECX寄存器中的地址。然后你用这个地址减去KERNEL32内存块的基地址,并将结果除以8。好啦,你得到了当前API的索引。马上对KERNEL32.DLL运行DUMPBIN /EXPORTS,找出这个API的函数名:SetUnhandledExceptionFilter。看来Defender将0040422作为它的未处理异常过滤程序(unhandled exception filter)。未处理异常过滤程序指的是在进程发生了异常而又无可用的处理程序来处理的情况下调用的程序。我们稍后再来考虑这个异常过滤程序以及它的功能。

我们接着看看另一个对NtDelayExecution的调用,它后面跟着另一个内部函数(401746)的调用。这个内部函数开始部分的代码我们非常熟悉,好像是另一段解密代码;而且,这个函数还被加了密。我不打算再讲述这段解密代码了,但有一个细节必须讲一下。在代码开始解密之前,执行了这样两条语句:

 

我之所以提到这两条语句,是因为变量[EBP-9C0]在几行代码之后被作为解密密钥来使用(通过与这个变量进行异或来解密代码)。你可能不记得你前面见过这个全局变量406008。还记得在第一个加密函数快要返回的时候它是怎样对自己进行再加密的吗?在加密过程中,代码计算了加密数据的校验和,并将最终的校验和存储在406008处的全局变量中。我之所以告诉你这些,是因为这是代码中一个异乎寻常的特性——解密密钥是在运行时计算出来的。这样做的一个好处是:任何在加密代码上设置的断点,如果不在此函数再加密前清除掉的话,就会改变这个校验和,从而防止下一个函数正确地解密!我将它命名为Defender,确实名副其实啊:镇守防线不被突破!

我们接着研究这个新的解密函数。这个函数以两个例行的NtDelayExecution调用开始。继而该函数通过这个混乱的接口调用了NtOpenFile函数,字符串“\??\C”以硬编码方式放在代码中。在NtOpenFile执行完后,函数又调用了NtQueryVolumeInformationFile,参数中带有FileFsVolumeInformation信息等级标志(information level flag)。之后,Defender从返回的数据结构中读取偏移地址+8处的数据,并将其存储到局部变量[406020]中。数据结构FILE_FS_VOLUME_INFORMATION中偏移地址+8处的内容是VolumeSerialNumber(这一信息我也是从网站http://undocumented.ntinternals.net上获得的)。

这完全是一段典型的拷贝保护代码,只是稍微有一点不同而已。主分区卷的序列号是一种生成与具体计算机相依赖的特征(码)的好方法。这段代码号是在格式化的时候随机分配给分区的一个32位数。这个值会一直保留到硬盘下一次被格式化。将这个值用于基于序列号的拷贝保护中意味着这段代码号不能在不同计算机上的用户之间共享——每一台计算机都要有一个不同的序列号。这段代码有一个略微有些不同寻常的地方,就是Defender直接使用本地API函数NtQueryVolumeInformationFile来获取主分区卷的序列号。通常程序员会用Win32的GetVolumeInformation这个API来完成这一工作。

我们现在已经快到了当前这个函数的尾声了。在返回前,这个函数又调用了一次NtDelayExecution,执行RDTSC指令,将低32位字作为返回值(好像是无用的返回值)加载到EAX中,然后回到开始处对自己进行再加密。

[] [返回上一页] [打 印]
关于本站 - 网站帮助 - 广告合作 - 下载声明 - 友情连接 - 网站地图 - 文章投稿 - 软件发布 - 购物资讯网 - _