一种抵抗符号执行和污点分析的软件保护方法与流程

文档序号:13250327阅读:232来源:国知局
技术领域本发明涉及计算机安全技术领域,具体涉及一种可抵抗符号执行和污点分析的软件保护方法。

背景技术:
随着计算机和网络的发展,软件已经成为人们日常生活中不可缺少的一部分,这些软件如办公软件、购物软件、游戏软件等给人们带来极大的方便,但同时也遭受到了巨大的安全威胁。攻击者攻击软件的方式主要有:软件逆向、代码盗用、恶意篡改和盗版等。攻击者要想实施攻击首先要分析软件的内部逻辑结构、软件的控制流结构及软件的语义信息,然后实施进一步的攻击。近年来,基于结合符号执行和污点分析的二进制代码逆向分析研究发展迅速,这种技术结合了传统的静态分析和动态分析的优点,能够对二进制代码进行全面而准确的逆向分析。具体方法是:首先,记录一条程序执行路径的详细信息(如寄存器、内存、变量、指令等),称为程序的一条执行轨迹;接着,使用符号执行和向前污点传播技术对执行轨迹中的敏感路径信息和敏感数据的传播信息进行收集和形式化表示;然后,进行路径可达性推理,得到软件的行为同用户输入、网络输入、系统状态等外部环境间的依赖关系。进一步,对收集到的这些依赖关系采用合适的代码简化技术(如算术简化、间接内存参考简化、数据传输简化等)进行有效的简化,去除一些冗余的代码;最后,构造出整个程序的完整的控制流图和数据流图。这种逆向方法已经被广泛地应用到软件测试、漏洞发掘、恶意代码分析、协议分析和代码复用等安全领域。严重威胁着软件业领域的健康发展。背景技术针对目前软件安全面临着严重威胁的情况,本发明的目的在于,提供一种抵抗符号执行和污点分析的软件保护方法,该方法利用计算机系统,对windows系统下的可执行文件进行保护,保护强度高,易于扩展。为了实现上述任务,本发明采用以下技术方案:一种抵抗符号执行和污点分析的软件保护方法,包括以下步骤:步骤一,对待保护PE文件的合法性进行检查;步骤二,定位待保护软件的关键代码段;步骤三,对关键代码段进行反汇编得到汇编指令,即本地指令序列;步骤四,根据本地指令序列中的跳转指令,进行基本块的划分,找出每个基本块的前必经基本块,构建基本块信息表,信息表中包括当前基本块、当前基本块的前必经基本块的起始地址、结束地址和当前基本块的状态信息;步骤五,设计异常指令,并建立异常指令库,从异常指令库中随机选择异常指令插入到基本块的结束位置;步骤六,将基本块中的跳转指令用异常指令进行替换,构建中断信息表,表中记录异常指令的当前地址以及异常指令所在基本块的目的地址;对中断信息表中的内容根据基本块中的最后一条指令根据指令类型的不同进行填充;步骤七,添加异常处理机制,并采用双进程的模式,实现指令的跳转功能;步骤八,对PE文件进行重构。进一步地,所述的保护方法保护的软件在执行过程中,执行到关键代码段遇到异常指令时,触发异常并由调试器进程捕获,此时调试器进程根据触发中断指令的地址,查看中断信息表,得到目的地址,再查看基本块信息表以得知该目的地址在哪一个基本块,得到这个基本块的状态,如果这个基本块被加密,则先解密再执行。进一步地,所述的步骤四中进行基本块划分的具体方法包括:(1)根据步骤三中得到本地指令序列进行遍历,找出所有指令序列中的跳转指令,包括条件跳转指令和非条件跳转指令,记录下来这些指令的指令序列、指令地址、指令操作码和指令操作数;(2)根据找出的跳转指令进行基本块的划分,划分基本块的方法为:(2-1)标出所有的首指令,首指令有以下几种情况:a.函数的第一条指令是首指令;b.任意一个转移指令的跳转目标都是首指令;c.紧跟在条件转移指令之后的指令都是首指令;(2-2)将某条首指令开始到下一个首指令之前的所有指令划分为一个基本块。进一步地,所述的步骤四还包括:基本块加密:计算基本块的指令条数作为基本块的加密秘钥,对基本块内的指令进行加密处理,则基本块划分结束后均处于加密状态。进一步地,所述的步骤六中对于基本块的最后一条指令进行处理的方法包括:如果基本块最后一条指令是普通指令,则在该指令拷贝到新节后添加一条异常指令,把异常指令的地址记录到中断信息表中,其中目的地址为该指令在原关键代码段中的下一条指令的地址;如果基本块最后一条指令为直接跳转指令,则需要处理跳转的目标地址;记原跳转指令为src:jmprel,其中src为该指令的地址,则跳向的目标地址为dest=src+rel;而拷贝到新节的跳转指令为src’:jmpxx,则xx为跳转指令到dest的偏移,即为dest-src’;在新节中把跳转指令替换成异常指令,则在中断信息表中记录新节中对应跳转指令的地址,中断信息表中的目的地址即为上面计算出来的xx;如果基本块最后一条指令为条件跳转指令,则在拷贝到新节中的条件跳转指令后面添加两个异常指令,这两个异常指令的信息同样也要记录到中断表中,其中第一个异常指令对应的目的地址为原关键代码段的条件跳转指令的下一条指令的地址,第二个异常指令对应的目的地址为原关键代码段对应的条件跳转指令跳向的目标地址。本发明与现有技术相比具有以下技术特点:1.针对二进制代码进行保护,与使用的编程语言无关,适用性广;2.由于将程序中的跳转指令用异常指令进行替换,攻击者在进行程序分析的时候,无法捕获到程序中的跳转指令,因此在进行用符号执行和污点分析进行路径探索不能够求解出路径的约束方程,所以不能得出程序中的控制依赖关系和数据的传播路径,这使得软件中的关键信息得以保护;3.通过引入双进程的思想来阻断污点传播路径,同时使用不透明谓词技术插入伪造的路径分支使混淆后的程序和原程序具有相似的指令分布规律,减少软件内部路径分支信息的泄漏,阻止符号执行和污点分析对路径分支信息的收集和形式化,进而增加逆向分析的难度。附图说明图1为本发明的流程分解示意图;图2为本发明方法的原理图;图3为利用本发明方法保护的程序执行过程的示例图;图4为基本块的最后一个指令是普通指令时跳转示例图;图5为基本块的最后一个指令是直接跳转指令时跳转示例图;图6为基本块的最后一个指令为条件跳转指令时跳转示例图;图7为PE文件重构时的结构示意图;具体实施方式本发明的一种抵抗符号执行和污点分析的软件保护方法,具体包括以下步骤:步骤一,对待保护PE文件的合法性进行检查;验证载入的待保护文件是否为PE文件,验证的方法是检查待保护文件中的标志信息,查找对应的标志位,如果标志位是合法的则判断出所载入的PE文件是合法的,否则就是不合法的PE文件,不进行后续的操作。在本发明中的PE文件是指windows平台上主流的可执行文件格式,如:.exe文件.dll文件等。在本例中,文件格式可以通过PEheader开始的标志Signature来检测。(1)判断文件开始的第一个字段是否为IMAGE_DOS_SIGNATURE,即5A4Dh。(2)再通过e_lfanew找到IMAGE_NT_HEADERS,判断Signature字段的值是否为IMAGE_NT_SIGNATURE,即00004550h,如果是IMAGEE_NT_SIGNATURE,就可以认为该文件是PE格式。步骤二,定位待保护软件的关键代码段关键代码段是指目标文件中需要被保护的代码,即是指定位软件中的核心算法(如压缩软件中的压缩算法、加密软件中的加密算法等),或者对重要数据进行操作的代码。因为保护的过程中只关心软件中的关键部分,这样可以在软件保护后保护强度和性能开销有一个权衡。对关键代码段进行定位,具体可采用在这些代码段的首尾添加标记,例如:#defineNISL_START_emit_(0xEB,0x0C,0x4E,0x49,0x53,0x4C,0x56,0x4D,0x53,0x54,0x41,0x52,0x54,0x00)#defineNISL_END_emit_(0xEB,0x0C,0x4E,0x49,0x53,0x4C,0x56,0x4D,0x45,0x4E,0x44,0x00,0x00,0x00)实际操作时,将NISL_START和NISL_END两个宏定义复制到待保护文件的源文件中,并将两个宏添加到关键代码段的首尾处,源文件编译后即可实现首尾标记的嵌入。步骤三,对关键代码段进行反汇编得到汇编指令,即本地指令序列,具体过程包括:(1)根据定位首尾标记在待保护的文件中找到关键代码段,得到关键代码段的起始地址和结束地址;(2)利用反汇编工具(如xde等)将得到的关键代码段的二进制代码反汇编得到汇编指令,按照指令地址,指令操作码、指令操作数,顺序地组成一个本地指令序列。步骤四,根据本地指令序列中的跳转指令,进行基本块的划分,找出每个基本块的前必经基本块,构建基本块信息表,信息表中包括当前基本块、当前基本块的前必经基本块的起始地址,结束地址和当前基本块的状态信息;(1)根据步骤三中反汇编的本地指令序列进行遍历,找出所有指令序列中的跳转指令,包括条件跳转指令和非条件跳转指令,例如jmp、jz、jp等指令;记录下来这些指令的指令序列、指令地址、指令操作码和指令操作数;(2)根据找出的跳转指令进行基本块的划分,划分基本块的方法为:(2-1)标出所有的首指令,首指令有以下几种情况:a.函数的第一条指令是首指令;b.任意一个转移指令的跳转目标都是首指令;c.紧跟在条件转移指令之后的指令都是首指令;(2-2)将某条首指令开始到下一个首指令之前的所有指令划分为一个基本块;(3)根据划分得到的基本块,构建出基本块之间的关系,找出每个基本块的前驱节基本块;这里的基本块之间的关系只是基本块的逻辑执行关系;由于基本块是由相邻的首指令之间的所有指令构成的,为便于后续执行过程,需要根据跳转指令的逻辑关系找出基本块之间的逻辑执行关系;(4)计算基本块的指令条数值作为基本块的加密秘钥,对基本块内的指令进行加密处理,基本块划分结束后都处于加密状态;加密采用的是根据基本块的指令数作为机密秘钥,并修改基本的加密信息状态,使攻击者不能看到源代码,当执行的时候再进行解密;(5)根据以上信息构建一个基本块信息表,基本块信息表中包括当前基本块的起始地址、结束地址,当前基本块的前必经基本块(前必经基本块是指在当前基本块执行之前的一个基本块)的起始地址、结束地址,以及当前基本块是否加密的状态信息,如下表所示:表1:基本块信息表Start_addrEnd_addrIdom_startIdom_endState004018BC004018C300401850004018B01/0004018CE004018D4004018BC004018C51/0004018D600401902004018CE004018D61/0在表1中:Start_addr:表示当前基本块的首地址;End_addr:表示当前基本块的结束地址;Idom_start:表示当前基本块前必经基本块的起始地址;Idom_end:表示当前基本块前必经基本块的结束地址;State:表示当前基本块的状态信息,指当前基本块是否为加密状态,1表示加密,0表示没有加密。步骤五,设计异常指令,并建立异常指令库,从异常指令库中随机选择异常指令插入到基本块的结束位置;异常指令是x86环境下的一些非法指令,这些非法指令是不能执行的,异常指令的作用是在程序的执行过程中产生一个中断异常,这个中断异常由调试进程进行捕获,进而调试进程跳转到原来指令的目的地址。异常指令的设计直接关系到攻击者在进行攻击时能否直接定位到关键跳转指令,单一的异常指令很容易被攻击者发现,因此建立一个异常指令库是非常有必要的。异常指令库中包含了事先写好的一些异常指令,这些指令在实际应用时是被随机选择添加到基本块的最后一条指令。(1)异常指令的设计异常指令是指非法的不可执行的指令,最简单的异常中断指令如:int3,但是直接在程序中添加int3中断指令比较明显,可以加入一些比较隐蔽的异常指令。设计的异常指令包括但不限于:int3、内存读写异常,如对内存区域中的只读地址进行写操作、指针溢出异常;数组越界操作、除零异常等。(2)建立异常指令库异常指令库的建立是在异常指令的设计的基础之上,把异常指令或异常指令的多种变形写到一个异常指令文件中,构成一个异常指令库;在进行保护的时候,系统利用随机函数产生一个随机数,从异常指令库中进行随机选择异常指令,插入到基本块的结束位置。异常指令库如表2所示:表2:异常指令类型和举例说明注:每一种异常指令类型的实例是多种多样的,在实际应用中可根据需要选择。步骤六,将基本块中的跳转指令用异常指令进行替换,构建中断信息表,表中记录异常指令的当前地址以及异常指令所在基本块的目的地址;对中断信息表中的内容根据基本块中的最后一条指令根据指令类型的不同进行填充;将基本块指令中的跳转指令用异常指令(内存读写异常、指针异常、除数异常等)进行替换,并记录异常指令的地址和异常指令的目的地址,当所有的指令替换结束后,生成一个中断地址信息表。对基本块的处理,要根据基本的最后一条地址是直接跳转或者条件跳转,分情况进行处理。在程序执行时遇到异常指令,用异常处理机制进行捕获,查找异常地址表信息,然后由异常处理程序进行跳转到原跳转指令跳向的地址。(1)建立中断地址信息表,中断信息表由异常指令的当前地址和异常指令所在基本块的目的地址组成。为方便表述,下面的异常指令用int3表示。中断信息表的结构如表3所示:表3:中断信息表中断(int3)所在地址目的地址(2)对基本块最后一条指令的处理:(2-1)如果基本块最后一条指令是一条普通指令,则在该指令拷贝到新节后添加一条异常指令int3,把int3地址记录到上述的中断信息表中,目的地址为该指令在原关键代码段中的下一条指令的地址;如图4的示例中,Block2(基本块2)的最后一条跳转指令跳向指令2,所以指令2作为块的最后一条指令,则INT3的目标地址则为指令3的起始地址。(2-2)如果基本块最后一条指令为直接跳转指令,则需要处理跳转的目标地址。如果原跳转指令为src:jmprel,其中src为该指令的地址,则跳向的目标地址为dest=src+rel.而拷贝到新节的跳转指令为src’:jmpxx,则xx为跳转指令到dest的偏移,即为dest-src’。在新节中把跳转指令替换成int3,则在中断信息表中记录新节中对应跳转指令的地址,中断表中的目的地址即为上面计算出来的xx,如图5所示;(2-3)如果基本块最后一条指令为条件跳转指令,有两种处理方法:方法一是和处理直接跳转指令一样可以得到新的跳转指令的目标地址,但是不能直接替换成INT3指令;方法二是在拷贝到新节中的条件跳转指令后面添加两个INT3指令,这两个INT3信息同样也要记录到中断表中,第一个INT3对应的目的地址为原关键代码段的条件跳转指令的下一条指令的地址,第二个INT3对应的地址为原关键代码段对应的条件跳转指令跳向的目标地址。拷贝到新节的JXX的偏移固定为2,如图6所示。步骤七,添加异常处理机制,并采用双进程的模式,实现指令的跳转功能;这里使用双进程的思想,首先父进程创建一个子进程。父进程是调试进程,子进程是被调试进程,当子进程遇到中断或异常时,父进程进行捕获,父进程捕获到异常信息后,查找对应的中断信息表,跳向对应的目的地址,从而实现指令的跳转功能。异常处理程序是指当程序中出现一个系统异常情况时,会有相应的异常处理机制,在Windows操作系统中异常处理机制主要有:结构化异常处理、向量化异常处理、C++异常处理、进程间的相互通信处理异常机制。在本方法中采用进程间的相互通信处理异常机制,这样做的好处是能够一定程度上阻止污染的传播路径,能够抵抗污点分析技术。双进程的创建过程如下:(1)添加调试器进程,调试器DLL名(dbger.dll)和DLL中的启动调试器(创建被调试进程)的导出函数名(AddDbger);(2)用于加载DLL和调用AddDbger的代码,先调用LoadLibraryA加载“dbger.dll”,获取dll的handle,返回到寄存器EAX中;然后调用GetProcAddress获取函数“AddDbger”的地址,地址返回到寄存器EAX中;最后去调用EAX,执行函数“AddDbger”;步骤八,对PE文件进行重构如图7所示,对原PE文件添加一个新节,添加的步骤如下:首先需要计算出新节的大小。新节内容包括以下部分,而且为了方便,每个部分都以0x10个字节进行对齐:代码,及所有需要保护的代码块的拷贝;中断地址映射表;代码块加密信息表;调试器dll名(dbger.dll)和启动调试器的导入函数名(AddDbger)、加载dll的代码,如图7所示。保护后的PE文件在执行过程中,执行到关键代码段遇到异常指令INT3时,触发异常并由调试器进程捕获;此时调试器进程根据触发中断指令的地址,查看中断信息表,得到目的地址,再查看基本块信息表以得知该目的地址在哪一个基本块,得到这个基本块的状态,如果处于明文则调整EIP=目标地址,执行,如果这个基本块被加密,则先解密再执行。
当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1