一种程序编译方法、装置及系统与流程

文档序号:18475077发布日期:2019-08-20 20:54阅读:196来源:国知局
一种程序编译方法、装置及系统与流程

本申请涉及软件安全技术领域,特别涉及一种程序编译方法、装置及系统。



背景技术:

目前,攻击者能够采用逆向工程技术通过对程序代码编译完成的执行文件进行反汇编,以恢复程序代码中的高级语义信息,从而帮助攻击者发现软件漏洞进行未经许可的修改,如绕过密码保护、识别和删除软件程序中的版权通知或水印、窃取知识产权等,导致各种软件的安全性较低。

为此,亟需一种能够对软件的程序代码进行保护的方案。



技术实现要素:

有鉴于此,本申请的目的在于提供一种程序编译方法、装置及系统,用以解决现有技术中软件的程序代码安全性较低的技术问题。

本申请提供了一种程序编译方法,包括:

获得待编译的程序代码,所述程序代码中包括至少一个存根函数的调用地址;

获得所述程序代码的编辑脚本,所述编辑脚本与所述存根函数的调用地址相关;

利用所述编辑脚本和所述存根函数的调用地址,重构出所述程序代码中被所述存根函数的调用地址替换的目标函数的调用地址;

基于所述目标函数的调用地址,对所述程序代码进行编译,得到所述程序代码的可执行文件。

上述方法,优选的,所述待编译的程序代码预先通过以下处理生成:

获得原始的程序代码,所述程序代码中包括至少一个目标函数的调用地址;

对所述原始的程序代码进行代码优化处理;

对所述目标函数的调用地址使用相应的存根函数的调用地址进行替换,以得到待编译的程序代码。

上述方法,优选的,对所述目标函数的调用地址使用相应的存根函数的调用地址进行替换,包括:

分别对所述程序代码中的每个所述目标函数的调用地址替换为其各自对应的存根函数的调用地址;

其中,每个所述存根函数的调用地址不同。

上述方法,优选的,对所述目标函数的调用地址使用相应的存根函数的调用地址进行替换,包括:

对所述程序代码中的所述目标函数的调用地址进行分组;

将属于同一分组的所述目标函数的调用地址替换为该分组对应的存根函数的调用地址;

其中,属于不同分组的所述目标函数的调用地址所对应的存根函数的调用地址不同。

上述方法,优选的,利用所述编辑脚本和所述存根函数的调用地址,重构出所述程序代码中被所述存根函数的调用地址替换的目标函数的调用地址,包括:

解析所述编辑脚本中所述存根函数的调用地址在所述程序代码中的位置信息和所述存根函数的调用地址替换目标函数的调用地址时的修改信息;

基于所述位置信息和所述修改信息,重构所述程序代码中所述目标函数的调用地址。

上述方法,优选的,所述程序代码的编辑脚本预先根据所述存根函数的调用地址与所述目标函数的调用地址之间的替换操作信息生成。

上述方法,优选的,还包括:

获得随机变量;

相应的,根据所述存根函数的调用地址与所述目标函数的调用地址之间的替换操作信息,生成所述程序代码的编辑脚本,包括:

根据所述存根函数的调用地址与所述目标函数的调用地址之间的替换操作信息,结合所述随机变量,生成所述程序代码的编辑脚本。

本申请还提供了一种程序编译装置,包括:

代码获得单元,用于获得待编译的程序代码,所述程序代码中包括至少一个存根函数的调用地址;

脚本获得单元,用于获得所述程序代码的编辑脚本,所述编辑脚本与所述存根函数的调用地址相关;

地址重构单元,用于利用所述编辑脚本和所述存根函数的调用地址,重构出所述程序代码中被所述存根函数的调用地址替换的目标函数的调用地址;

代码编译单元,用于基于所述目标函数的调用地址,对所述程序代码进行编译。

本申请还提供了一种程序编译系统,包括:

编辑引擎,用于获得待编译的程序代码,所述程序代码中包括至少一个存根函数的调用地址;获得所述程序代码的编辑脚本,所述编辑脚本与所述存根函数的调用地址相关;利用所述编辑脚本和所述存根函数的调用地址,重构出所述程序代码中被所述存根函数的调用地址替换的目标函数的调用地址;

编译器,用于基于所述目标函数的调用地址,对所述程序代码进行编译。

由以上方案可知,本申请提供的一种程序编译方法、装置及系统,通过编辑脚本对程序代码中的存根函数的调用地址进行编辑,以重构出程序代码中被替换的目标函数的调用地址,之后再基于目标函数的调用地址对程序代码进行编译,从而使得即使可执行文件被反汇编,也会由于其反汇编出的程序代码中存在存根函数而不会被外界解读出程序代码的内容,从而达到保护程序代码的目的,由此提高程序代码的安全性。

附图说明

为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据提供的附图获得其他的附图。

图1为本申请实施例一提供的一种程序编译方法的实现流程图;

图2为本申请实施例一提供的一种程序编译方法的部分流程图;

图3为本申请实施例二提供的一种程序编译装置的结构示意图;

图4为本申请实施例三提供的一种程序编译系统的结构示意图。

具体实施方式

下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。

参考图1,为本申请实施例一提供的一种程序编译方法的实现流程图,适用于能够进行代码编译的设备中,主要用于对需要进行保护的程序代码进行编译,以避免编译出的可执行文件被轻易的反汇编,造成安全漏洞。

在本实施例中,该方法可以包括以下步骤:

步骤101:获得待编译的程序代码。

其中,程序代码中包括至少一个存根函数的调用地址。

也就是说,本实施例中进行代码编译的程序代码是经过替换处理的程序代码,即原始的程序代码中的目标函数的调用地址被存根函数的调用地址替换,由此,参与代码编译的程序代码中包含不可被攻击者轻易识别或解读的存根函数的调用地址。

步骤102:获得程序代码的编辑脚本。

其中,编辑脚本与存根函数的调用地址相关。

也就是说,程序代码的编辑脚本是基于程序代码中替换来的存根函数的调用地址来生成的,因此,在程序代码经过存根函数的调用地址的替换处理之后,编辑脚本也相应的根据存根函数的调用地址相关的替换信息所生成,本实施例中在对待编译的程序代码进行获取之后,再获取该程序代码对应的编辑脚本。

步骤103:利用编辑脚本和存根函数的调用地址,重构出程序代码被存根函数的调用地址替换的目标函数的调用地址。

其中,编辑脚本中包含与存根函数的调用地址相关的替换信息,如替换方式等等,因此,本实施例中可以利用编辑脚本对存根函数的调用地址进行编辑,进而重构出程序代码被存根函数的调用地址替换的目标函数的调用地址。

步骤104:基于目标函数的调用地址,对程序代码进行编译,得到程序代码的可执行文件。

其中,本实施例中可以首先将目标函数的调用地址替换相应的存根函数的调用地址,以实现程序代码的重新编辑,之后,利用代码编译器对程序代码进行编译,在编译过程中遇到存根函数的调用地址时即可利用基于存根函数的调用地址重构出的目标函数的调用地址对目标函数进行调用并编译,例如,基于目标函数的调用地址,跳转到该调用地址对应的内存空间,以调用目标函数再进行编译,以实现对程序代码的编译处理,得到程序代码的可执行文件。

由以上方案可知,本申请提供的一种程序编译方法,通过编辑脚本对程序代码中的存根函数的调用地址进行编辑,以重构出程序代码中被替换的目标函数的调用地址,之后再基于目标函数的调用地址对程序代码进行编译,从而使得即使可执行文件被反汇编,也会由于其反汇编出的程序代码中存在存根函数而不会被外界解读出程序代码的内容,从而达到保护程序代码的目的,由此提高程序代码的安全性。

在一种实现方式中,本实施例中所获取到的程序代码是经过预先复杂化的替换操作的,具体如下,如图2中所示:

步骤201:获得原始的程序代码。

其中,原始的程序代码可以理解为由开发人员基于汇编语言如c或c#等语言撰写生成的程序代码,该程序代码表征开发人员的知识产权,需要对该原始的程序代码进行保护。

需要说明的是,原始的程序代码中包含至少一个目标函数的调用地址,目标函数可以理解为程序运行中的过程的含义,该目标函数的调用地址也可以理解为对过程的引用,在程序代码中可能包含一个或多个对过程的引用。

步骤202:对原始的程序代码进行代码优化处理。

其中,本实施例中的优化处理可以包括有:对原始的程序代码中一些无意义的代码块或代码段进行删除、对原始的程序代码中一些特定的指令或代码进行复杂化替换(如替换成随机的、无意义的或故意误导的指令),等等。

步骤203:对目标函数的调用地址使用相应的存根函数的调用地址进行替换,以得到待编译的程序代码。

其中,本实施例中在进行地址替换时,可以采用不同的替换方案,如下:

第一种替换方案中,可以分别对程序代码中的每个目标函数的调用地址替换为其各自对应的存根函数的调用地址,其中,每个存根函数的调用地址不同,也就是说,对于程序代码中的每个目标函数的调用地址来说,替换它的存根函数的调用地址不同,相应的,每个存根函数在内存中的映射地址不同,由此,程序代码中的每个目标函数即过程被分开打乱,不同的过程映射到不同的内存位置,从而达到对程序代码进行复杂化替换的目的;

第二中替换方案中,可以先对程序代码中所包含的目标函数的调用地址进行分组,相同的目标函数的调用地址分为同一分组,不同的目标函数的调用地址分为不同的分组,如对同一个过程的引用分到同一分组中或者属于同一运行阶段(集群过程)中的多个过程的引用分到同一分组,之后,将属于同一分组的目标函数的调用地址替换为该分组对应的存根函数的调用地址,其中,属于同一分组的目标函数的调用地址所对应的存根函数的调用地址相同,属于不同分组的目标函数的调用地址所对应的存根函数的调用地址不同。例如,对多个相同或多个相关的过程引用可以替换为同一个存根的引用,由此,多个过程或指令将映射到相同的内存地址,从而远离过程引用和内存地址的传统一对一映射,由此进一步对程序代码进行复杂化替换。

等等。

相应的,在原始的程序代码被复杂化替换之后,相应生成出程序代码的编辑脚本,该编辑脚本具体是根据存根函数的调用地址与目标函数的调用地址之间的替换操作信息生成,例如,地址替换的位置、替换方式、替换内容等等替换操作信息,该替换操作信息所表征的是存根函数的调用地址替换目标函数的调用地址的规则或规范,由此,待编译的程序代码的编辑脚本能够用以后续对程序代码进行编辑时的目标函数的调用地址的重构。

具体的,编辑脚本可以基于java语言生成,以java语言基于以上替换操作信息描述存根函数的调用地址在程序代码中的位置信息和存根函数的调用地址替换目标函数的调用地址时的修改信息,以此生成编辑脚本,相应的,编辑脚本中包含有存根函数的调用地址在程序代码中的位置信息和存根函数的调用地址替换目标函数的调用地址时的修改信息,这些位置信息和修改信息则是基于以上替换操作信息中的内容进行生成的。

而在编辑脚本的生成过程中,本实施例中可以通过伪随机数生成器生成并获取到随机变量(如随机数)之后,将随机变量加入到编辑脚本的生成过程中,具体的,在获取到存根函数的调用地址与所述目标函数的调用地址之间的替换操作信息,将这些信息结合随机变量,生成程序代码的编辑脚本。例如,在编辑脚本中确定一个或多个静态呈现的值,如描述位置信息的字节值或描述修改信息的字节值等,将这些静态呈现的值与生成的随机数相结合,以生成编辑脚本中所需要的值,进而生成编辑脚本,由此使得编辑脚本在这些值上面的混淆虽然是已知的,但是在实际的计算如反汇编中是很难从分析上确定的,因此,对于攻击者来说结合了随机变量所生成的编辑脚本是动态变化的,无法预测或分析的,导致无法通过获取编辑脚本实现对可执行文件的反汇编。

在一种实现方式中,本实施例中步骤103在重构目标函数的调用地址时,具体可以通过以下方式实现:

首先,解析编辑脚本中存根函数的调用地址在程序代码中的位置信息和存根函数的调用地址替换目标函数的调用地址时的修改信息。

其中,位置信息表征程序代码在被编辑时的开始位置,即存根函数的调用地址在程序代码中的位置均为重构目标函数的调用地址的开始位置。

而修改信息则可以表征存根函数的调用地址在替换目标函数的调用地址时所涉及的代码修改信息,如替换时更改的字节数量、字节规范、字节位置和字节值等等,这些修改信息也可以表征在基于存根函数的调用地址重构目标函数的调用地址时所需要做的修改信息,如需要修改的字节数量、字节规范、字节位置和修改到哪些字节值等。

之后,再基于这些位置信息和修改信息,重构程序代码中的目标函数的调用地址。

例如,在程序代码中确定出存根函数的调用地址的位置之后,对这些存根函数的调用地址进行与修改信息相对应或相匹配的修改操作,进而重构得到目标函数的调用地址,如在存根函数的调用地址中的地址字节中删除预设的字节值、偏移预设的字节数量等等,以得到相应的目标函数的调用地址。

参考图3,为本申请实施例二提供的一种程序编译装置的结构示意图,该装置适用于能够进行代码编译的设备中,主要用于对需要进行保护的程序代码进行编译,以避免编译出的可执行文件被轻易的反汇编,造成安全漏洞。

在本实施例中,该装置可以包括以下单元:

代码获得单元301,用于获得待编译的程序代码。

其中,程序代码中包括至少一个存根函数的调用地址。

也就是说,本实施例中进行代码编译的程序代码是经过替换处理的程序代码,即原始的程序代码中的目标函数的调用地址被存根函数的调用地址替换,由此,参与代码编译的程序代码中包含不可被攻击者轻易识别或解读的存根函数的调用地址。

脚本获得单元302,用于获得程序代码的编辑脚本。

其中,编辑脚本与存根函数的调用地址相关。

也就是说,程序代码的编辑脚本是基于程序代码中替换来的存根函数的调用地址来生成的,因此,在程序代码经过存根函数的调用地址的替换处理之后,编辑脚本也相应的根据存根函数的调用地址相关的替换信息所生成,本实施例中在对待编译的程序代码进行获取之后,再获取该程序代码对应的编辑脚本。

地址重构单元303,用于利用编辑脚本和存根函数的调用地址,重构出程序代码中被存根函数的调用地址替换的目标函数的调用地址。

其中,编辑脚本中包含与存根函数的调用地址相关的替换信息,如替换方式等等,因此,本实施例中可以利用编辑脚本对存根函数的调用地址进行编辑,进而重构出程序代码被存根函数的调用地址替换的目标函数的调用地址。

代码编译单元304,用于基于目标函数的调用地址,对程序代码进行编译。

其中,本实施例中可以利用代码编译器对程序代码进行编译,在编译过程中遇到存根函数的调用地址时即可利用基于存根函数的调用地址重构出的目标函数的调用地址对目标函数进行调用并编译,例如,基于目标函数的调用地址,跳转到该调用地址对应的内存空间,以调用目标函数再进行编译,以实现对程序代码的编译处理,得到程序代码的可执行文件。

由以上方案可知,本申请提供的一种程序编译装置,通过编辑脚本对程序代码中的存根函数的调用地址进行编辑,以重构出程序代码中被替换的目标函数的调用地址,之后再基于目标函数的调用地址对程序代码进行编译,从而使得即使可执行文件被反汇编,也会由于其反汇编出的程序代码中存在存根函数而不会被外界解读出程序代码的内容,从而达到保护程序代码的目的,由此提高程序代码的安全性。

在一种实现方式中,待编译的程序代码预先通过以下处理生成:

获得原始的程序代码,程序代码中包括至少一个目标函数的调用地址;对原始的程序代码进行代码优化处理;对目标函数的调用地址使用相应的存根函数的调用地址进行替换,以得到待编译的程序代码。

具体的,有以下地址替换方式:

分别对程序代码中的每个目标函数的调用地址替换为其各自对应的存根函数的调用地址;其中,每个存根函数的调用地址不同。

或者

对程序代码中的目标函数的调用地址进行分组;将属于同一分组的目标函数的调用地址替换为该分组对应的存根函数的调用地址;其中,属于不同分组的目标函数的调用地址所对应的存根函数的调用地址不同。

而相应的,程序代码的编辑脚本预先根据存根函数的调用地址与目标函数的调用地址之间的替换操作信息生成。

基于以上方案,本实施例中可以进一步通过获得随机变量,再将随机变量结合到编辑脚本的生成过程中,即:根据存根函数的调用地址与目标函数的调用地址之间的替换操作信息,结合随机变量,生成程序代码的编辑脚本。

在一种实现方式中,地址重构单元303可以通过以下方式重构出目标函数的调用地址:

解析编辑脚本中存根函数的调用地址在程序代码中的位置信息和存根函数的调用地址替换目标函数的调用地址时的修改信息;基于位置信息和修改信息,重构程序代码中目标函数的调用地址。

参考图4,为本申请实施例三提供的一种程序编译系统的结构示意图,该装置适用于能够进行代码编译的设备中,主要用于对需要进行保护的程序代码进行编译,以避免编译出的可执行文件被轻易的反汇编,造成安全漏洞。

在本实施例中,该系统可以包括以下结构:

编辑引擎401,用于获得待编译的程序代码,程序代码中包括至少一个存根函数的调用地址;获得程序代码的编辑脚本,编辑脚本与存根函数的调用地址相关;利用编辑脚本和存根函数的调用地址,重构出程序代码中被存根函数的调用地址替换的目标函数的调用地址。

编译器402,用于基于目标函数的调用地址,对程序代码进行编译。

也就是说,本实施例中进行代码编译的程序代码是经过替换处理的程序代码,即原始的程序代码中的目标函数的调用地址被存根函数的调用地址替换,由此,参与代码编译的程序代码中包含不可被攻击者轻易识别或解读的存根函数的调用地址。在编译器402对这样的程序代码进行编译之前,需要编辑引擎401首先对替换有存根函数的调用地址的程序代码进行重新编辑。具体的,编辑引擎401需要获得编辑脚本来进行重新编辑,而程序代码的编辑脚本是基于程序代码中替换来的存根函数的调用地址来生成的,因此,在程序代码经过存根函数的调用地址的替换处理之后,编辑脚本也相应的根据存根函数的调用地址相关的替换信息所生成,本实施例中在对待编译的程序代码进行获取之后,再获取该程序代码对应的编辑脚本。之后,编辑引擎401利用编辑脚本对存根函数的调用地址进行编辑,进而重构出程序代码被存根函数的调用地址替换的目标函数的调用地址。由此,编译器402就能够基于目标函数的调用地址,对重新编辑的程序代码(将目标函数的调用地址替换相应的存根函数的调用地址,以实现程序代码的重新编辑)进行编译,如基于目标函数的调用地址,跳转到该调用地址对应的内存空间,以调用目标函数再进行编译,以实现对程序代码的编译处理,得到程序代码的可执行文件。

由以上方案可知,本申请提供的一种程序编译系统,利用编辑引擎通过编辑脚本对程序代码中的存根函数的调用地址进行编辑,以重构出程序代码中被替换的目标函数的调用地址,之后利用编译器再基于目标函数的调用地址对程序代码进行编译,从而使得即使可执行文件被反汇编,也会由于其反汇编出的程序代码中存在存根函数而不会被外界解读出程序代码的内容,从而达到保护程序代码的目的,由此提高程序代码的安全性。

在一种实现方式中,待编译的程序代码预先通过以下处理生成:

获得原始的程序代码,程序代码中包括至少一个目标函数的调用地址;对原始的程序代码进行代码优化处理;对目标函数的调用地址使用相应的存根函数的调用地址进行替换,以得到待编译的程序代码。

具体的,有以下地址替换方式:

分别对程序代码中的每个目标函数的调用地址替换为其各自对应的存根函数的调用地址;其中,每个存根函数的调用地址不同。

或者

对程序代码中的目标函数的调用地址进行分组;将属于同一分组的目标函数的调用地址替换为该分组对应的存根函数的调用地址;其中,属于不同分组的目标函数的调用地址所对应的存根函数的调用地址不同。

而相应的,程序代码的编辑脚本预先根据存根函数的调用地址与目标函数的调用地址之间的替换操作信息生成。

基于以上方案,本实施例中可以进一步通过获得随机变量,再将随机变量结合到编辑脚本的生成过程中,即:根据存根函数的调用地址与目标函数的调用地址之间的替换操作信息,结合随机变量,生成程序代码的编辑脚本。

在一种实现方式中,编辑引擎401可以通过以下方式重构出目标函数的调用地址:

解析编辑脚本中存根函数的调用地址在程序代码中的位置信息和存根函数的调用地址替换目标函数的调用地址时的修改信息;基于位置信息和修改信息,重构程序代码中目标函数的调用地址。

基于以上技术方案,以下对本案在对程序代码进行编译保护的具体实现进行举例说明:

首先,对已经编写完成的原始程序代码进行优化处理,如删掉不必要或无意义的语句,之后,对程序代码进行初步复杂化,如将其中一些指令替换成随机的、无意义的或故意误导的指令;

之后,对程序代码中的过程的引用(目标函数的调用地址)替换成存根的引用(存根函数的调用地址),如果所有对过程的引用都被对存根的引用所替代,在后续进行程序代码的重新编辑及编译时,遇到存根的引用时,通过存根的引用将编辑脚本的位置和过程的入口点(地址)传递给编辑引擎;

然后,编辑引擎根据编辑脚本中的信息重构所需的过程并跳转到过程的入口点,由此完成程序代码的编辑过程,并由编译器对重新编辑的程序代码进行编译,生成可执行文件。

另外,对于编辑脚本而言,本案中将编辑脚本随机动态化,具体可以为:使用一个种子为不透明变量的伪随机数生成器,将编辑脚本中静态呈现的值与伪随机数生成器生成的值结合起来,化静为动。

其中,以上方案中的替换可以理解为对程序代码中的代码突变处理,而本案中可以考虑两种类型的突变:一次通过的突变(类型1)和基于集群的突变(类型2)。如下:

类型1、一次修改的实现方式,本案中将程序代码中的各个过程分开打乱,这意味着每个过程都有自己的模板(存根)。因此,不同的过程不会映射到相同的内存位置。本案中对程序代码的混淆(复杂化)处理时的思想是改变程序中的一个过程。在程序代码的编译运行时,这些更改会在第一次编译过程之前通过一轮编辑撤消。为此,本案中将存根放在过程的入口点,在第一次调用编辑引擎时,这个存根将被过程的原始代码覆盖,即对经过存根替换的程序代码进行恢复。这样,对编辑引擎的调用将在对过程的后续调用中被绕过。

类型2、集群突变技术,聚类背后的一般思想是对指令序列足够相似的过程进行分组,以便在不需要太多编辑的情况下从单个模板重构每个指令序列的代码。然后,集群中的过程将映射到相同的内存区域(集群模板)。对集群过程的每个调用都被一个存根替换,存根使用适当的参数调用编辑引擎来指导编辑过程。本案中为了更大程度的复杂化程序代码,可以对分组尽可能扩大,单个集群(分组)越大,总体上集群的数量就越少,由此,更多不同的指令将映射到相同的地址,从而远离指令和内存地址的传统一对一映射,进一步对程序代码复杂化处理,以避免被轻易的反汇编。

其中,以上的编辑脚本必须包含所有必要的信息,以便将模板中的指令转换为原始过程中的指令。此信息包括模板的位置和需要更改的字节的规范以及更改到什么值。本案中用来编码这些信息的格式如下:

editscript=address<editblock>1<editblock>2...<editblock>l$

editblock=m<edit>1<edit>2...<edit>m

edit=offsetnbyte1byte2...byten

可见,编辑脚本以模板的地址开始,即编辑开始的代码地址,它后面跟着一个编辑块的可变序列,每个编辑块指定它持有的编辑数及其序列,并用stop符号$终止。编辑指定偏移量,即,可以跳过的字节数,然后是应该写入的字节数和要写入的字节数。由于编辑脚本中的所有值(地址除外)都是字节,这允许我们简洁地指定修改,同时仍然保持足够的通用性来指定每一个可能的修改。

其次,编辑引擎中将通过存根传递编辑脚本的地址,它将保存适当的程序状态,如寄存器内容、解释编辑脚本、必要时刷新指令缓存、恢复保存的程序状态,最后分支到作为第二个参数传递的过程入口点。需要注意的是,刷新指令缓存的必要性取决于体系结构:在某些体系结构上,例如当前实现中使用的intelia-32体系结构,不需要显式缓存刷新。

基于以上方案,攻击者可以静态地分析编辑脚本,以及编辑器的代码,从而找出使用编辑脚本调用编辑器时所发生的更改。为了克服这个问题,本案中可以使用一个伪随机数生成器,它的种子是一个不透明的变量。一个变量在程序的p点是不透明的,如果它在p点有一个属性,这个属性在混淆时是已知的,但是在计算上很难从分析上确定。

由此,本案中基本思想是将编辑脚本中静态呈现的值与伪随机数生成器生成的值结合起来。由于种子(不透明变量)在模糊时间的值,可以预测伪随机数生成器将生成的值,因此,可以在编辑脚本中编写值,当与伪随机数结合时,编辑脚本将生成所需的值,然后对编辑脚本中的每个字节进行异或,伪随机数生成器在传递给编辑引擎之前创建的字节。

可见,现有技术中由于目前很少有自修改代码,所以许多分析和工具都是基于代码在执行过程中不会更改的假设。而静态反汇编器在检查可执行程序代码部分的内容时一个接一个地解码连续的指令,直到不能再进行反汇编为止。显然,如果指令没有出现在程序的静态映像中,这些方法就会失败。虽然动态反汇编器在程序执行时检查它,对于实际执行的代码,动态反汇编器比静态反汇编器更精确。但是,它们不会为未在使用的特定输入上执行的任何代码提供反汇编。为了减少运行时的开销,动态分析工具通常会“缓存”已经处理过的代码区域的信息。这减少了重复反汇编相同代码的运行时开销。但是,它假定中间代码在执行期间不会更改。

许多其他用于程序分析和逆向工程的工具也无法处理动态更改代码。因此,本案中基于自修改代码,将攻击者工具的不足完全的暴露出来,从而削弱了攻击者。

具体的,本案中对程序代码在编译执行过程中不断变化。因此,现有逆向工具以及对逆向工程的分析所做的许多假设都被破坏了,只要不破坏不透明变量或随机数生成器,该技术就是安全的,由此使程序更难正确地开始拆卸,更不用说恢复高级信息。本实施例中相当于在更接近源头上解决问题,将危险扼杀在摇篮中。如果一个程序已经使用了这些高级混淆技术中的任何一种来混淆,那么就增加了一层额外的保护,使其更难破译程序的实际结构。

需要说明的是,本说明书中的各个实施例均采用递进的方式描述,每个实施例重点说明的都是与其他实施例的不同之处,各个实施例之间相同相似的部分互相参见即可。

最后,还需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。

以上对本申请所提供的一种程序编译方法、装置及系统进行了详细介绍,对所公开的实施例的上述说明,使本领域专业技术人员能够实现或使用本申请。对这些实施例的多种修改对本领域的专业技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本申请的精神或范围的情况下,在其它实施例中实现。因此,本申请将不会被限制于本文所示的这些实施例,而是要符合与本文所公开的原理和新颖特点相一致的最宽的范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1