本发明涉及软件逆向工程技术领域,具体的说,是一种Python字节码防逆向方法。
背景技术:
目前,在全世界范围内Python是使用最多的编程语言,Python程序运行的方式也相当独特。Python首先将后缀为.py的源码文件编译为字节码文件,存储在工程目录__pycache__下,再交由虚拟机转换为二进制码,由CPU执行。Python的字节码文件为了达到跨平台性,所以保留了源代码中的所有信息。正是因为Python字节码的这种特性,导致了字节码文件很容易被攻击者反编译出其中的源代码,给开发者带来损失。
技术实现要素:
本发明的目的在于提供一种Python字节码防逆向方法,用于解决现有技术中Python字节码容易被攻击者反编译出其中的源代码,给开发者带来损失的问题。
本发明通过下述技术方案解决上述问题:
一种Python字节码防逆向方法,包括:
步骤S100:Python解释器将采用Python语言编写的源码文件利用编译模块编译成字节码;
步骤S200:虚拟机将字节码文件包含的操作码序列中的非关键操作码用新的值进行替换,使其包含新的操作码。
操作码替换其实质为将字节码文件包含的操作码序列(co_code)中的非关键操作码用新的值进行替换,使其包含新的操作码,从而改变操作码序列的内容与结构,达到防逆转的目的。
进一步地,步骤S200具体包括:
步骤S210:参数定义
虚拟机中定义n个操作的集合为:
OP={op1,op2,opi,...,opn}
其中,opi表示虚拟机所支持的第i个操作,n为虚拟机所支持操作的总数;
与集合OP对应的操作码集合为:OP_CODE={code1,code2,codei,...,coden}
其中codei为opi的表示形式,与opi一一对应,codei∈N+且codei≤255,1≤i≤n;
步骤S220:定义替换操作码
使用集合OP_CODE′={code′1,code′2,code'i,...,code′n}来替换集合OP_CODE,使OP_CODE′至少存在一个元素使得codei≠codei,其中,code′i≤255,1≤i≤n;
步骤S230:操作码替换
对源Python程序进行编译解释运行,然后从其工程目录__pycache__下,取出Python字节码文件,打开字节码文件,使用Python自带的compile函数读取其中字节码文件对应的PyCodeObject对象中的操作码序列co_code域中的操作码值,形成操作码集合OP_CODE,对集合中的操作码值按照下述规则进行判断和按值替换,
(1)如果op_codei<90&&为非关键操作码,则操作码已经显式声明,都是简单的不带参数的操作,同一类内部可以随机改变顺序,随机使用0到64之间的数替换其操作码值,不会影响Python程序的执行;
(2)如果90≤op_codei≤131,为非关键操作码,则该带参数的操作码,和函数调用无关,内部打乱其顺序,随机使用0到128之间的数替换其操作码值,不会对源程序造成影响;
(3)如果131<op_codei≤137,为非关键操作码,则该带参数的操作码,和函数调用无关,对其两两切换顺序,随机使用0到255之间的数替换其操作码值,不会对源程序造成影响;
(4)如果137<op_codei≤147,为非关键操作码,则该带参数的操作码,两个扩展操作内部顺序可以随机打乱,并随机使用0到255之间的数替换其操作码值,不会对源程序造成影响;
PyCodeObject对象中的co_code域,已经包含新的操作码,从而改变操作码序列了的内容与结构,相当于加密了字节码文件。最后,将(.pyc)Python操作码文件发布出去,重新解释执行,即可达到无法逆向编译出源代码的目的。
本发明与现有技术相比,具有以下优点及有益效果:
(1)本发明在保证Python字节码运行结果和逻辑正确的前提下,对字节码中的非关键操作码进行替换,改变字节码文件中的操作码序列的内容和结构,使得字节码不能够被逆向反编译出源代码。
附图说明
图1为本发明的原理框图。
具体实施方式
下面结合实施例对本发明作进一步地详细说明,但本发明的实施方式不限于此。
实施例1:
结合附图1所示,一种Python字节码防逆向方法,包括:
步骤S100:Python解释器将采用Python语言编写的源码文件利用编译模块编译成字节码;
步骤S200:虚拟机将字节码文件包含的操作码序列中的非关键操作码用新的值进行替换,使其包含新的操作码。
操作码替换其实质为将字节码文件包含的操作码序列(co_code)中的非关键操作码用新的值进行替换,使其包含新的操作码,从而改变操作码序列的内容与结构,达到防逆转的目的。
进一步地,步骤S200具体包括:
步骤S210:参数定义
虚拟机中定义n个操作的集合为:
OP={op1,op2,opi,...,opn}
其中,opi表示虚拟机所支持的第i个操作,n为虚拟机所支持操作的总数;
与集合OP对应的操作码集合为:OP_CODE={code1,code2,codei,...,coden}
其中codei为opi的表示形式,与opi一一对应,codei∈N+且codei≤255,1≤i≤n;
步骤S220:定义替换操作码
使用集合OP_CODE′={code′1,code′2,code'i,...,code′n}来替换集合OP_CODE,使OP_CODE′至少存在一个元素使得code′i≠codei,其中,code′i≤255,1≤i≤n;
步骤S230:操作码替换
对源Python程序进行编译解释运行,然后从其工程目录__pycache__下,取出(.pyc)Python字节码文件,打开字节码文件,使用Python自带的compile函数读取其中字节码文件对应的PyCodeObject对象中的操作码序列co_code域中的操作码值,形成操作码集合OP_CODE,对集合中的操作码值按照下述规则进行判断是否为非关键操作码,并改变其值,由于Python支持的每个操作码(下同)只占一个字节,其值介于0~255之间,所以替换的值也应介于0~255之间:
将非关键操作码集合其中的操作码值进行判断和替换,判断规则如图1所示:
(1)如果op_codei<90&&为非关键操作码,则操作码已经显式声明,都是简单的不带参数的操作,同一类内部可以随机改变顺序,随机使用0到64之间的数替换其操作码值,不会影响Python程序的执行;
(2)如果90≤op_codei≤131,为非关键操作码,则该带参数的操作码,和函数调用无关,内部打乱其顺序,随机使用0到128之间的数替换其操作码值,不会对源程序造成影响;
(3)如果131<op_codei≤137,为非关键操作码,则该带参数的操作码,和函数调用无关,对其两两切换顺序,随机使用0到255之间的数替换其操作码值,不会对源程序造成影响;
(4)如果137<op_codei≤147,为非关键操作码,则该带参数的操作码,两个扩展操作内部顺序可以随机打乱,并随机使用0到255之间的数替换其操作码值,不会对源程序造成影响;
PyCodeObject对象中的co_code域,已经包含新的操作码,从而改变操作码序列了的内容与结构,相当于加密了字节码文件。最后,将(.pyc)Python操作码文件发布出去,重新解释执行,即可达到无法逆向编译出源代码的目的。
尽管这里参照本发明的解释性实施例对本发明进行了描述,上述实施例仅为本发明较佳的实施方式,本发明的实施方式并不受上述实施例的限制,应该理解,本领域技术人员可以设计出很多其他的修改和实施方式,这些修改和实施方式将落在本申请公开的原则范围和精神之内。