护程序的文件头_IMAGE_DOS_HEADER的e_res[0]和 _IMAGE_DOS_HEADER的e_res[1]的位置,这个位置系统没 有使用,因此可作为我们存储验证信息的位置。 验证授权则是授权过程的逆过程,如图6所示。程序从 USB Key的2001文件读取授权码,进行CRC32的校验,然后 将本文件IMAGE_DOS_HEADER字段的e_res[0]和e_res[1] 读取出来。为了防止软件破解者的跟踪,进入SEH的异常处 理程序进行对比验证,如果不能验证成功,则退出程序。 3.2.4 使用SEH机制进行验证 异常(Exception)事件是指程序执行时发生的事件,异常事 件会打断程序正常执行的顺序。在Windows OS异常有以下几种: 表1 异常事件列表 ![]() Windows OS利用80x86处理器的保护机制来捕获处理异 常。Windows提供了结构化的异常处理(SEH) ,SEH是基于 线程的,不同的线程可以有不同的异常处理,每个线程也可以 有多个异常处理程序。SEH异常处理回调函数的入口地址存储 在结构EXCEPTION_REGISTERATION中,其定义如下: EXCEPTION_REGISTERATION STRUCT prev dd ? ;前一个EXCEPTION_REGISTERATION 结构的地址 hander dd ? ;异常处理函数地址 EXCEPTION_REGISTERATION ENDS EXCEPTION_REGISTERATION结构保存在线程信息 块(TIB)中,偏移为0,而寄存器fs:[0]始终是指向这个结构 的, 因此fs:[0]是指向EXCEPTION_REGISTERATION结构的, SHE异常程序入口如图7所示。 ![]() 当异常事件被触发时,注册的异常处理程序就会被调用。 这种情况下,程序的执行的流程就会发生改变,原来程序中发 生异常后的一部分代码将不被执行。利用这个特点,我们新建 一个线程,在线程中触发一个EXCEPTION_INT_DIVIDE_BY_Z ERO(除零错误)的异常事件,在异常程序中进行授权验证。 USB Key中文件2001中存储着密钥password_usb,可执 行文件中IMAGE_DOS_HEADER结构的e_res[1]这个字段是 保留未用的,可用来存储验证字段password_exe,验证的过程 可通过CRC32(循环冗余校验码)算法来计算,如下: CRC32(password_usb)=password_exe 在程序中,通过函数void verify_password()来实现。在此 会使用上述的SEH机制,在函数内部首先将password_usb和 password_exe读取,然后触发一个EXCEPTION_INT_DIVIDE _BY_ZERO,在异常处理函数中进行验证,如果验证成功,则 返回程序的正确路径继续执行,如果验证失败,则直接退出 程序。这样做的好处是函数的反汇编代码不再是正常的代码 的执行,而是在异常触发的时候利用x86对异常处理的机制 跳到另一个环节去运行了,使得程序反汇编跟踪者不明所以。 3.3 测试结果 程序的测试包括各个功能模块的测试。授权模块需要测 试程序在初始化USB Key和可执行文件后,其验证过程是在 异常处理程序中完成,验证结果是否正确。程序完整性的测 试是程序在修改文件的某些部分后,自校验程序是否能够起 作用,发现文件的修改并做出相应的处理。反调试功能主要 是针对调试器ollydbg的调试,是否能够达到一定的反调试的 保护能力。程序的加壳保护主要是程序能否将区块等部分正 确处理,并且不影响程序的正常运行。 3.3.1 验证授权 通过使用USB Key的文件系统工具查看,取出文 件2001中的授权码,经过CRC32的校验和被保护程序 _IMAGE_DOS_HEADER的e_res[0]和_IMAGE_DOS_HEADER 的e_res[1]中存储的校验值是相等的。程序的授权验证机制也 能够正常工作[4]。 3.3.2 程序完整性 程序的完整性校验可以防止程序的修改。下面来验证文 件校验和代码段校验功能的准确性。分别通过修改PE文件中 的某个字节,修改代码段(.text)来实现的。 程序首先进行文件的CRC32的校验。程序映射到内存之 后,读取磁盘上的可执行文件的数据,除去DOS文件头,将 剩下的数据进行CRC32的校验。同时,读取USB Key中2003 |