基于操作码替换与合并的Python脚本程序防逆转方法转让专利

申请号 : CN201611122610.4

文献号 : CN106503496B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 顾乃杰王小强陈悟王岩

申请人 : 合肥康捷信息科技有限公司

摘要 :

本发明公开了一种基于操作码替换与合并的Python脚本程序防逆转方法,包括:1分析Python解释器、虚拟机中操作码的生成和执行逻辑;2更改操作码映射(opcode.h)单元;3分析编译生成的字节码文件中操作码序列中的基本块信息;4定义新的操作码;5更改窥孔优化(peephole.h)单元,对处于同一个基本块中的两个(或者两个以上的)操作码进行合并为一个新的操作码;6更改虚拟机(ceval.h)单元,以支持对新操作码的解释执行;7Python虚拟机判定操作码值,从操作码值得知是替换与合并之后的操作码,采用对应的解释过程对其进行解释执行;8Python脚本程序正常执行。

权利要求 :

1.一种基于操作码替换与合并的Python脚本程序防逆转方法,是应用于Python源码文件中,所述Python源码文件中包含opcode.h文件、peephole.c文件和ceval.c文件:所述操作码为所述opcode.h文件中的n个自然数;所述n个自然数分别对应于n个虚拟机操作;

定义所述n个虚拟机操作的集合为:OP={op1,op2,…,opi,…,opn},opi表示第i个虚拟机操作;

定义所述n个操作码的集合为CODE={code1,code2,…,codei,…,coden},codei表示第i个操作码,且第i个虚拟机操作opi对应于第i个操作码codei;所述n个操作码分为带参数的操作码和不带参数的操作码,假设所有不带参数的操作码为前a个操作码,即{code1,code2,…,codea};所有带参数的操作码为剩余n-a个操作码,即{codea+1,codea+2,…,coden},1≤i≤n;

定义操作码序列S是一串由m个操作码和k个参数组成的序列;

定义基本块为所述操作码序列S中若干个顺序执行的操作码所构成的子序列;

定义所述操作码序列S的基本块信息BS是一个长度为m的序列;所述基本块信息BS中的每个元素与所述操作码序列S中的m个操作码一一对应,所述基本块信息BS中的每个元素值为其对应的操作码在所述操作码序列S中的基本块序号;其特征是,所述Python脚本程序防逆转方法是按如下步骤进行:步骤1、替换操作;

步骤1.1、在所述前a个操作码{code1,code2,…,codea}中去除和“SLICE”相关的操作码后,将剩余的操作码的顺序进行随机交换,得到所有不带参数的操作码的新子集sub1;所述和“SLICE”相关的操作码有SLICE、STORE_SLICE、DELETE_SLICE对应的操作码值;

步骤1.2、在所述剩余n-a个带参数的操作码{codea+1,codea+2,…,coden}中去除和“FUNCTION”相关的操作码后,将剩余的操作码的顺序进行随机交换,得到所有带参数的操作码的新子集sub2;所述和“FUNCTION”相关的操作码有CALL_FUNCTION、MAKE_FUNCTION、CALL_FUNCTION_VAR、CALL_FUNCTION_KW、CALL_FUNCTION_VAR_KW对应的操作码值;

步骤1.3、由所有不带参数的操作码的新子集sub1和所有带参数的操作码的新子集sub2构成操作码替换的集合,记为CODE′={code′1,code′2,…,code′i,…,code′n},code′i表示第i个操作的替换码,所述操作码替换的集合CODE′中至少存在一个元素不属于所述n个操作码的集合CODE;

步骤1.4、在所述opcode.h文件中利用所述操作码替换的集合CODE′替换所述n个操作码的集合CODE;

步骤2、合并操作

步骤2.1、从字节码文件中提取所述操作码序列S和基本块信息BS并进行分析,得到操作码对在所述字节码文件中出现频率的降序排序;

步骤2.2、选取排序为前W个的操作码对,将前W个的操作码对中每一个操作码对(codei,codej)进行合并,形成一个新的操作码codei+j;1≤i≠j≤n;

步骤2.2.1、在所述opcode.h文件添加所述前W个的操作码对的定义和语义信息;

步骤2.2.2、在所述peephole.c文件中添加对所述前W个的操作码的合并过程;

步骤2.2.3、在所述ceval.c文件中添加对所述前W个的操作码的解释过程;

步骤3、利用gcc重新编译经上述步骤1-步骤2形成的新的Python源码文件,生成新的Python脚本运行环境new_python,作为Python脚本程序的防逆转环境。

说明书 :

基于操作码替换与合并的Python脚本程序防逆转方法

技术领域

[0001] 本发明涉及软件代码保护技术领域,具体地说是一种基于单表代替密码与Playfair密码的虚拟机操作码替换与合并的Python脚本程序防逆转方法。

背景技术

[0002] Python脚本程序是使用Python脚本语言开发的应用程序。使用python脚本语言开发的应用程序(app.py)首先要通过Python脚本编译器将其编译为具有特定结构的字节码文件(app.pyc),让后将字节码文件(app.pyc)发布给客户运行。
[0003] 使用Python脚本语言开发的应用编译生成的字节码(.pyc)文件,不是针对特定处理器和系统的二进制文件,而是针对Python虚拟机(Python Virtual Machine)的具有特定的结构和特征的文件,其保留了Python源码文件中的全部信息。
[0004] 而目前使用Python脚本语言开发的应用程序容易被攻击者反编译为源码文件,对开发者和用户造成损失,这些都字节码文件的组织格式有关。字节码文件中最重要的一个属性域就是操作码序列,其中包含了对程序执行逻辑的控制,和对程序中各个参数的执行的操作等信息,因此对操作码序列的保护显得尤为重要。

发明内容

[0005] 本发明是为了克服现有Python程序防逆转技术存在的不足之处,提供一种基于操作码替换与合并的Python脚本程序防逆转方法,以期能为字节码文件提供安全性高的保护措施,并提升Python应用程序的运行效率。
[0006] 本发明为达到上述发明目的,采用如下技术方案:
[0007] 本发明一种基于操作码替换与合并的Python脚本程序防逆转方法,是应用于Python源码文件中,所述Python源码文件中包含opcode.h文件、peephole.c文件和ceval.c文件:所述操作码为所述opcode.h文件中的n个自然数;所述n个自然数分别对应于n个虚拟机操作;
[0008] 定义所述n个虚拟机操作的集合为:OP={op1,op2,…,opi,…,opn},opi表示第i个虚拟机操作;
[0009] 定义所述n个操作码的集合为CODE={code1,code2,…,codei,…,coden},codei表示第i个操作码,且第i个虚拟机操作opi对应于第i个操作码codei;所述n个操作码分为带参数的操作码和不带参数的操作码,假设所有不带参数的操作码为前a个操作码,即{code1,code2,…,codea};所有带参数的操作码为剩余n-a个操作码,即{codea+1,codea+2,…,coden},1≤i≤n;
[0010] 定义操作码序列S是一串由m个操作码和k个参数组成的序列;
[0011] 定义基本块为所述操作码序列S中若干个顺序执行的操作码所构成的子序列;
[0012] 定义所述操作码序列S的基本块信息BS是一个长度为m的序列;所述基本块信息BS中的每个元素与所述操作码序列S中的m个操作码一一对应,所述基本块信息BS中的每个元素值为其对应的操作码在所述操作码序列S中的基本块序号;其特点是,所述Python脚本程序防逆转方法是按如下步骤进行:
[0013] 步骤1、替换操作;
[0014] 步骤1.1、在所述前a个操作码{code1,code2,…,codea}中去除和“SLICE”相关的操作码后,将剩余的操作码的顺序进行随机交换,得到所有不带参数的操作码的新子集sub1;
[0015] 步骤1.2、在所述剩余n-a个带参数的操作码{codea+1,codea+2,…,coden}中去除和“FUNCTION”相关的操作码后,将剩余的操作码的顺序进行随机交换,得到所有带参数的操作码的新子集sub2;
[0016] 步骤1.3、由所有不带参数的操作码的新子集sub1和所有带参数的操作码的新子集sub2构成操作码替换的集合,记为CODE′={code′1,code′2,…,code′i,…,code′n},code′i表示第i个操作的替换码,所述操作码替换的集合CODE′中至少存在一个元素不属于所述n个操作码的集合CODE;
[0017] 步骤1.4、在所述opcode.h文件中利用所述操作码替换的集合CODE′替换所述n个操作码的集合CODE;
[0018] 步骤2、合并操作
[0019] 步骤2.1、从字节码文件中提取所述操作码序列S和基本块信息BS并进行分析,得到操作码对在所述字节码文件中出现频率的降序排序;
[0020] 步骤2.2、选取排序为前W个的操作码对,将前W个的操作码对中每一个操作码对(codei,codej)进行合,形成一个新的操作码codei+j;1≤i≠j≤n;
[0021] 步骤2.2.1、在所述opcode.h文件添加所述前W个的操作码对的定义和语义信息;
[0022] 步骤2.2.2、在所述peephole.c文件中添加对所述前W个的操作码的合并过程;
[0023] 步骤2.2.3、在所述ceval.c文件中添加对所述前W个的操作码的解释过程;
[0024] 步骤3、利用gcc重新编译经上述步骤1-步骤2形成的新的Python源码文件,生成新的Python脚本运行环境new_python,作为Python脚本程序的防逆转环境。
[0025] 与已有技术相比,本发明有益效果体现在:
[0026] 1、一种基于单表代替密码的虚拟机操作码替换的Python脚本程序防逆转方法,在不影响Python应用的运行结果的前提下,使用新的操作码CODE′对来的操作的语义信息进行隐藏,防止他人进行反编译,为Python脚本程序提供较强的安全保障。
[0027] 2、本发明提出的Python应用程序防逆转方法,将同在一个基本块中的操作码序列进行合并,使得用一个新操作码就可以蕴含原来多个操作码的语义信息,不但对操作码序列中的语义信息进行了隐藏,而且有效减少了操作码序中操作码的个数,从而缩短了操作码序列的长度,改变了操作码序列的内容和结构,大大增加了字节码文件的安全性,并且使得Python应用程序执行效率增加了%5左右、应用大小减少了1.5%左右。

附图说明

[0028] 图1为本发明操作码替换示意图;
[0029] 图2为本发明操作码序列经操作码替换前后示意图;
[0030] 图3为本发明操作码合并过程示意图;
[0031] 图4为本发明操作码序列经操作码合并前后示意图;
[0032] 图5为本发明操作码序列经操作码替换与合并前后示意图。

具体实施方式

[0033] 下面结合附图通过具体实施例对本发明基于单表代替密码和Playfair密码的虚拟机操作码替换与合并的Python脚本程序防逆转方法做进一步的详细说明。
[0034] 本实施例中,一种基于操作码替换与合并的Python脚本程序防逆转方法,是应用于Python源码文件中,这些Python源码文件中包含操作码映射opcode.h文件、窥孔优化peephole.c文件和虚拟机ceval.c文件;操作码为opcode.h文件中定义的n个自然数;这n个自然数分别对应于ceval.c文件中涉及到的n个虚拟机操作;
[0035] 定义n个虚拟机操作的集合为:OP={op1,op2,…,opi,…,opn},opi表示第i个虚拟机操作,为LOAD_CONST、STORE_NAME等具有特定语义信息的操作;
[0036] 定义n个操作码的集合为CODE={code1,code2,…,codei,…,coden},codei表示第i个操作码,且第i个虚拟机操作opi对应于第i个操作码codei;1≤i≤n;n个操作码分为带参数的操作码和不带参数的操作码,假设所有不带参数的操作码为前a个操作码,即{code1,code2,…,codea};所有带参数的操作码为剩余n-a个操作码,即{codea+1,codea+2,…,coden},具体的说,在Python-2.7.9中,如果codei<90,则codei为不带参数的操作码,如果90≤codei≤147,则codei为带参数的操作码,1≤i≤n;
[0037] 定义第i个虚拟机操作opi到第i个操作码codei的映射关系为:map(opi)=codei;
[0038] 定义操作码序列S是一串由m个操作码和k个参数组成的一个型如下面所示的序列;
[0039]
[0040] 其中 为 的两个参数,可以为空,1≤j≤m;
[0041] 定义基本块为操作码序列S中若干个顺序执行的操作码所构成的子序列,即由JUMP_FORWARD、CONTINUE_LOOP等跳转、循环控制操作码链接的操做不属于同一基本块中;
[0042] 定义操作码序列S的基本块信息BS是一个形如下面所示的长度为m的序列;基本块信息BS中的每个元素valj与在操作码序列S中的m个操作码一一对应,基本块信息BS中的每个元素valj的值为其对应的操作码 在操作码序列S中的基本块的序号;
[0043] BS=[val1,val2,...,valj,...,valm]
[0044] 本实施例中的Python脚本程序防逆转方法是按如下步骤进行:
[0045] 步骤1、替换操作;
[0046] 步骤1.1、在前a个操作码{code1,code2,…,codea}中去除和“SLICE”相关的操作码后,具体有SLICE、STORE_SLICE、DELETE_SLICE对应的操作码值,将剩余的操作码的顺序进行随机交换,得到所有不带参数的操作码的新子集sub1;
[0047] 步骤1.2、在剩余n-a个带参数的操作码{codea+1,codea+2,…,coden}中去除和“FUNCTION”相关的操作码后,具体有CALL_FUNCTION、MAKE_FUNCTION、CALL_FUNCTION_VAR、CALL_FUNCTION_KW、CALL_FUNCTION_VAR_KW对应的操作码值,将剩余的操作码的顺序进行随机交换,得到所有带参数的操作码的新子集sub2;
[0048] 步骤1.3、由所有不带参数的操作码的新子集sub1和所有带参数的操作码的新子集sub2构成操作码替换的集合,记为CODE′={code1′,code′2,…,code′i,…,code′n},codei′表示第i个操作的替换码,操作码替换的集合CODE′中至少存在一个元素不属于n个操作码的集合CODE;
[0049] 步骤1.4、如图1所示,在opcode.h文件中利用操作码替换的集合CODE′替换操作码的集合CODE,即可完成图2所示的S到S'的转换;
[0050] 步骤2、合并操作
[0051] 步骤2.1、按图3所示的流程,从大量的字节码文件中提取操作码序列S和基本块信息BS并进行分析,寻找BS中能使valr=valr+1的r,能使vals=vals+1的s…,即寻找S中可以合并的操作码对(opr,opr+1),(ops,ops+1)…,并按这些(opr,opr+1),(ops,ops+1)…出现的频率进行降序排序,得到操作码对在字节码文件中出现频率的降序排序;
[0052] 步骤2.2、选取排序为前W个的操作码对,将前W个的操作码对中任意每一个操作码对(codei,codej)进行合,形成一个新的操作码codei+j,如图4所示,从而完成将操作码序列S到S″的转换,1≤i≠j≤n;
[0053] 步骤2.2.1、在opcode.h文件添加前W个的操作码对的定义和语义信息;
[0054] 步骤2.2.2、在peephole.c文件中添加对前W个的操作码的合并过程;
[0055] 步骤2.2.3、在ceval.c文件中添加对前W个的操作码的解释过程;
[0056] 步骤3、利用gcc重新编译经上述步骤1-步骤2形成的新的Python源码文件,生成新的Python脚本运行环境new_python,作为Python脚本程序的防逆转环境,防逆转环境new_python编译脚本文件(app.py),最终生成包含如图5中S″'所示的操作码序列的字节码文件(app.pyc),字节码文件(app.pyc)能够被new_python正确解释执行,且现有的反编译工具不能反编译出字节码文件(app.pyc)中的源代码的。