CN114329352A - 代码保护方法、装置、设备以及存储介质 - Google Patents
代码保护方法、装置、设备以及存储介质 Download PDFInfo
- Publication number
- CN114329352A CN114329352A CN202011049772.6A CN202011049772A CN114329352A CN 114329352 A CN114329352 A CN 114329352A CN 202011049772 A CN202011049772 A CN 202011049772A CN 114329352 A CN114329352 A CN 114329352A
- Authority
- CN
- China
- Prior art keywords
- instruction
- code
- intermediate code
- combination
- target
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Landscapes
- Devices For Executing Special Programs (AREA)
Abstract
本申请实施例公开了一种代码保护方法、装置、设备以及存储介质,该方法包括:获取待保护代码的中间代码,并对上述中间代码进行劣化以得到目标中间代码;从上述目标中间代码中确定出重复指令组合;确定各重复指令组合对应的复合指令,并生成复合中间代码;生成上述复合中间代码中各指令的动态指令操作码,并根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表,其中,不同指令对应的动态指令操作码不同;基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码。采用本发明实施例,可将代码转换为字节码,增加代码安全性。
Description
技术领域
本申请涉及计算机软件技术领域,尤其涉及一种代码保护方法、装置、设备以及存储介质。
背景技术
随着计算机软件技术的发展,JavaScript作为一种可以直接编写在HTML文件中的语言,被广泛地应用在网页设计中。由于JavaScript代码通常是以明文的方式保存的,在并不足够安全的应用场景下很容易被第三方盗用,从而窃取用户数据。因此,大部分网站和终端会采用对JavaScript代码进行加密为密文或者进行代码混淆的方式对原始JavaScript代码进行保护。但在网页执行JavaScript代码的过程中,还是存在将密文还原为原始JavaScript代码的过程,通过快照或者拦截手段可以直接获取到原始JavaScript代码。且由于代码混淆后的JavaScript代码依然保留着JavaScript代码的格式,故而对混淆后的代码进行格式化之后,可以恢复一定的可读性,进而通过静态分析破解出原始JavaScript代码。现有技术无法有效抵抗快照拦截或静态分析等代码破解手段。
发明内容
本申请实施例提供一种代码保护方法、装置、设备以及存储介质,可将代码转换为字节码,增加代码安全性。
第一方面,本申请实施例提供一种代码保护方法,该方法包括:
获取待保护代码的中间代码,并对上述中间代码进行劣化以得到目标中间代码;
从上述目标中间代码中确定出重复指令组合,上述重复指令组合在上述目标中间代码中出现至少两次;
确定上述目标中间代码中各重复指令组合对应的复合指令,并根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码;
生成上述复合中间代码中各指令的动态指令操作码,并根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表,其中,不同指令对应的动态指令操作码不同;
基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码。
结合第一方面,在一种可能的实施方式中,上述方法还包括:
获取虚拟机描述信息,并根据上述虚拟机描述信息和上述指令表生成用于运行上述字节码的虚拟机;
其中,上述虚拟机描述信息包括寄存器数量、寄存器类型、寄存器用途、内存结构、运行栈和异常栈、运行环境的交互要求以及取指-分派-执行循环表;
基于上述字节码及上述虚拟机生成交付代码。
结合第一方面,在一种可能的实施方式中,上述获取待保护代码的中间代码包括:
获取待保护代码,并确定上述待保护代码对应的抽象语法树;
基于上述待保护代码对应的抽象语法树编译得到上述待保护代码的中间代码。
结合第一方面,在一种可能的实施方式中,上述从上述目标中间代码中确定出重复指令组合,包括:
从上述目标中间代码中确定出指令组合及各指令组合在上述目标中间代码中的出现次数;
将上述各指令组合按照上述各指令组合的出现次数进行排序,并将上述出现次数大于阈值的指令组合确定为上述重复指令组合。
结合第一方面,在一种可能的实施方式中,上述目标中间代码中一个重复指令组合对应多个复合指令,其中,任一重复指令组合对应的复合指令的个数不超过上述任一重复指令组合在上述目标中间代码中的出现次数。
结合第一方面,在一种可能的实施方式中,上述根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码,包括:
按照上述目标中间代码中各指令在上述目标中间代码中出现的顺序,确定各重复指令组合与上述目标中间代码中除重复指令组合之外的其他指令的组合顺序;
将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码。
结合第一方面,在一种可能的实施方式中,上述将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令包括:
将上述目标中间代码中的全部各重复指令组合替换为各重复指令组合对应的复合指令;或者
将上述目标中间代码中的部分重复指令组合替换为各重复指令组合对应的复合指令。
结合第一方面,在一种可能的实施方式中,上述对上述中间代码进行劣化,包括:
在上述中间代码中***无实际用途的指令;或者
将上述中间代码中的整数或字符串常量转换为多条运算指令;或者
在上述中间代码中不可达的目标地址中***不完整的指令;或者
将上述中间代码中的指令进行无副作用的顺序交换。
第二方面,本申请实施例提供了一种代码保护装置,该装置包括:
代码获取模块,用于获取待保护代码的中间代码,并对上述中间代码进行劣化以得到目标中间代码;
重复指令确定模块,用于从上述目标中间代码中确定出重复指令组合,上述重复指令组合在上述目标中间代码中出现至少两次;
复合代码生成模块,用于确定上述目标中间代码中各重复指令组合对应的复合指令,并根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码;
指令表生成模块,用于生成上述复合中间代码中各指令的动态指令操作码,并根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表,其中,不同指令对应的动态指令操作码不同;
字节码生成模块,用于基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码。
结合第二方面,在一种可能的实施方式中,上述装置还包括:
虚拟机生成模块,用于获取虚拟机描述信息,并根据上述虚拟机描述信息和上述指令表生成用于运行上述字节码的虚拟机;
其中,上述虚拟机描述信息包括寄存器数量、寄存器类型、寄存器用途、内存结构、运行栈和异常栈、运行环境的交互要求以及取指-分派-执行循环表;
交付代码生成模块,用于基于上述字节码及上述虚拟机生成交付代码。
结合第二方面,在一种可能的实施方式中,上述代码获取模块还包括:
代码编译单元,用于获取待保护代码,确定上述待保护代码对应的抽象语法树,并基于上述待保护代码对应的抽象语法树编译得到上述待保护代码的中间代码。
结合第二方面,在一种可能的实施方式中,上述重复指令确定模块包括:
重复指令筛选单元,用于从上述目标中间代码中确定出指令组合及各指令组合在上述目标中间代码中的出现次数,将上述各指令组合按照上述各指令组合的出现次数进行排序,并将上述出现次数大于阈值的指令组合确定为上述重复指令组合。
结合第二方面,在一种可能的实施方式中,上述目标中间代码中一个重复指令组合对应多个复合指令,其中,任一重复指令组合对应的复合指令的个数不超过上述任一重复指令组合在上述目标中间代码中的出现次数。
结合第二方面,在一种可能的实施方式中,上述复合代码生成模块包括:
指令顺序确定单元,用于按照上述目标中间代码中各指令在上述目标中间代码中出现的顺序,确定各重复指令组合与上述目标中间代码中除重复指令组合之外的其他指令的组合顺序。
指令组合单元,用于将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码。
结合第二方面,在一种可能的实施方式中,上述指令组合单元包括:
复合指令替换单元,用于将上述目标中间代码中的全部各重复指令组合替换为各重复指令组合对应的复合指令;或者将上述目标中间代码中的部分重复指令组合替换为各重复指令组合对应的复合指令。
结合第二方面,在一种可能的实施方式中,上述代码获取模块,包括:
代码劣化单元,用于在上述中间代码中***无实际用途的指令;或者将上述中间代码中的整数或字符串常量转换为多条运算指令;或者在上述中间代码中不可达的目标地址中***不完整的指令;或者将上述中间代码中的指令进行无副作用的顺序交换。
第三方面,本申请实施例提供了一种终端设备,该设备包括处理器和存储器,该处理器和存储器相互连接。该存储器用于存储支持该终端执行上述第一方面和/或第一方面任一种可能的实现方式提供的方法的计算机程序,该计算机程序包括程序指令,该处理器被配置用于调用上述程序指令,执行上述第一方面和/或第一方面任一种可能的实施方式所提供的方法。
第四方面,本申请实施例提供了一种计算机可读存储介质,该计算机可读存储介质存储有计算机程序,该计算机程序被处理器执行以实现上述第一方面和/或第一方面任一种可能的实施方式所提供的方法。
本申请实施例中,通过将待保护代码编译为等效的中间代码并进行劣化,得到目标中间代码,并将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码。其中,可以理解的是,将待保护代码编译为等效的中间代码并进行劣化,可以模糊目标中间代码与待保护代码的关联性,提高代码保护强度。进一步的,将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,可以进一步地模糊复合中间代码与待保护代码的关联性,提高代码保护强度。更进一步的,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码,可以将待保护代码转换为字节码,更进一步地模糊字节码与待保护代码的关联性,提高代码保护强度。利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。可以由此可见,采用本发明实施例,可将代码转换为字节码,增加代码安全性;此外,利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。
附图说明
为了更清楚地说明本申请实施例中的技术方案,下面将对实施例中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1是本申请实施例提供的网络架构示意图;
图2是本申请实施例提供的代码保护方法的一流程示意图;
图3是本申请实施例提供的触发代码保护请求的一场景示意图;
图4是本申请实施例提供的抽象语法树的一结构示意图;
图5是本申请实施例提供的生成交付代码的一流程示意图;
图6是本申请实施例提供的代码保护方法的另一流程示意图;
图7是本申请实施例提供的在虚拟机上运行字节码的一流程示意图;
图8是本申请实施例提供的代码保护装置的结构示意图;
图9是本申请实施例提供的计算机设备的示意图。
具体实施方式
下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
请参见图1,是本发明实施例提供的网络架构的结构示意图。如图1所示,该网络架构可以包括云端服务器2000以及用户终端集群;用户终端集群可以包括多个用户终端,如图1所示,具体包括用户终端3000a、用户终端3000b、…、用户终端3000n;如图1所示,用户终端3000a、用户终端3000b、…、用户终端3000n均可以在满足一定的数据交互条件下,分别建立与云端服务器2000之间的数据连接关系,以便于能够与该云端服务器2000进行数据交互。
为便于理解,本申请实施例可以在图1所示的多个用户终端中选择一个用户终端作为目标用户终端,该目标用户终端可以包括:智能手机、平板电脑、桌上型电脑等需要进行代码保护功能(例如,电子缴费功能,投资管理功能)的智能终端。例如,本申请实施例可以将图1所示的用户终端3000a作为上述目标用户终端,该目标用户终端中可以集成有具备该代码保护功能的目标应用。应当理解,集成在该目标用户终端中目标应用可以统称为应用客户端。其中,上述目标应用可以包括社交应用(例如,用户验证应用)、生活应用(例如,电子缴费应用)、财务应用(例如,投资管理应用)等具有代码保护功能的应用。在该目标用户终端中所应用的待保护代码可以包含该目标用户终端中所应用的待保护代码以及对待保护代码进行编译得到的中间代码。
可以理解的是,本申请实施例中所描述的通过代码保护方法对待保护代码进行转换得到字节码的方案,可以适用于所有在网页或者应用客户端(即前述目标应用)中对代码进行保护的应用场景。其中,当具有代码保护功能的目标应用运行在该目标用户终端中时,该目标用户终端所运行的代码可以包含提前内置在该目标应用中的待保护代码,还可以包含当前通过网络从该服务器2000中下载的待保护代码。
应当理解,本申请实施例可以将提前内置在该目标应用中的待保护代码和当前下载的待保护代码统称为待保护代码。由此可见,本申请实施例可以在网页或者目标应用运行期间,对该待保护代码进行保护处理,以得到前述字节码,从而可以在网页或者应用客户端中运行字节码时,提高代码的安全性,并减少代码保护操作对***内存的占用。
可选的,本申请实施例还可以在该目标用户终端运行目标应用之前,在该目标用户终端中提前对从上述图1所示的服务器2000中所获取到的待保护代码进行字节化处理,以得到前述字节码。从而可以在该目标用户终端运行该目标应用时,直接运行该字节码,以在该目标应用运行期间减少***性能损耗(比如,可以在该目标用户终端中减少代码保护操作对***内存的占用)。可选的,本申请实施例在该目标用户终端运行目标应用之前,还可以在服务器2000中预先对该待保护代码进行字节化处理,得到字节码,从而可以在该目标用户终端运行该目标应用时,通过网络向该服务器2000发送数据下载指令(即数据加载指令),以使该服务器可以基于该下载指令中所携带的终端标识来判断该目标用户终端是否满足字节化条件。若该服务器2000确定该目标用户终端满足字节化条件,即该服务器2000确定该目标用户终端的终端标识的类型属于低端机的标识类型,则可以在该服务器2000中将预先字节化处理后所存储的字节码返回给目标用户终端进行运行,从而可以在该目标应用运行在目标用户终端中时,减少***性能损耗,并可以提高待保护代码的安全性。由此可见,本申请实施例还可以在运行目标应用之前,在目标用户终端或者服务器2000中对待保护代码进行字节化处理,以得到字节码。
可选的,本申请实施例还可以在该目标用户终端运行目标应用之前,在该目标用户终端中提前对从上述图1所示的服务器2000中所获取到的待保护代码进行处理,以得到前述字节码。换言之,该读取到的待保护代码也可以直接被服务器2000处理为字节码从而被目标用户终端获取,并进行后续处理。例如,以上述目标应用为生活应用(电子乘车码)为例,该目标用户终端可以通过该生活应用加载并运行该字节码以得到包含用户验证签名的电子乘车码,并利用该用户验证签名进行身份验证。
本申请实施例所描述的待保护代码可以包含应用于接口的代码、以及应用于协议的代码等等。换言之,该待保护代码中可以包含拉取数据时用于生成验证签名的代码,也可以包含数据通讯时用于描述私有协议的代码,也可以包含进行线上交易时描述交易逻辑的代码。例如,以上述目标应用为生活应用为例,在搭乘地铁前需要通过目标应用生成供用户搭乘地铁的乘车码,该目标用户终端可以通过该生活应用捕捉用户的行为信息并生成乘车码的展示请求。具体包括根据用户的身份信息运行签名生成代码生成用户签名,进而可以将用户签名写入乘车码中,以供后续对用户进行身份验证。其中,运行签名生成代码的过程即需要进行代码保护。
请参见图2,图2是本申请实施例提供的代码保护方法的一流程示意图。如图2所示的代码保护方法包括:
S101:获取待保护代码的中间代码,并对上述中间代码进行劣化以得到目标中间代码。
在一些可行的实施方式中,上述待保护代码可以包括Java代码,JavaScript代码以及C/C++代码等代码。其中,由于Java及JavaScript语言的灵活性,使得利用Java或JavaScript语言进行编写的代码相较于利用C或C++语言进行编写的代码更容易被窃取。在本申请中,为了描述方便,将以对JavaScript代码进行代码保护的过程为例来进行说明。在前端***发展早期,JavaScript代码在前端***中承担的职责并不多,只是简单的提交表单,JavaScript代码非常简单,并不需要任何的保护。但随着前端***的发展,JavaScript代码的功能开始变得复杂,JavaScript代码的文件体积变得越来越大,为了缩小JavaScript代码的文件体积,加快前端数据的传输速度,开始出现了很多对JavaScript代码进行压缩的工具,比如uglify、compressor、clouser等等。这些压缩工具的主要工作方式是合并多个JavaScript代码文件,去除JavaScript代码里的空格符和换行符,压缩JavaScript代码中的变量名,以及删除JavaScript代码中的注释。虽然这些压缩工具的原始目的是为了减少JavaScript代码文件的体积,但是人们发现压缩替换后的JavaScript代码相比于原始JavaScript代码的可读性差了很多。也就是说,对JavaScript代码进行压缩间接起到了代码保护的作用,于是压缩JavaScript代码文件成为了早起对代码进行保护的手段。但随着技术的发展,如Chrome、Firefox等主流浏览器开始提供了格式化JavaScript代码的功能,可以在一定程度上恢复JavaScript代码的可读性。此外,随着浏览器性能及网络速度的提高,很多后端逻辑开始转移到前端运行,例如在很多登录、注册、支付、交易等等页面中,开始依赖JavaScript代码执行关键的数据交互任务,这类JavaScript代码并不希望被人轻易的破解,于是对JavaScript代码进行保护变得日渐重要。具体请一并参见图3,图3是本申请实施例提供的触发代码保护请求的一场景示意图。如图3所示,该场景以图1所对应实施例中的终端3000a为例,其中,可基于终端向用户显示应用A、应用B以及应用C等应用,此时用户可通过点击应用A、应用B以及应用C中的任一应用对其进行访问,从而在访问应用A、应用B以及应用C中的任一应用的过程中,触发对应用A、应用B以及应用C中的任一需要进行代码保护的操作。可选地,在用户触发对应用A、应用B以及应用C中的任一应用中任一段代码进行执行的操作过程中,可将用户试图执行的应用A、应用B以及应用C中的任一应用中指定的代码作为待保护代码,从而进行代码保护操作。其中,当用户通过点击触发应用A中需要执行代码保护的操作,以应用A为第一应用且为生活应用为例,在搭乘地铁前需要通过目标应用生成供用户搭乘地铁的乘车码,该目标用户终端可以通过该应用A捕捉用户的行为信息并生成乘车码的展示请求。具体包括根据用户的身份信息运行签名生成代码生成用户签名,进而可以将用户签名写入乘车码中,以供后续对用户进行身份验证,其中,运行签名生成代码的过程即需要进行代码保护。
在一些可行的实施方式中,JavaScript代码保护主要包括对JavaScript代码进行加密或者混淆。代码加密的过程是预先使用加密算法对需要保护的JavaScript代码进行加密,同时向目标用户终端交付密文和解密程序。目标应用在目标用户终端启动时,先通过解密程序将密文还原为原始代码,再将原始代码传递给JavaScript解释器运行。但由于目标应用在目标用户终端启动时,还是存在将密文解密还原为原始JavaScript代码的过程,第三方通过对目标应用程序采取内存快照或拦截JavaScript解释器入口等手段,依旧可以直接获取原始JavaScript代码。代码混淆是将JavaScript代码转换成一种功能上等价,但是难于阅读和理解的形式。代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码。执行代码混淆的程序被称作代码混淆器,目前已经存在许多种功能各异的代码混淆器。代码混淆包括:将代码中的各种元素,如变量,函数,类的名字改写成无意义的名字,比如改写成单个字母,或是简短的无意义字母组合,或者改写成符号,使得阅读的人无法根据名字猜测其用途。重写代码中的部分逻辑,将其变成功能上等价,但是更难理解的形式,比如将for循环改写成while循环,将循环改写成递归,精简中间变量,等等。打乱代码的格式,比如删除空格,将多行代码挤到一行中,或者将一行代码断成多行等等。但由于混淆后的代码仍然是JavaScript代码,在进行格式化后,可以恢复一定的可读性,并容易以字符串和整数常量作为突破口进行静态分析,强度不高。所以,单纯地采用代码加密或代码混淆手段,无法很好地对JavaScript代码进行保护。
在一些可行的实施方式中,获取待保护代码的中间代码包括:获取待保护代码,并确定上述待保护代码对应的抽象语法树。基于上述待保护代码对应的抽象语法树编译得到上述待保护代码的中间代码。抽象语法树,简称语法树,是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于if-condition-then这样的条件跳转语句,可以使用带有两个分支的节点来表示。具体请一并参见图4,图4是本申请实施例提供的抽象语法树的一结构示意图。其中,10a是原始JavaScript代码,10b是利用抽象语法树对原始JavaScript代码的表示。例如,对原始JavaScript代码中的指令“var a=42;”进行词法分析可以得到:Keyword(var)、Identifier(a)、Punctuator(=)、Numeric(42)、Punctuator(;),进而将原始代码指令中的“=”和“;”去掉,只保留var变量定义,进而连接变量名“a”和变量值“42”。
在一些可行的实施方式中,在得到待保护代码的中间代码之后,可以进一步对上述中间代码进行劣化,包括:在上述中间代码中***无实际用途的指令;或者将上述中间代码中的整数或字符串常量转换为多条运算指令;或者在上述中间代码中不可达的目标地址中***不完整的指令;或者将上述中间代码中的指令进行无副作用的顺序交换。例如,在代码执行到第5步指令之后,需要跳转到第10步指令继续执行,不需要用到中间6-9步指令,则在6-9步指令的目标地址中间***不完整的指令。或者,例如,将整数42改写为形如“e=11+17+14”的运算指令。或者,例如,将指令“var a=42;”与指令“var b=5;”的顺序进行交换。在对中间代码进行劣化之后,可以得到目标中间代码。
S102:从上述目标中间代码中确定出重复指令组合。
在一些可行的实施方式中,在得到上述目标中间代码之后,目标中间代码会经常有一些重复的指令组合。例如,对JavaScript代码在抽象语法树中进行编译之后,会得到一些对同一变量进行赋值并进行相同计算步骤的指令,这些指令就属于重复指令组合,为了进一步提高代码的还原难度,我们可以将确定目标中间代码中的重复指令组合,以及每个重复指令组合在目标中间代码中的位置。
在一些可行的实施方式中,可以从上述目标中间代码中确定出指令组合及各指令组合在上述目标中间代码中的出现次数。将上述各指令组合按照上述各指令组合的出现次数进行排序,并将上述出现次数大于或等于阈值的指令组合确定为上述重复指令组合。例如,对于指令顺序为“ABACDABCDEAB”的目标中间代码,其中指令组合“AB”出现3次,指令组合“CD”出现2次。其中,为了进一步提高代码的还原难度,每次对目标中间代码进行重复指令确定时,其对应的阈值可变。例如,当阈值为2时,重复指令组合为“AB”和“CD”;当阈值为3时,重复指令组合为“AB”。
S103:确定上述目标中间代码中各重复指令组合对应的复合指令,并根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码。
在一些可行的实施方式中,上述目标中间代码中一个重复指令组合对应多个复合指令,其中,任一重复指令组合对应的复合指令的个数不超过上述任一重复指令组合在上述目标中间代码中的出现次数。例如,对于指令顺序为“ABACDABCDEAB”的目标中间代码,其中指令组合“AB”出现3次,指令组合“CD”出现2次。当阈值为2时,重复指令组合为“AB”和“CD”,可以指定重复指令组合“AB”对应的复合指令为“X”,重复指令组合“CD”对应的复合指令为“Y”。为了进一步提高代码的还原难度,可以指定重复指令组合“AB”对应的复合指令为“X1”、“X2”和“X3”,重复指令组合“CD”对应的复合指令为“Y1”和“Y2”。
在一些可行的实施方式中,上述根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码,包括:按照上述目标中间代码中各指令在上述目标中间代码中出现的顺序,确定各重复指令组合与上述目标中间代码中除重复指令组合之外的其他指令的组合顺序。将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码。例如,对于指令顺序为“ABACDABCDEAB”的目标中间代码,其中指令组合“AB”出现3次,指令组合“CD”出现2次。当阈值为2时,重复指令组合为“AB”和“CD”,可以指定重复指令组合“AB”对应的复合指令为“X”,重复指令组合“CD”对应的复合指令为“Y”。可以将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”替换为该重复指令组合对应的复合指令“X”,将重复指令组合“CD”替换为该重复指令组合对应的复合指令“Y”,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码“XAYXYEX”。
在一些可行的实施方式中,上述将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令包括:将上述目标中间代码中的全部各重复指令组合替换为各重复指令组合对应的复合指令。或者将上述目标中间代码中的部分重复指令组合替换为各重复指令组合对应的复合指令。例如,为了进一步提高代码的还原难度,可以将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”全部/部分替换为该重复指令组合对应的复合指令“X”,将重复指令组合“CD”全部/部分替换为该重复指令组合对应的复合指令“Y”,并按照上述组合顺序,将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合,生成复合中间代码“XAYABYEX”。
更进一步地,在一些可行的实施方式中,可以将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”全部或者部分替换为该重复指令组合对应的复合指令“X1”、“X2”或“X3”,将重复指令组合“CD”全部或者部分替换为该重复指令组合对应的复合指令“Y1”或“Y2”,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码“X2AY1ABY2EX1”。
S104:生成上述复合中间代码中各指令的动态指令操作码,并根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表。
在一些可行的实施方式中,例如将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”全部或者部分替换为该重复指令组合对应的复合指令“X1”、“X2”或“X3”,将重复指令组合“CD”全部或者部分替换为该重复指令组合对应的复合指令“Y1”或“Y2”,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码“X2AY1ABY2EX1”。得到复合中间代码包括指令“X2”、“A”、“Y1”、“B”、“Y2”、“E”以及“X1”,为了进一步提高代码的还原难度,可以在每次对复合中间代码进行编译时,分别对“X2”、“A”、“Y1”、“A”、“B”、“Y2”、“E”以及“X1”生成动态指令操作码,例如,生成“X2”的动态指令操作码为“0010”、“A”的动态指令操作码为“0101”、“Y1”的动态指令操作码为“0100”、“B”的动态指令操作码为“1010”、“Y2”的动态指令操作码为“0110”、“E”的动态指令操作码为“0111”以及“X1”的动态指令操作码为“1100”。
进一步地,根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表如表1所示。其中,表1为根据复合中间代码生成的指令表。
表1
指令 | 动态指令操作码 | 操作数 |
X2 | 0010 | 00110101 |
A | 0101 | 00100100 |
Y1 | 0100 | 10110011 |
B | 1010 | 11001010 |
Y2 | 0110 | 01010101 |
E | 0111 | 11001100 |
X1 | 1100 | 01001101 |
S105:基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码。
在一些可行的实施方式中,例如根据目标中间代码“ABACDABCDEAB”生成复合中间代码“X2AY1ABY2EX1”。以及根据复合中间代码生成的指令表“X2”的动态指令操作码为“0010”、操作数为“00110101”,“A”的动态指令操作码为“0101”、操作数为“00100100”,“Y1”的动态指令操作码为“0100”、操作数为“10110011”,“B”的动态指令操作码为“1010”、操作数为“11001010”,“Y2”的动态指令操作码为“0110”、操作数为“01010101”,“E”的动态指令操作码为“0111”、操作数为“11001100”,以及“X1”的动态指令操作码为“1100”、操作数为“01001101”。基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码:“0010 00110101 0101 00100100 0100 10110011 0101 00100100 1010 11001010 011001010101 0111 11001100 1100 01001101”。
在一些可行的实施方式中,具体请一并参见图5,图5是本申请实施例提供的生成交付代码的一流程示意图。如图5所示,在生成字节码之后,可以获取虚拟机描述信息,并根据上述虚拟机描述信息和上述指令表生成用于运行上述字节码的虚拟机。并对上述字节码及上述虚拟机进行包装,生成交付代码。其中,上述虚拟机描述信息包括寄存器数量、寄存器类型、寄存器用途、内存结构、运行栈和异常栈、运行环境的交互要求以及取指-分派-执行循环表。
本申请实施例中,通过将待保护代码编译为等效的中间代码并进行劣化,得到目标中间代码,并将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码。其中,可以理解的是,将待保护代码编译为等效的中间代码并进行劣化,可以模糊目标中间代码与待保护代码的关联性,提高代码保护强度。进一步的,将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,可以进一步地模糊复合中间代码与待保护代码的关联性,提高代码保护强度。更进一步的,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码,可以将待保护代码转换为字节码,更进一步地模糊字节码与待保护代码的关联性,提高代码保护强度。利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。可以由此可见,采用本发明实施例,可将代码转换为字节码,增加代码安全性;此外,利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。
进一步地,请参见图6,图6是本申请实施例提供的代码保护方法的另一流程示意图。如图6所示的执行主体为目标用户终端,上述方法可以包含以下步骤:
S301:从驱动层获取消息通知。
为便于理解,实现该实施例的目标用户终端可以包括:智能手机、平板电脑、桌上型电脑等需要进行代码保护功能(例如,电子缴费功能,投资管理功能)的智能终端,该目标用户终端中可以集成有具备该代码保护功能的目标应用。应当理解,集成在该目标用户终端中目标应用可以统称为应用客户端。其中,上述目标应用可以包括社交应用(例如,用户验证应用)、生活应用(例如,电子缴费应用)、财务应用(例如,投资管理应用)等具有代码保护功能的应用。在该目标用户终端中所应用的待保护代码可以包含该目标用户终端中所应用的待保护代码以及对待保护代码进行编译得到的中间代码。
可以理解的是,本申请实施例中所描述的通过代码保护方法对待保护代码进行转换得到字节码的方案,可以适用于所有在网页或者应用客户端(即前述目标应用)中对代码进行保护的应用场景。其中,当具有代码保护功能的目标应用运行在该目标用户终端中时,该目标用户终端所运行的代码可以包含提前内置在该目标应用中的待保护代码,还可以包含当前通过网络从该服务器2000中下载的待保护代码。
应当理解,本申请实施例可以将提前内置在该目标应用中的待保护代码和当前下载的待保护代码统称为待保护代码。由此可见,本申请实施例可以在网页或者目标应用运行期间,对该待保护代码进行保护处理,以得到前述字节码,从而可以在网页或者应用客户端中运行字节码时,提高代码的安全性,并减少代码保护操作对***内存的占用。
其中,目标用户终端中的驱动层一般由硬件抽象层(HAL)、板级支持包(BSP)和驱动程序组成,是嵌入式***中不可或缺的重要部分。它的作用是为上层程序提供外部设备的操作接口,并且实现设备的驱动程序。上层程序可以不管操作的设备内部实现,只需要调用驱动的接口即可。
代码保护请求验证程序获取到驱动层发送的消息通知之后,需要进行如S302-S303的步骤对消息的有效性进行验证,若验证成功,则执行步骤S304,否则,返回步骤S301并处于挂起状态。
S302:从消息通知中解析出目标应用的应用信息,并从目标应用的应用信息中的命令行参数中解析出目标应用的代码保护事件对应的待保护代码及校验信息。
S303:从消息通知中解析出目标应用的应用信息,并从目标应用的应用信息中的命令行参数中解析出目标应用的代码保护事件对应的待保护代码及校验信息。
可选的,本申请实施例还可以在该目标用户终端运行目标应用之前,在该目标用户终端中提前对从服务器中所获取到的待保护代码进行字节化处理,以得到前述字节码。从而可以在该目标用户终端运行该目标应用时,直接运行该字节码,以在该目标应用运行期间减少***性能损耗(比如,可以在该目标用户终端中减少代码保护操作对***内存的占用)。可选的,本申请实施例在该目标用户终端运行目标应用之前,还可以在服务器中预先对该待保护代码进行字节化处理,得到字节码,从而可以在该目标用户终端运行该目标应用时,通过网络向该服务器发送数据下载指令(即数据加载指令),以使该服务器可以基于该下载指令中所携带的终端标识来判断该目标用户终端是否满足字节化条件。若该服务器确定该目标用户终端满足字节化条件,即该服务器确定该目标用户终端的终端标识的类型属于低端机的标识类型,则可以在该服务器中将预先字节化处理后所存储的字节码返回给目标用户终端进行运行,从而可以在该目标应用运行在目标用户终端中时,减少***性能损耗,并可以提高待保护代码的安全性。由此可见,本申请实施例还可以在运行目标应用之前,在目标用户终端或者服务器中对待保护代码进行字节化处理,以得到字节码。
可选的,本申请实施例还可以在该目标用户终端运行目标应用之前,在该目标用户终端中提前对从服务器中所获取到的待保护代码进行处理,以得到前述字节码。换言之,该读取到的待保护代码也可以直接被服务器处理为字节码从而被目标用户终端获取,并进行后续处理。例如,以上述目标应用为生活应用(电子乘车码)为例,该目标用户终端可以通过该生活应用加载并运行该字节码以得到包含用户验证签名的电子乘车码,并利用该用户验证签名进行身份验证。
本申请实施例所描述的待保护代码可以包含应用于接口的代码、以及应用于协议的代码等等。换言之,该待保护代码中可以包含拉取数据时用于生成验证签名的代码,也可以包含数据通讯时用于描述私有协议的代码,也可以包含进行线上交易时描述交易逻辑的代码。例如,以上述目标应用为生活应用为例,在搭乘地铁前需要通过目标应用生成供用户搭乘地铁的乘车码,该目标用户终端可以通过该生活应用捕捉用户的行为信息并生成乘车码的展示请求。具体包括根据用户的身份信息运行签名生成代码生成用户签名,进而可以将用户签名写入乘车码中,以供后续对用户进行身份验证。其中,运行签名生成代码的过程即需要进行代码保护。
在一些可行的实施方式中,驱动层获取目标应用的应用信息。其中,应用信息包括命令行参数,命令行参数携带目标应用的代码保护事件对应的待保护代码及校验信息。通过策略引擎将目标应用的应用信息上抛给代码保护请求验证程序,并向代码保护验证程序发送消息通知。
S304:若目标应用信息校验成功,则将待保护代码发送给代码保护处理程序。
在本申请中,为了描述方便,将以对JavaScript代码进行代码保护的过程为例来进行说明。在前端***发展早期,JavaScript代码在前端***中承担的职责并不多,只是简单的提交表单,JavaScript代码非常简单,并不需要任何的保护。但随着前端***的发展,JavaScript代码的功能开始变得复杂,JavaScript代码的文件体积变得越来越大,为了缩小JavaScript代码的文件体积,加快前端数据的传输速度,开始出现了很多对JavaScript代码进行压缩的工具,比如uglify、compressor、clouser等等。这些压缩工具的主要工作方式是合并多个JavaScript代码文件,去除JavaScript代码里的空格符和换行符,压缩JavaScript代码中的变量名,以及删除JavaScript代码中的注释。虽然这些压缩工具的原始目的是为了减少JavaScript代码文件的体积,但是人们发现压缩替换后的JavaScript代码相比于原始JavaScript代码的可读性差了很多。也就是说,对JavaScript代码进行压缩间接起到了代码保护的作用,于是压缩JavaScript代码文件成为了早起对代码进行保护的手段。但随着技术的发展,如Chrome、Firefox等主流浏览器开始提供了格式化JavaScript代码的功能,可以在一定程度上恢复JavaScript代码的可读性。此外,随着浏览器性能及网络速度的提高,很多后端逻辑开始转移到前端运行,例如在很多登录、注册、支付、交易等等页面中,开始依赖JavaScript代码执行关键的数据交互任务,这类JavaScript代码并不希望被人轻易的破解,于是对JavaScript代码进行保护变得日渐重要。
在一些可行的实施方式中,JavaScript代码保护主要包括对JavaScript代码进行加密或者混淆。代码加密的过程是预先使用加密算法对需要保护的JavaScript代码进行加密,同时向目标用户终端交付密文和解密程序。目标应用在目标用户终端启动时,先通过解密程序将密文还原为原始代码,再将原始代码传递给JavaScript解释器运行。但由于目标应用在目标用户终端启动时,还是存在将密文解密还原为原始JavaScript代码的过程,第三方通过对目标应用程序采取内存快照或拦截JavaScript解释器入口等手段,依旧可以直接获取原始JavaScript代码。代码混淆是将JavaScript代码转换成一种功能上等价,但是难于阅读和理解的形式。代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码。执行代码混淆的程序被称作代码混淆器,目前已经存在许多种功能各异的代码混淆器。代码混淆包括:将代码中的各种元素,如变量,函数,类的名字改写成无意义的名字,比如改写成单个字母,或是简短的无意义字母组合,或者改写成符号,使得阅读的人无法根据名字猜测其用途。重写代码中的部分逻辑,将其变成功能上等价,但是更难理解的形式,比如将for循环改写成while循环,将循环改写成递归,精简中间变量,等等。打乱代码的格式,比如删除空格,将多行代码挤到一行中,或者将一行代码断成多行等等。但由于混淆后的代码仍然是JavaScript代码,在进行格式化后,可以恢复一定的可读性,并容易以字符串和整数常量作为突破口进行静态分析,强度不高。所以,单纯地采用代码加密或代码混淆手段,无法很好地对JavaScript代码进行保护。
S305:获取待保护代码的中间代码并对中间代码进行劣化以得到目标中间代码。
在一些可行的实施方式中,获取待保护代码的中间代码包括:获取待保护代码,并确定上述待保护代码对应的抽象语法树。基于上述待保护代码对应的抽象语法树编译得到上述待保护代码的中间代码。抽象语法树,简称语法树,是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于if-condition-then这样的条件跳转语句,可以使用带有两个分支的节点来表示。例如,对原始JavaScript代码中的指令“var a=42;”进行词法分析可以得到:Keyword(var)、Identifier(a)、Punctuator(=)、Numeric(42)、Punctuator(;),进而将原始代码指令中的“=”和“;”去掉,只保留var变量定义,进而连接变量名“a”和变量值“42”。
在一些可行的实施方式中,在得到待保护代码的中间代码之后,可以进一步对上述中间代码进行劣化,包括:在上述中间代码中***无实际用途的指令;或者将上述中间代码中的整数或字符串常量转换为多条运算指令;或者在上述中间代码中不可达的目标地址中***不完整的指令;或者将上述中间代码中的指令进行无副作用的顺序交换。例如,在代码执行到第5步指令之后,需要跳转到第10步指令继续执行,不需要用到中间6-9步指令,则在6-9步指令的目标地址中间***不完整的指令。或者,例如,将整数42改写为形如“e=11+17+14”的运算指令。或者,例如,将指令“var a=42;”与指令“var b=5;”的顺序进行交换。在对中间代码进行劣化之后,可以得到目标中间代码。
S306:从目标中间代码中确定出重复指令组合。
在一些可行的实施方式中,在得到上述目标中间代码之后,目标中间代码会经常有一些重复的指令组合。例如,对JavaScript代码在抽象语法树中进行编译之后,会得到一些对同一变量进行赋值并进行相同计算步骤的指令,这些指令就属于重复指令组合,为了进一步提高代码的还原难度,我们可以将确定目标中间代码中的重复指令组合,以及每个重复指令组合在目标中间代码中的位置。
在一些可行的实施方式中,可以从上述目标中间代码中确定出指令组合及各指令组合在上述目标中间代码中的出现次数。将上述各指令组合按照上述各指令组合的出现次数进行排序,并将上述出现次数大于或等于阈值的指令组合确定为上述重复指令组合。例如,对于指令顺序为“ABACDABCDEAB”的目标中间代码,其中指令组合“AB”出现3次,指令组合“CD”出现2次。其中,为了进一步提高代码的还原难度,每次对目标中间代码进行重复指令确定时,其对应的阈值可变。例如,当阈值为2时,重复指令组合为“AB”和“CD”;当阈值为3时,重复指令组合为“AB”。
S307:确定上述目标中间代码中各重复指令组合对应的复合指令,并根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码。
在一些可行的实施方式中,上述目标中间代码中一个重复指令组合对应多个复合指令,其中,任一重复指令组合对应的复合指令的个数不超过上述任一重复指令组合在上述目标中间代码中的出现次数。例如,对于指令顺序为“ABACDABCDEAB”的目标中间代码,其中指令组合“AB”出现3次,指令组合“CD”出现2次。当阈值为2时,重复指令组合为“AB”和“CD”,可以指定重复指令组合“AB”对应的复合指令为“X”,重复指令组合“CD”对应的复合指令为“Y”。为了进一步提高代码的还原难度,可以指定重复指令组合“AB”对应的复合指令为“X1”、“X2”和“X3”,重复指令组合“CD”对应的复合指令为“Y1”和“Y2”。
在一些可行的实施方式中,上述根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码,包括:按照上述目标中间代码中各指令在上述目标中间代码中出现的顺序,确定各重复指令组合与上述目标中间代码中除重复指令组合之外的其他指令的组合顺序。将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码。例如,对于指令顺序为“ABACDABCDEAB”的目标中间代码,其中指令组合“AB”出现3次,指令组合“CD”出现2次。当阈值为2时,重复指令组合为“AB”和“CD”,可以指定重复指令组合“AB”对应的复合指令为“X”,重复指令组合“CD”对应的复合指令为“Y”。可以将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”替换为该重复指令组合对应的复合指令“X”,将重复指令组合“CD”替换为该重复指令组合对应的复合指令“Y”,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码“XAYXYEX”。
在一些可行的实施方式中,为了进一步提高代码的还原难度,可以将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”全部/部分替换为该重复指令组合对应的复合指令“X”,将重复指令组合“CD”全部/部分替换为该重复指令组合对应的复合指令“Y”,并按照上述组合顺序,将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合,生成复合中间代码“XAYABYEX”。
更进一步地,在一些可行的实施方式中,可以将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”全部或者部分替换为该重复指令组合对应的复合指令“X1”、“X2”或“X3”,将重复指令组合“CD”全部或者部分替换为该重复指令组合对应的复合指令“Y1”或“Y2”,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码“X2AY1ABY2EX1”。
S308:生成上述复合中间代码中各指令的动态指令操作码,并根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表。
在一些可行的实施方式中,例如将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”全部或者部分替换为该重复指令组合对应的复合指令“X1”、“X2”或“X3”,将重复指令组合“CD”全部或者部分替换为该重复指令组合对应的复合指令“Y1”或“Y2”,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码“X2AY1ABY2EX1”。得到复合中间代码包括指令“X2”、“A”、“Y1”、“B”、“Y2”、“E”以及“X1”,为了进一步提高代码的还原难度,可以在每次对复合中间代码进行编译时,分别对“X2”、“A”、“Y1”、“A”、“B”、“Y2”、“E”以及“X1”生成动态指令操作码,例如,生成“X2”的动态指令操作码为“0010”、“A”的动态指令操作码为“0101”、“Y1”的动态指令操作码为“0100”、“B”的动态指令操作码为“1010”、“Y2”的动态指令操作码为“0110”、“E”的动态指令操作码为“0111”以及“X1”的动态指令操作码为“1100”。并根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表如表2所示。其中,表2为根据复合中间代码生成的指令表。
表2
指令 | 动态指令操作码 | 操作数 |
X2 | 0010 | 00110101 |
A | 0101 | 00100100 |
Y1 | 0100 | 10110011 |
B | 1010 | 11001010 |
Y2 | 0110 | 01010101 |
E | 0111 | 11001100 |
X1 | 1100 | 01001101 |
S309:基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码。
在一些可行的实施方式中,例如根据目标中间代码“ABACDABCDEAB”生成复合中间代码“X2AY1ABY2EX1”。以及根据复合中间代码生成的指令表“X2”的动态指令操作码为“0010”、操作数为“00110101”,“A”的动态指令操作码为“0101”、操作数为“00100100”,“Y1”的动态指令操作码为“0100”、操作数为“10110011”,“B”的动态指令操作码为“1010”、操作数为“11001010”,“Y2”的动态指令操作码为“0110”、操作数为“01010101”,“E”的动态指令操作码为“0111”、操作数为“11001100”,以及“X1”的动态指令操作码为“1100”、操作数为“01001101”。基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码:“0010 00110101 0101 00100100 0100 10110011 0101 00100100 1010 11001010 011001010101 0111 11001100 1100 01001101”。
S309:将交付代码发送给目标应用。
在一些可行的实施方式中,在生成字节码之后,可以获取虚拟机描述信息,并根据上述虚拟机描述信息和上述指令表生成用于运行上述字节码的虚拟机。并对上述字节码及上述虚拟机进行包装,生成交付代码。其中,上述虚拟机描述信息包括寄存器数量、寄存器类型、寄存器用途、内存结构、运行栈和异常栈、运行环境的交互要求以及取指-分派-执行循环表。在具体合成过程中,将指令表中记录的每一条指令的操作码填写到取指-分派-执行循环表中的指令分派表,将指令的具体功能填写到取指-分派-执行循环表。可选地,可以将字节码表达为JavaScript中的二进制数组并进行压缩。添加虚拟机引导程序,初始化运行环境和指定程序入口地址,以及导入和导出全局变量。具体请一并参见图7,图7是本申请实施例提供的在虚拟机上运行字节码的一流程示意图。如图7所示,虚拟机通过对字节码进行解释执行,完成与原始代码逻辑等价的代码功能。在虚拟机接收到执行字节码的请求后,可以通过与宿主环境交互判断运行环境是否正常。若运行环境异常,则通过异常处理程序对异常进行处理。若运行环境正常,则按照取指-分派-执行循环表执行字节码,直至执行完成之后退出。
本申请实施例中,通过将待保护代码编译为等效的中间代码并进行劣化,得到目标中间代码,并将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码。其中,可以理解的是,将待保护代码编译为等效的中间代码并进行劣化,可以模糊目标中间代码与待保护代码的关联性,提高代码保护强度。进一步的,将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,可以进一步地模糊复合中间代码与待保护代码的关联性,提高代码保护强度。更进一步的,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码,可以将待保护代码转换为字节码,更进一步地模糊字节码与待保护代码的关联性,提高代码保护强度。利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。可以由此可见,采用本发明实施例,可将代码转换为字节码,增加代码安全性;此外,利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。
进一步地,请参见图8,图8是本申请实施例提供的代码保护装置的结构示意图。如图8所示,上述装置可以包含:
代码获取模块60,用于获取待保护代码的中间代码,并对上述中间代码进行劣化以得到目标中间代码。
在一些可行的实施方式中,代码获取模块60包括代码编译单元601,用于获取待保护代码,确定上述待保护代码对应的抽象语法树,并基于上述待保护代码对应的抽象语法树编译得到上述待保护代码的中间代码。
在一些可行的实施方式中,代码获取模块60包括代码劣化单元602,用于在上述中间代码中***无实际用途的指令;或者将上述中间代码中的整数或字符串常量转换为多条运算指令;或者在上述中间代码中不可达的目标地址中***不完整的指令;或者将上述中间代码中的指令进行无副作用的顺序交换。
在一些可行的实施方式中,获取待保护代码的中间代码包括:获取待保护代码,并确定上述待保护代码对应的抽象语法树。基于上述待保护代码对应的抽象语法树编译得到上述待保护代码的中间代码。抽象语法树,简称语法树,是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于if-condition-then这样的条件跳转语句,可以使用带有两个分支的节点来表示。其中,10a是原始JavaScript代码,10b是利用抽象语法树对原始JavaScript代码的表示。例如,对原始JavaScript代码中的指令“var a=42;”进行词法分析可以得到:Keyword(var)、Identifier(a)、Punctuator(=)、Numeric(42)、Punctuator(;),进而将原始代码指令中的“=”和“;”去掉,只保留var变量定义,进而连接变量名“a”和变量值“42”。
在一些可行的实施方式中,在得到待保护代码的中间代码之后,可以进一步对上述中间代码进行劣化,包括:在上述中间代码中***无实际用途的指令;或者将上述中间代码中的整数或字符串常量转换为多条运算指令;或者在上述中间代码中不可达的目标地址中***不完整的指令;或者将上述中间代码中的指令进行无副作用的顺序交换。例如,在代码执行到第5步指令之后,需要跳转到第10步指令继续执行,不需要用到中间6-9步指令,则在6-9步指令的目标地址中间***不完整的指令。或者,例如,将整数42改写为形如“e=11+17+14”的运算指令。或者,例如,将指令“var a=42;”与指令“var b=5;”的顺序进行交换。在对中间代码进行劣化之后,可以得到目标中间代码。
重复指令确定模块61,用于从上述目标中间代码中确定出重复指令组合,上述重复指令组合在上述目标中间代码中出现至少两次。
在一些可行的实施方式中,在得到上述目标中间代码之后,目标中间代码会经常有一些重复的指令组合。例如,对JavaScript代码在抽象语法树中进行编译之后,会得到一些对同一变量进行赋值并进行相同计算步骤的指令,这些指令就属于重复指令组合,为了进一步提高代码的还原难度,我们可以将确定目标中间代码中的重复指令组合,以及每个重复指令组合在目标中间代码中的位置。
在一些可行的实施方式中,重复指令确定模块61包括重复指令筛选单元611,用于根从上述目标中间代码中确定出指令组合及各指令组合在上述目标中间代码中的出现次数,将上述各指令组合按照上述各指令组合的出现次数进行排序,并将上述出现次数大于或等于阈值的指令组合确定为上述重复指令组合。
具体地,可以从上述目标中间代码中确定出指令组合及各指令组合在上述目标中间代码中的出现次数。将上述各指令组合按照上述各指令组合的出现次数进行排序,并将上述出现次数大于或等于阈值的指令组合确定为上述重复指令组合。例如,对于指令顺序为“ABACDABCDEAB”的目标中间代码,其中指令组合“AB”出现3次,指令组合“CD”出现2次。其中,为了进一步提高代码的还原难度,每次对目标中间代码进行重复指令确定时,其对应的阈值可变。例如,当阈值为2时,重复指令组合为“AB”和“CD”;当阈值为3时,重复指令组合为“AB”。
复合代码生成模块62,用于确定上述目标中间代码中各重复指令组合对应的复合指令,并根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码。
在一些可行的实施方式中,复合代码生成模块62包括指令顺序确定单元621和指令组合单元622。
其中,指令顺序确定单元621,用于按照上述目标中间代码中各指令在上述目标中间代码中出现的顺序,确定各重复指令组合与上述目标中间代码中除重复指令组合之外的其他指令的组合顺序。
指令组合单元622,用于将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码。
在一些可行的实施方式中,指令组合单元622包括复合指令替换子单元6221,用于将上述目标中间代码中的全部各重复指令组合替换为各重复指令组合对应的复合指令;或者将上述目标中间代码中的部分重复指令组合替换为各重复指令组合对应的复合指令。
在一些可行的实施方式中,上述目标中间代码中一个重复指令组合对应多个复合指令,其中,任一重复指令组合对应的复合指令的个数不超过上述任一重复指令组合在上述目标中间代码中的出现次数。例如,对于指令顺序为“ABACDABCDEAB”的目标中间代码,其中指令组合“AB”出现3次,指令组合“CD”出现2次。当阈值为2时,重复指令组合为“AB”和“CD”,可以指定重复指令组合“AB”对应的复合指令为“X”,重复指令组合“CD”对应的复合指令为“Y”。为了进一步提高代码的还原难度,可以指定重复指令组合“AB”对应的复合指令为“X1”、“X2”和“X3”,重复指令组合“CD”对应的复合指令为“Y1”和“Y2”。
在一些可行的实施方式中,上述根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码,包括:按照上述目标中间代码中各指令在上述目标中间代码中出现的顺序,确定各重复指令组合与上述目标中间代码中除重复指令组合之外的其他指令的组合顺序。将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码。例如,对于指令顺序为“ABACDABCDEAB”的目标中间代码,其中指令组合“AB”出现3次,指令组合“CD”出现2次。当阈值为2时,重复指令组合为“AB”和“CD”,可以指定重复指令组合“AB”对应的复合指令为“X”,重复指令组合“CD”对应的复合指令为“Y”。可以将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”替换为该重复指令组合对应的复合指令“X”,将重复指令组合“CD”替换为该重复指令组合对应的复合指令“Y”,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码“XAYXYEX”。
在一些可行的实施方式中,为了进一步提高代码的还原难度,可以将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”全部/部分替换为该重复指令组合对应的复合指令“X”,将重复指令组合“CD”全部/部分替换为该重复指令组合对应的复合指令“Y”,并按照上述组合顺序,将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合,生成复合中间代码“XAYABYEX”。
更进一步地,在一些可行的实施方式中,可以将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”全部或者部分替换为该重复指令组合对应的复合指令“X1”、“X2”或“X3”,将重复指令组合“CD”全部或者部分替换为该重复指令组合对应的复合指令“Y1”或“Y2”,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码“X2AY1ABY2EX1”。
指令表生成模块63,用于生成上述复合中间代码中各指令的动态指令操作码,并根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表,其中,不同指令对应的动态指令操作码不同。
在一些可行的实施方式中,例如将上述目标中间代码“ABACDABCDEAB”中的重复指令组合“AB”全部或者部分替换为该重复指令组合对应的复合指令“X1”、“X2”或“X3”,将重复指令组合“CD”全部或者部分替换为该重复指令组合对应的复合指令“Y1”或“Y2”,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码“X2AY1ABY2EX1”。得到复合中间代码包括指令“X2”、“A”、“Y1”、“B”、“Y2”、“E”以及“X1”,为了进一步提高代码的还原难度,可以在每次对复合中间代码进行编译时,分别对“X2”、“A”、“Y1”、“A”、“B”、“Y2”、“E”以及“X1”生成动态指令操作码,例如,生成“X2”的动态指令操作码为“0010”、“A”的动态指令操作码为“0101”、“Y1”的动态指令操作码为“0100”、“B”的动态指令操作码为“1010”、“Y2”的动态指令操作码为“0110”、“E”的动态指令操作码为“0111”以及“X1”的动态指令操作码为“1100”。并根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表如表3所示。其中,表3为根据复合中间代码生成的指令表。
表3
指令 | 动态指令操作码 | 操作数 |
X2 | 0010 | 00110101 |
A | 0101 | 00100100 |
Y1 | 0100 | 10110011 |
B | 1010 | 11001010 |
Y2 | 0110 | 01010101 |
E | 0111 | 11001100 |
X1 | 1100 | 01001101 |
字节码生成模块64,用于基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码。
在一些可行的实施方式中,例如根据目标中间代码“ABACDABCDEAB”生成复合中间代码“X2AY1ABY2EX1”。以及根据复合中间代码生成的指令表“X2”的动态指令操作码为“0010”、操作数为“00110101”,“A”的动态指令操作码为“0101”、操作数为“00100100”,“Y1”的动态指令操作码为“0100”、操作数为“10110011”,“B”的动态指令操作码为“1010”、操作数为“11001010”,“Y2”的动态指令操作码为“0110”、操作数为“01010101”,“E”的动态指令操作码为“0111”、操作数为“11001100”,以及“X1”的动态指令操作码为“1100”、操作数为“01001101”。基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码:“0010 00110101 0101 00100100 0100 10110011 0101 00100100 1010 11001010 011001010101 0111 11001100 1100 01001101”。
在一些可行的实施方式中,代码保护装置还包括:虚拟机生成模块65和交付代码生成模块66。其中,虚拟机生成模块65用于获取虚拟机描述信息,并根据上述虚拟机描述信息和上述指令表生成用于运行上述字节码的虚拟机。交付代码生成模块66用于基于上述字节码及上述虚拟机生成交付代码。
其中,上述虚拟机描述信息包括寄存器数量、寄存器类型、寄存器用途、内存结构、运行栈和异常栈、运行环境的交互要求以及取指-分派-执行循环表。在具体合成过程中,将指令表中记录的每一条指令的操作码填写到取指-分派-执行循环表中的指令分派表,将指令的具体功能填写到取指-分派-执行循环表。可选地,可以将字节码表达为JavaScript中的二进制数组并进行压缩。添加虚拟机引导程序,初始化运行环境和指定程序入口地址,以及导入和导出全局变量。具体地,虚拟机通过对字节码进行解释执行,完成与原始代码逻辑等价的代码功能。在虚拟机接收到执行字节码的请求后,可以通过与宿主环境交互判断运行环境是否正常。若运行环境异常,则通过异常处理程序对异常进行处理。若运行环境正常,则按照取指-分派-执行循环表执行字节码,直至执行完成之后退出。
本申请实施例中,通过将待保护代码编译为等效的中间代码并进行劣化,得到目标中间代码,并将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码。其中,可以理解的是,将待保护代码编译为等效的中间代码并进行劣化,可以模糊目标中间代码与待保护代码的关联性,提高代码保护强度。进一步的,将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,可以进一步地模糊复合中间代码与待保护代码的关联性,提高代码保护强度。更进一步的,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码,可以将待保护代码转换为字节码,更进一步地模糊字节码与待保护代码的关联性,提高代码保护强度。利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。可以由此可见,采用本发明实施例,可将代码转换为字节码,增加代码安全性;此外,利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。
参见图9,图9是本申请实施例提供的设备的结构示意图。如图9所示,本实施例中的设备1000可以包括:处理器1001,网络接口1004和存储器1005,此外,上述设备1000还可以包括:用户接口1003,和至少一个通信总线1002。其中,通信总线1002用于实现这些组件之间的连接通信。其中,用户接口1003可以包括显示屏(Display)、键盘(Keyboard),可选用户接口1003还可以包括标准的有线接口、无线接口。网络接口1004可选的可以包括标准的有线接口、无线接口(如WI-FI接口)。存储器1004可以是高速RAM存储器,也可以是非不稳定的存储器(non-volatile memory),例如至少一个磁盘存储器。存储器1005可选的还可以是至少一个位于远离前述处理器1001的存储装置。如图9所示,作为一种计算机可读存储介质的存储器1005中可以包括操作***、网络通信模块、用户接口模块以及设备控制应用程序。
在图9所示的设备1000中,网络接口1004可提供网络通讯功能;而用户接口1003主要用于为用户提供输入的接口;而处理器1001可以用于调用存储器1005中存储的设备控制应用程序,以实现:
获取待保护代码的中间代码,并对上述中间代码进行劣化以得到目标中间代码;
从上述目标中间代码中确定出重复指令组合,上述重复指令组合在上述目标中间代码中出现至少两次;
确定上述目标中间代码中各重复指令组合对应的复合指令,并根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码;
生成上述复合中间代码中各指令的动态指令操作码,并根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表,其中,不同指令对应的动态指令操作码不同;
基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码。
在一些可行的实施方式中,上述方法还包括:
获取虚拟机描述信息,并根据上述虚拟机描述信息和上述指令表生成用于运行上述字节码的虚拟机;
其中,上述虚拟机描述信息包括寄存器数量、寄存器类型、寄存器用途、内存结构、运行栈和异常栈、运行环境的交互要求以及取指-分派-执行循环表;
基于上述字节码及上述虚拟机生成交付代码。
在一些可行的实施方式中,上述获取待保护代码的中间代码包括:
获取待保护代码,并确定上述待保护代码对应的抽象语法树;
基于上述待保护代码对应的抽象语法树编译得到上述待保护代码的中间代码。
在一些可行的实施方式中,上述从上述目标中间代码中确定出重复指令组合,包括:
根从上述目标中间代码中确定出指令组合及各指令组合在上述目标中间代码中的出现次数;
将上述各指令组合按照上述各指令组合的出现次数进行排序,并将上述出现次数大于或等于阈值的指令组合确定为上述重复指令组合。
在一些可行的实施方式中,上述目标中间代码中一个重复指令组合对应多个复合指令,其中,任一重复指令组合对应的复合指令的个数不超过上述任一重复指令组合在上述目标中间代码中的出现次数。
在一些可行的实施方式中,上述根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码,包括:
按照上述目标中间代码中各指令在上述目标中间代码中出现的顺序,确定各重复指令组合与上述目标中间代码中除重复指令组合之外的其他指令的组合顺序;
将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码。
在一些可行的实施方式中,上述将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令包括:
将上述目标中间代码中的全部各重复指令组合替换为各重复指令组合对应的复合指令;或者
将上述目标中间代码中的部分重复指令组合替换为各重复指令组合对应的复合指令。
在一些可行的实施方式中,上述对上述中间代码进行劣化,包括:
在上述中间代码中***无实际用途的指令;或者
将上述中间代码中的整数或字符串常量转换为多条运算指令;或者
在上述中间代码中不可达的目标地址中***不完整的指令;或者
将上述中间代码中的指令进行无副作用的顺序交换。
应当理解,在一些可行的实施方式中,上述处理器1001可以是中央处理单元(central processing unit,CPU),该处理器还可以是其他通用处理器、数字信号处理器(digital signal processor,DSP)、专用集成电路(application specific integratedcircuit,ASIC)、现成可编程门阵列(field-programmable gate array,FPGA)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等。通用处理器可以是微处理器或者该处理器也可以是任何常规的处理器等。该存储器可以包括只读存储器和随机存取存储器,并向处理器提供指令和数据。存储器的一部分还可以包括非易失性随机存取存储器。例如,存储器还可以存储设备类型的信息。
为便于理解,本申请实施例可以在多种用户终端中选择一个用户终端作为目标用户终端,该目标用户终端可以包括:智能手机、平板电脑、桌上型电脑等携带图片数据处理功能(例如,图片拍摄功能,生成用户画像功能)的智能终端。该目标用户终端可以包括:智能手机、平板电脑、桌上型电脑等需要进行代码保护功能(例如,电子缴费功能,投资管理功能)的智能终端。例如,本申请实施例可以将图1所示的用户终端3000a作为上述目标用户终端,该目标用户终端中可以集成有具备该代码保护功能的目标应用。应当理解,集成在该目标用户终端中目标应用可以统称为应用客户端。其中,上述目标应用可以包括社交应用(例如,用户验证应用)、生活应用(例如,电子缴费应用)、财务应用(例如,投资管理应用)等具有代码保护功能的应用。在该目标用户终端中所应用的待保护代码可以包含该目标用户终端中所应用的待保护代码以及对待保护代码进行编译得到的中间代码。
可以理解的是,本申请实施例中所描述的通过代码保护方法对待保护代码进行转换得到字节码的方案,可以适用于所有在网页或者应用客户端(即前述目标应用)中对代码进行保护的应用场景。其中,当具有代码保护功能的目标应用运行在该目标用户终端中时,该目标用户终端所运行的代码可以包含提前内置在该目标应用中的待保护代码,还可以包含当前通过网络从该服务器2000中下载的待保护代码。
应当理解,本申请实施例可以将提前内置在该目标应用中的待保护代码和当前下载的待保护代码统称为待保护代码。由此可见,本申请实施例可以在网页或者目标应用运行期间,对该待保护代码进行保护处理,以得到前述字节码,从而可以在网页或者应用客户端中运行字节码时,提高代码的安全性,并减少代码保护操作对***内存的占用。
可选的,本申请实施例还可以在该目标用户终端运行目标应用之前,在该目标用户终端中提前对从服务器中所获取到的待保护代码进行字节化处理,以得到前述字节码。从而可以在该目标用户终端运行该目标应用时,直接运行该字节码,以在该目标应用运行期间减少***性能损耗(比如,可以在该目标用户终端中减少代码保护操作对***内存的占用)。可选的,本申请实施例在该目标用户终端运行目标应用之前,还可以在服务器中预先对该待保护代码进行字节化处理,得到字节码,从而可以在该目标用户终端运行该目标应用时,通过网络向该服务器发送数据下载指令(即数据加载指令),以使该服务器可以基于该下载指令中所携带的终端标识来判断该目标用户终端是否满足字节化条件。若该服务器确定该目标用户终端满足字节化条件,即该服务器确定该目标用户终端的终端标识的类型属于低端机的标识类型,则可以在该服务器中将预先字节化处理后所存储的字节码返回给目标用户终端进行运行,从而可以在该目标应用运行在目标用户终端中时,减少***性能损耗,并可以提高待保护代码的安全性。由此可见,本申请实施例还可以在运行目标应用之前,在目标用户终端或者服务器中对待保护代码进行字节化处理,以得到字节码。
可选的,本申请实施例还可以在该目标用户终端运行目标应用之前,在该目标用户终端中提前对从服务器中所获取到的待保护代码进行处理,以得到前述字节码。换言之,该读取到的待保护代码也可以直接被服务器处理为字节码从而被目标用户终端获取,并进行后续处理。例如,以上述目标应用为生活应用(电子乘车码)为例,该目标用户终端可以通过该生活应用加载并运行该字节码以得到包含用户验证签名的电子乘车码,并利用该用户验证签名进行身份验证。
本申请实施例所描述的待保护代码可以包含应用于接口的代码、以及应用于协议的代码等等。换言之,该待保护代码中可以包含拉取数据时用于生成验证签名的代码,也可以包含数据通讯时用于描述私有协议的代码,也可以包含进行线上交易时描述交易逻辑的代码。例如,以上述目标应用为生活应用为例,在搭乘地铁前需要通过目标应用生成供用户搭乘地铁的乘车码,该目标用户终端可以通过该生活应用捕捉用户的行为信息并生成乘车码的展示请求。具体包括根据用户的身份信息运行签名生成代码生成用户签名,进而可以将用户签名写入乘车码中,以供后续对用户进行身份验证。其中,运行签名生成代码的过程即需要进行代码保护。
应当理解,上述存储器1005中存储的设备控制应用程序可以包括如下功能模块:
代码获取模块,用于获取待保护代码的中间代码,并对上述中间代码进行劣化以得到目标中间代码;
重复指令确定模块,用于从上述目标中间代码中确定出重复指令组合,上述重复指令组合在上述目标中间代码中出现至少两次;
复合代码生成模块,用于确定上述目标中间代码中各重复指令组合对应的复合指令,并根据上述各重复指令组合对应的复合指令以及上述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码;
指令表生成模块,用于生成上述复合中间代码中各指令的动态指令操作码,并根据上述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表,其中,不同指令对应的动态指令操作码不同;
字节码生成模块,用于基于上述指令表和上述复合中间代码生成上述复合中间代码对应的字节码。
在一些可行的实施方式中,上述装置还包括:
虚拟机生成模块,用于获取虚拟机描述信息,并根据上述虚拟机描述信息和上述指令表生成用于运行上述字节码的虚拟机;
其中,上述虚拟机描述信息包括寄存器数量、寄存器类型、寄存器用途、内存结构、运行栈和异常栈、运行环境的交互要求以及取指-分派-执行循环表;
交付代码生成模块,用于基于上述字节码及上述虚拟机生成交付代码。
在一些可行的实施方式中,上述代码获取模块还包括:
代码编译单元,用于获取待保护代码,确定上述待保护代码对应的抽象语法树,并基于上述待保护代码对应的抽象语法树编译得到上述待保护代码的中间代码。
在一些可行的实施方式中,上述重复指令确定模块包括:
重复指令筛选单元,用于根从上述目标中间代码中确定出指令组合及各指令组合在上述目标中间代码中的出现次数,将上述各指令组合按照上述各指令组合的出现次数进行排序,并将上述出现次数大于或等于阈值的指令组合确定为上述重复指令组合。
在一些可行的实施方式中,上述目标中间代码中一个重复指令组合对应多个复合指令,其中,任一重复指令组合对应的复合指令的个数不超过上述任一重复指令组合在上述目标中间代码中的出现次数。
在一些可行的实施方式中,上述复合代码生成模块包括:
指令顺序确定单元,用于按照上述目标中间代码中各指令在上述目标中间代码中出现的顺序,确定各重复指令组合与上述目标中间代码中除重复指令组合之外的其他指令的组合顺序。
指令组合单元,用于将上述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令,并按照上述组合顺序将上述各重复指令组合对应的复合指令与上述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码。
在一些可行的实施方式中,上述指令组合单元包括:
复合指令替换单元,用于将上述目标中间代码中的全部各重复指令组合替换为各重复指令组合对应的复合指令;或者将上述目标中间代码中的部分重复指令组合替换为各重复指令组合对应的复合指令。
在一些可行的实施方式中,上述代码获取模块,包括:
代码劣化单元,用于在上述中间代码中***无实际用途的指令;或者将上述中间代码中的整数或字符串常量转换为多条运算指令;或者在上述中间代码中不可达的目标地址中***不完整的指令;或者将上述中间代码中的指令进行无副作用的顺序交换。
具体实现中,上述设备1000可通过其内置的各个功能模块执行如上述图2和/或图6中各个步骤所提供的实现方式,具体可参见上述各个步骤所提供的实现方式,在此不再赘述。
本申请实施例中,通过将待保护代码编译为等效的中间代码并进行劣化,得到目标中间代码,并将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码。其中,可以理解的是,将待保护代码编译为等效的中间代码并进行劣化,可以模糊目标中间代码与待保护代码的关联性,提高代码保护强度。进一步的,将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,可以进一步地模糊复合中间代码与待保护代码的关联性,提高代码保护强度。更进一步的,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码,可以将待保护代码转换为字节码,更进一步地模糊字节码与待保护代码的关联性,提高代码保护强度。利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。可以由此可见,采用本发明实施例,可将代码转换为字节码,增加代码安全性;此外,利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。
本申请实施例还提供一种计算机可读存储介质,该计算机可读存储介质存储有计算机程序,被处理器执行以实现图2和/或图6中各个步骤所提供的方法,具体可参见上述各个步骤所提供的实现方式,在此不再赘述。
上述计算机可读存储介质可以是前述任一实施例提供的任务处理装置的内部存储单元,例如电子设备的硬盘或内存。该计算机可读存储介质也可以是该电子设备的外部存储设备,例如该电子设备上配备的插接式硬盘,智能存储卡(smart media card,SMC),安全数字(secure digital,SD)卡,闪存卡(flash card)等。上述计算机可读存储介质还可以包括磁碟、光盘、只读存储记忆体(read-only memory,ROM)或随机存储记忆体(randomaccess memory,RAM)等。进一步地,该计算机可读存储介质还可以既包括该电子设备的内部存储单元也包括外部存储设备。该计算机可读存储介质用于存储该计算机程序以及该电子设备所需的其他程序和数据。该计算机可读存储介质还可以用于暂时地存储已经输出或者将要输出的数据。
本申请实施例中,通过将待保护代码编译为等效的中间代码并进行劣化,得到目标中间代码,并将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码。其中,可以理解的是,将待保护代码编译为等效的中间代码并进行劣化,可以模糊目标中间代码与待保护代码的关联性,提高代码保护强度。进一步的,将目标中间代码中的重复指令组合替换为复合指令,得到复合中间代码,可以进一步地模糊复合中间代码与待保护代码的关联性,提高代码保护强度。更进一步的,对复合中间代码中的指令生成动态指令操作码并存入指令表,从而可以生成复合中间代码对应的字节码,可以将待保护代码转换为字节码,更进一步地模糊字节码与待保护代码的关联性,提高代码保护强度。利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。可以由此可见,采用本发明实施例,可将代码转换为字节码,增加代码安全性;此外,利用虚拟机运行字节码,并将虚拟机与字节码打包交付,可以提高字节码的适用性。
本申请的权利要求书和说明书及附图中的术语“第一”、“第二”等是用于区别不同对象,而不是用于描述特定顺序。此外,术语“包括”和“具有”以及它们任何变形,意图在于覆盖不排他的包含。例如包含了一系列步骤或单元的过程、方法、***、产品或设备没有限定于已列出的步骤或单元,而是可选地还包括没有列出的步骤或单元,或可选地还包括对于这些过程、方法、产品或设备固有的其它步骤或单元。在本文中提及“实施例”意味着,结合实施例描述的特定特征、结构或特性可以包含在本申请的至少一个实施例中。在说明书中的各个位置展示该短语并不一定均是指相同的实施例,也不是与其它实施例互斥的独立的或备选的实施例。本领域技术人员显式地和隐式地理解的是,本文所描述的实施例可以与其它实施例相结合。在本申请说明书和所附权利要求书中使用的术语“和/或”是指相关联列出的项中的一个或多个的任何组合以及所有可能组合,并且包括这些组合。
本领域普通技术人员可以意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合来实现,为了清楚地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本申请的范围。
以上所揭露的仅为本申请较佳实施例而已,当然不能以此来限定本申请之权利范围,因此依本申请权利要求所作的等同变化,仍属本申请所涵盖的范围。
Claims (10)
1.一种代码保护方法,其特征在于,所述方法包括:
获取待保护代码的中间代码,并对所述中间代码进行劣化以得到目标中间代码;
从所述目标中间代码中确定出重复指令组合,所述重复指令组合在所述目标中间代码中出现至少两次;
确定所述目标中间代码中各重复指令组合对应的复合指令,并根据所述各重复指令组合对应的复合指令以及所述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码;
生成所述复合中间代码中各指令的动态指令操作码,并根据所述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表,其中,不同指令对应的动态指令操作码不同;
基于所述指令表和所述复合中间代码生成所述复合中间代码对应的字节码。
2.根据权利要求1所述的方法,其特征在于,所述方法还包括:
获取虚拟机描述信息,并根据所述虚拟机描述信息和所述指令表生成用于运行所述字节码的虚拟机;
其中,所述虚拟机描述信息包括寄存器数量、寄存器类型、寄存器用途、内存结构、运行栈和异常栈、运行环境的交互要求以及取指-分派-执行循环表;
基于所述字节码及所述虚拟机生成交付代码。
3.根据权利要求1或2所述的方法,其特征在于,所述获取待保护代码的中间代码,包括:
获取待保护代码,并确定所述待保护代码对应的抽象语法树;
基于所述待保护代码对应的抽象语法树编译得到所述待保护代码的中间代码。
4.根据权利要求3所述的方法,其特征在于,所述从所述目标中间代码中确定出重复指令组合,包括:
从所述目标中间代码中确定出指令组合及各指令组合在所述目标中间代码中的出现次数;
将所述各指令组合按照所述各指令组合的出现次数进行排序,并将所述出现次数大于阈值的指令组合确定为所述重复指令组合。
5.根据权利要求4所述的方法,其特征在于,所述目标中间代码中一个重复指令组合对应多个复合指令,其中,任一重复指令组合对应的复合指令的个数不超过所述任一重复指令组合在所述目标中间代码中的出现次数。
6.根据权利要求3所述的方法,其特征在于,所述根据所述各重复指令组合对应的复合指令以及所述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码,包括:
按照所述目标中间代码中各指令在所述目标中间代码中出现的顺序,确定各重复指令组合与所述目标中间代码中除重复指令组合之外的其他指令的组合顺序;
将所述目标中间代码中各重复指令组合替换为各重复指令组合对应的复合指令,并按照所述组合顺序将所述各重复指令组合对应的复合指令与所述目标中间代码中除重复指令组合之外的其他指令进行组合以生成复合中间代码。
7.根据权利要求3所述的方法,其特征在于,所述对所述中间代码进行劣化,包括:
在所述中间代码中***无实际用途的指令;或者
将所述中间代码中的整数或字符串常量转换为多条运算指令;或者
在所述中间代码中不可达的目标地址中***不完整的指令;或者
将所述中间代码中的指令进行无副作用的顺序交换。
8.一种代码保护装置,其特征在于,包括:
代码获取模块,用于获取待保护代码的中间代码,并对所述中间代码进行劣化以得到目标中间代码;
重复指令确定模块,用于从所述目标中间代码中确定出重复指令组合,所述重复指令组合在所述目标中间代码中出现至少两次;
复合代码生成模块,用于确定所述目标中间代码中各重复指令组合对应的复合指令,并根据所述各重复指令组合对应的复合指令以及所述目标中间代码中除重复指令组合之外的其他指令生成复合中间代码;
指令表生成模块,用于生成所述复合中间代码中各指令的动态指令操作码,并根据所述复合中间代码中各指令、各指令对应的动态指令操作码和操作数生成指令表,其中,不同指令对应的动态指令操作码不同;
字节码生成模块,用于基于所述指令表和所述复合中间代码生成所述复合中间代码对应的字节码。
9.一种终端设备,其特征在于,包括处理器和存储器,所述处理器和存储器相互连接;
所述存储器用于存储计算机程序,所述计算机程序包括程序指令,所述处理器被配置用于调用所述程序指令,执行如权利要求1-7中任一项所述的方法。
10.一种计算机可读存储介质,其特征在于,所述计算机可读存储介质存储有计算机程序,所述计算机程序被处理器执行以实现权利要求1-7中任一项所述的方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011049772.6A CN114329352A (zh) | 2020-09-29 | 2020-09-29 | 代码保护方法、装置、设备以及存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011049772.6A CN114329352A (zh) | 2020-09-29 | 2020-09-29 | 代码保护方法、装置、设备以及存储介质 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN114329352A true CN114329352A (zh) | 2022-04-12 |
Family
ID=81011982
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202011049772.6A Pending CN114329352A (zh) | 2020-09-29 | 2020-09-29 | 代码保护方法、装置、设备以及存储介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN114329352A (zh) |
-
2020
- 2020-09-29 CN CN202011049772.6A patent/CN114329352A/zh active Pending
Similar Documents
Publication | Publication Date | Title |
---|---|---|
EP3038004A1 (en) | Method for providing security for common intermediate language-based program | |
CN106203006A (zh) | 基于dex与so文件动态执行的Android应用加固方法 | |
EP2962193B1 (en) | Compiler based obfuscation | |
CN107908392B (zh) | 数据采集工具包定制方法、装置、终端和存储介质 | |
US20170116410A1 (en) | Software protection | |
CN106326694A (zh) | 一种基于C源代码的混淆的Android应用加固方法 | |
CN104239757A (zh) | 应用程序防止逆向的方法及装置、运行方法及终端 | |
CN108399319B (zh) | 源代码保护方法、应用服务器及计算机可读存储介质 | |
CN104680039A (zh) | 一种应用程序安装包的数据保护方法及装置 | |
CN112231702B (zh) | 应用保护方法、装置、设备及介质 | |
CN110333872B (zh) | 一种应用的处理方法、装置、设备和介质 | |
CN106897587A (zh) | 加固应用、加载加固应用的方法和装置 | |
CN112966227A (zh) | 代码加密解密方法和装置、存储介质 | |
CN116522368A (zh) | 一种物联网设备固件解密解析方法、电子设备、介质 | |
Moebius et al. | SecureMDD: a model-driven development method for secure smart card applications | |
CN113312577B (zh) | 网页资源处理方法、装置、电子设备和存储介质 | |
CN111045722A (zh) | 智能合约打包方法、装置、***、计算机设备及存储介质 | |
US20140351947A1 (en) | Method of generating execution file for mobile device, method of executing application of mobile device, device to generate application execution file, and mobile device | |
CN112882690B (zh) | 一种应用开发方法及装置 | |
KR101557455B1 (ko) | 응용 프로그램 코드 분석 장치 및 그것을 이용한 코드 분석 방법 | |
WO2024032209A1 (zh) | 区块链交易验证方法、装置、存储介质及电子设备 | |
CN114329352A (zh) | 代码保护方法、装置、设备以及存储介质 | |
CN107403103B (zh) | 文件解密方法和装置 | |
CN110046504B (zh) | 基于Linker的SO文件隐藏方法、储存介质及装置 | |
CN113449330A (zh) | 对Javascript加密文件进行传输的方法 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |