一种代码加固方法和装置与流程

文档序号:11177613阅读:957来源:国知局
一种代码加固方法和装置与流程

本申请涉及信息安全领域,尤其涉及一种代码加固方法和装置。



背景技术:

随着软件相关技术的发展,用户平时的生活和工作对应用程序的依赖度也随之提高,同时,用户对应用程序的安全意识更在逐渐增强。应用程序在发布后,容易被逆向工具反编译而暴露其源代码,致使该应用程序出现代码泄漏,或者是应用程序被篡改而损害用户利益。因此,有必要对应用程序相关的代码进行加固,以降低应用程序被逆向破解的风险。



技术实现要素:

本申请实施例提供一种代码加固方法和装置,用于降低应用程序被逆向破解的风险。

本申请实施例采用下述技术方案:

一种代码加固方法,包括:接收客户端发送的原始代码;分析所述原始代码的语义,得出分析结果;根据所述分析结果,对所述原始代码进行加固以得到加固代码,其中,所述加固代码与所述原始代码的执行结果等价,且逆向工具对经过编译后的所述加固代码进行反编译的复杂度,大于对经过编译后的所述原始代码进行反编译的复杂度。

可选地,分析所述原始代码的语义,得出分析结果,具体包括:将所述原始代码进行预编译得出预编译文件,得到抽象语法树和控制流图,并选取对应的加固策略,其中,所述加固策略包括:控制流混淆、程序跳转逻辑隐藏和/或插入安全防护代码,则,根据所述分析结果,对所述原始代码进行加固,具体包括:根据所述抽象语法树和控制流图,利用所述加固策略,对所述原始代码进行加固。

可选地,分析所述原始代码的语义,得出分析结果,具体包括下述至少一种:查找到所述原始代码中的分支跳转节点的条件常量;查找到所述原始代码中的类名、函数名和/或变量,则,对所述原始代码进行加固,分别对应于:将所述原始代码中分支跳转节点的条件数常量替换为不可逆的函数运算;将所述原始代码中的类名、函数名和变量名称中的至少一种,替换为预设字母。

可选地,所述原始代码包括下述至少一种:安卓应用工程中的javanativeinterface代码;xcode工程中的c代码、c++代码或objectivec代码。

可选地,得到加固代码后,所述方法还包括:将所述加固代码发送至客户端,以便客户端根据所述加固后代码生成可编译的工程。

可选地,对所述原始代码进行加固,具体包括:对所述原始代码中的有效数据信息进行加固,其中,所述原始代码中包括有有效数据信息和无效数据信息,所述有效数据包括所述原始代码执行过程中所需要的数据,所述无效数据包括所述原始代码执行过程中无需使用的数据。

一种代码加固装置,包括:接收模块,用于接收客户端发送的原始代码;语义分析模块,用于分析所述原始代码的语义,得出分析结果;加固模块,用于根据所述分析结果,对所述原始代码进行加固以得到加固代码,其中,所述加固代码与所述原始代码的执行结果等价,且逆向工具对经过编译后的所述加固代码进行反编译的复杂度,大于对经过编译后的所述原始代码进行反编译的复杂度。

可选地,语义分析模块分析所述原始代码的语义,得出分析结果,具体包括:将所述原始代码进行预编译得出预编译文件,得到抽象语法树和控制流图,并选取对应的加固策略,其中,所述加固策略包括:控制流混淆、程序跳转逻辑隐藏和/或插入安全防护代码,则,加固模块根据所述分析结果,对所述原始代码进行加固,具体包括:根据所述抽象语法树和控制流图,利用所述加固策略,对所述原始代码进行加固。

可选地,语义分析模块分析所述原始代码的语义,得出分析结果,具体包括下述至少一种:查找到所述原始代码中的分支跳转节点的条件常量;查找到所述原始代码中的类名、函数名和/或变量,则,加固模块对所述原始代码进行加固,分别对应于:将所述原始代码中分支跳转节点的条件数常量替换为不可逆的函数运算;将所述原始代码中的类名、函数名和变量名称中的至少一种,替换为预设字母。

可选地,所述原始代码包括下述至少一种:安卓应用工程中的javanativeinterface代码;xcode工程中的c代码、c++代码或objectivec代码。

本申请实施例采用的上述至少一个技术方案能够达到以下有益效果:在接收到客户端发送的原始代码之后,首先分析原始代码的语义,然后根据分析的结果,对原始代码进行加固以得到加固代码,因为得到的加固代码与原始代码的执行结果等价,且逆向工具对经过编译后的加固代码进行反编译的复杂度大大提高,从而降低应用程序被逆向破解的风险。

附图说明

此处所说明的附图用来提供对本申请的进一步理解,构成本申请的一部分,本申请的示意性实施例及其说明用于解释本申请,并不构成对本申请的不当限定。在附图中:

图1为本申请实施例1提供的代码加固方法实现流程示意图;

图2为本申请实施例1提供的代码加固方法适用场景示意图;

图3为本申请实施例2提供的代码加固装置结构示意图。

具体实施方式

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

实施例1

由于java语言具有天生的易反编译特性,利用java编写的应用程序,一般会把涉及到程序的核心算法、加密解密方法、协议等重要信息利用c或c++进行编写,因为c或c++被逆向破解的难度比java更高,这样,相对于全部采用java编写的应用程序,将会降低被逆向破解的风险。

但是,利用c或c++编写的代码,在进行反汇编以及采用逆向工具处理后,同样也面临被逆向破解的风险,因此,有必要对应用程序中的代码进行加固,以降低应用程序被逆向破解的风险。

为解决上述技术问题,本申请实施例1提供了一种代码加固方法,用于降低应用程序被逆向破解的风险。该方法的具体流程示意图如图1所示,包括下述步骤:

步骤s11:接收客户端发送的原始代码。

该步骤中的原始代码,是相对于后续步骤中加固之后的生成的加固代码而言,具体可以是程序工程源代码,例如androidstudio工程中的c代码、c++代码、javanativeinterface代码;xcode工程中的c代码、c++代码、objectivec代码;嵌入式工程中的c代码等。此外,该步骤中的原始代码,还可以是对程序源代码进行预编译,预编译之后生成的代码。

该实施例的执行主体可以是一代码加固服务器,服务器可以接收客户端发送的原始代码,并提供代码加固的核心任务。与服务器连接的有客户端,客户端的数量可以为多个,且可以分为本地客户端和远端客户端。由于本实施例中的代码加固服务器能够对每个客户端发送的原始代码进行加固,进而广泛地同时满足更多用户的代码加固需求。

步骤s12:分析所述原始代码的语义,得出分析结果。

对原始代码进行语义分析,具体可以是分析原始代码的执行控制逻辑、跳转逻辑、字符串对象、库函数调用或核心功能代码块等。

根据上述分析的语义即可得出的分析结果,得到的分析结果的目的,可以是为了后续步骤中对原始代码进行加固时,选用具体对应的加固策略,加固策略具体可以包括下述至少一种:控制流混淆、程序跳转逻辑隐藏、插入防止反编译的安全防护代码和类名、函数名和变量名替换等。

与上述加固策略相对应,该步骤中得到的分析结果具体可以包括:所述原始代码预编译后的抽象语法树和控制流图,因为通过分析抽象语法树和控制流图,可以得出原始代码中的循环控制语句的跳转逻辑等。另外,该步骤中得到的分析结果还可以包括:原始代码的分支跳转节点的条件常量、原始代码中的类名、函数名和/或变量等。

步骤s13:根据所述分析结果,对所述原始代码进行加固以得到加固代码。

其中,所述加固代码与所述原始代码的执行结果等价,即,保证编译后执行所述加固代码所得到的结果,等价于编译后执行原始代码的效果。

另外,采用逆向工具对经过编译后的所述加固代码进行反编译的复杂度,大于利用上述逆向工具对经过编译后的所述原始代码进行反编译的复杂度。

为满足上述两个条件,该步骤中对原始代码进行加固时,根据具体得到的分析结果,可以是采取下述加固策略:将所述原始代码中的循环控制语句替换为功能等价的分支选择语句;将所述原始代码中分支跳转节点的条件数常量替换为不可逆的函数运算;将所述原始代码中的类名、函数名和/或变量名称替换为预设字母;当然还可以在所述原始代码中随机插入冗余代码、花指令等。

另外,由于原始代码中一般包括有效数据信息和无效数据信息,有效数据包括所述原始代码执行过程中所需要的数据,无效数据包括所述原始代码执行过程中无需使用的数据,其中,有效数据信息和无效数据信息可以具体从分析结果中得出。则该步骤中对所述原始代码进行加固时,可以只对原始代码中的有效数据信息进行加固,忽略原始代码中的无效数据信息。这样,在客户端发送的代码量较大时,可以提高代码加固时的执行效率。

步骤s13中得到加固代码后,还可以将所述加固代码发送至客户端,以便客户端对加固代码进行整理,产生可编译的工程,这样,对客户端的加固代码的结果实时可查看、处理,有利于提高代码加固效率。

采用实施例1提供的代码加固方法,在接收到客户端发送的原始代码之后,首先分析原始代码的语义,然后根据分析的结果,对原始代码进行加固以得到加固代码,因为得到的加固代码与原始代码的执行结果等价,且逆向工具对经过编译后的加固代码进行反编译的复杂度大大提高,从而降低应用程序被逆向破解的风险。

该实施例中对原始代码进行加固后得到的加固代码,在其编译公开后,相对于原始代码编译后得到的文件而言,可以大大增加反编译的复杂度,延长反编译所需的时间。尽可能使不法分子因反编译获取的信息的价值远小于其耗费的时间和精力的价值,起到了代码加固的效果。

采用实施例1提供的代码加固方法,可以大大减少逆向工程得到原始代码的概率。逆向工程目前主要通过借助逆向工具,对应用的可执行文件进行反编译、反汇编、通过静态分析等来分析应用程序的业务逻辑或接口数据。本实施例1提供的代码加固方法,可以通过代码混乱变形,隐藏程序原始的控制流,使程序各部分逻辑结构相似,从而有效阻止攻击者使用逆向工具还原出业务逻辑或核心算法。加固代码经编译器编译得到的可执行文件,完全保持原始代码的业务逻辑和功能,并具有明显的抗逆向分析特性。

为详细说明本实施例1提供的代码加固方法,以下将对步骤s13中的代码加固方法的具体执行手段做详细介绍,其中,可以根据实际情况,对接收到的原始代码采取下述一种多等多种的加固方法。

1)把原始代码的执行控制逻辑(如if、while、for、do等控制语句)等效变换为平坦的控制逻辑(如switch…case语句),这样就隐藏了原始代码程序的层次结构,且保证加固代码与原始代码的执行结果等价。

2)在原始代码运行的分支跳转节点,将原来的条件数常量变换为不可逆的函数运算,使逆向工具不能得到跳转逻辑,攻击者也难以通过静态分析得到真实的分支跳转值,且保证加固代码与原始代码的执行结果等价。

另外,对于跳转控制条件和分支语句,还可以在保持原程序逻辑关系的前提下,随机确定控制块的执行顺序,达到模糊控制逻辑、隐藏控制流的目的。

3)插入不透明谓词和冗余代码,此外,在插入不透明谓词和冗余代码时还可以使用随机数,使得代码混淆结果具有差异性,使攻击者更加难以发现代码混淆规律,且保证加固代码与原始代码的执行结果等价。

此外,还可以在原始代码中插入安全防护代码,使反汇编的时候程序出错,让破解者无法清楚正确地反汇编程序的内容,迷失方向。

4)用不能直接猜出含义的通用变量名和函数名a、b、c等替换原始代码中的类名、函数名和/或变量,由于该种混淆方式只改变字符串,不改变原始代码的执行逻辑,同时保证加固代码与原始代码的执行结果等价。

实质上,对原始代码进行代码加固的方式还有很多,例如,在原始代码中增加大量的跳转指令、比较指令、循环指令等。比如条件跳转和比较指令,只有当原始代码运行到此刻时,才能知道程序将会走向哪个分支,因此大量的条件跳转将大大干扰反汇编人员的分析。

采用上述加固手段之后,对于原始代码中的某个函数(或方法)p经加固变换算法o加固后得到函数(或方法)p′,变换前后:1)p和p′执行结果等价;2)p′控制逻辑明显平坦化,即混淆了原始代码执行时的跳转逻辑;3)p′中各分支跳转条件被隐藏。

前文提到,实施例1的执行主体可以是一代码加固服务器,且与代码加固服务器通过网络连接的有多个客户端。在一种具体的实施方式中,实施例1的应用场景如图2所示,其中,在客户端中包括有工作目录、用户工程文件、加固执行引擎等。

上述客户端和服务器通过网络连接,在服务器端包括有apiserver(接口服务器),webserver(网页服务器)、任务处理器、配置服务器、mysql数据库等。其中,上述webserver具体又可以包括登录页面、升级页面、网络设置和用户管理等;上述任务处理器具体包括有原始代码加固程序和升级程序等,源代码加固程序主要起到对源代码加固的作用;上述mysql数据库中具体可以包括有用户信息表、任务信息表和任务处理器表等。

另外,上述webserver中还可以包括有web后台管理系统,web后台管理系统是服务器上的webserver通过web服务,为用户提供服务器后台管理的功能,例如,支持用户修改、设置服务器ip地址;支持服务器升级以及支持用户帐号管理等。

上述客户端可以利用javafx框架实现操作界面,利用c++语言实现加固业务逻辑,客户端配置有运行工程文件的开发环境;服务器端可以采用torando框架实现。

客户端和服务器构成的代码加固系统可以对c,c++,objectivec等语言编辑的代码进行加固。具体例如,对苹果xcodeios工程代码(objectivec/c/c++)进行加固,也可以用于androidjni工程代码(c,c++)进行加固,也可以用于对嵌入式工程的c代码进行加固。

另外,在上述服务器端,可以先预设代码加固规则库,上述规则库可以存储有各种各样的加固规则,这些加固规则可以是与可能得到的、各种各样可能的原始代码分析结果相对应。这样,服务器在具体进行代码加固时,根据步骤s12中得到的分析结果,可以直接查找加固规则库中与该分析结果相对应的加固规则,无需每次针对具体的原始代码,重新确定一次加固规则,从而能够提高服务器的加固效率。

通过上述客户端和服务器系统,用户在客户端加固工程项目的代码时,采用的全部流程可以为以下三个步骤:

1)用户打开客户端,并建立客户端与服务器的连接;用户配置加固工程项目(包括选择待加固的工程,当然也可以配置加固选项),提交加固,客户端调用本地开发环境对工程进行编译分析,客户端在本地对源码文件进行预编译并分析得出加固配置文件(json)上传预编译后的文件和加固配置。

2)服务器执行加固。

3)当服务器对工程代码加固完成之后,客户端可以下载加固后的文件,并对下载后的文件进行后处理(代码整理为可编译的完整工程);还可以加固后可编译性验证;呈现加固结果等。

由于对代码进行加固时,服务器可选的加固方法有很多,因此,服务器可以采取默认模式,即:客户端只负责上传原始代码,服务器选择默认的加固方法对原始代码进行加固;当然,在上述实施方式中,客户端也可以主动选择加固方式,并将选取的加固方式以加固配置文件的方式发送给服务器,这样服务器可以只针对客户端选取的加固方式进行加固,更利于提高加固效率,并且使提供的代码加固方法应用范围更广,适应于不同用户的加固需求。

实施例2

与实施例1提供的代码加固方法对应,本申请还提供一种代码加固装置实施例,可以应用在如图2所示的服务器侧,用于降低应用程序被逆向破解的风险。如图3所示,该装置200包括:

接收模块21,用于接收客户端发送的原始代码,所述原始代码可以包括:安卓应用工程中的javanativeinterface代码;xcode工程中的c代码、c++代码或objectivec代码等。

语义分析模块22,用于分析所述原始代码的语义,得出分析结果;

加固模块23,用于根据所述分析结果,对所述原始代码进行加固以得到加固代码,其中,所述加固代码与所述原始代码的执行结果等价,且逆向工具对经过编译后的所述加固代码进行反编译的复杂度,大于对经过编译后的所述原始代码进行反编译的复杂度。

采用实施例2提供的代码加固装置,在接收到客户端发送的原始代码之后,首先分析原始代码的语义,然后根据分析的结果,对原始代码进行加固以得到加固代码,因为得到的加固代码与原始代码的执行结果等价,且逆向工具对经过编译后的加固代码进行反编译的复杂度大大提高,从而降低应用程序被逆向破解的风险。

上述语义分析模块22得出分析结果,具体可以包括:将所述原始代码进行预编译得出预编译文件,得到抽象语法树和控制流图,并选取对应的加固策略,其中,所述加固策略包括:控制流混淆、程序跳转逻辑隐藏和/或插入安全防护代码,则,加固模块23对所述原始代码进行加固,具体可以包括:根据所述抽象语法树和控制流图,利用所述加固策略,对所述原始代码进行加固。

上述语义分析模块22得出分析结果,具体可以包括:具体包括下述至少一种:查找到所述原始代码中的分支跳转节点的条件常量;查找到所述原始代码中的类名、函数名和/或变量,则,加固模块23对所述原始代码进行加固,分别对应于:将所述原始代码中分支跳转节点的条件数常量替换为不可逆的函数运算;将所述原始代码中的类名、函数名和变量名称中的至少一种,替换为预设字母。

接收模块21接收的原始代码为程序源代码时,则得到加固代码后,所述装置还可以包括加密模块发送模块,用于将所述加固代码发送至客户端,以便客户端根据所述加固后代码生成可编译的工程。

加固模块23对所述原始代码进行加固,具体可以包括:对所述原始代码中的有效数据信息进行加固,其中,所述原始代码中包括有有效数据信息和无效数据信息,所述有效数据包括所述原始代码执行过程中所需要的数据,所述无效数据包括所述原始代码执行过程中无需使用的数据。

本领域内的技术人员应明白,本申请的实施例可提供为方法、系统、或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、cd-rom、光学存储器等)上实施的计算机程序产品的形式。

本申请是参照根据本申请实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。

这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。

这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。

在一个典型的配置中,计算设备包括一个或多个处理器(cpu)、输入/输出接口、网络接口和内存。

内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(ram)和/或非易失性内存等形式,如只读存储器(rom)或闪存(flashram)。内存是计算机可读介质的示例。

计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(pram)、静态随机存取存储器(sram)、动态随机存取存储器(dram)、其他类型的随机存取存储器(ram)、只读存储器(rom)、电可擦除可编程只读存储器(eeprom)、快闪记忆体或其他内存技术、只读光盘只读存储器(cd-rom)、数字多功能光盘(dvd)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitorymedia),如调制的数据信号和载波。

还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、商品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、商品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括要素的过程、方法、商品或者设备中还存在另外的相同要素。

以上仅为本申请的实施例而已,并不用于限制本申请。对于本领域技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本申请的权利要求范围之内。

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