首页> 中国专利> 一种基于模块钩子的Python字节码文件保护方法

一种基于模块钩子的Python字节码文件保护方法

摘要

本发明公开了一种基于模块钩子的Python字节码文件保护方法,包括:1对Python字节码文件进行加密处理;2设计Python模块钩子及其对应的注册脚本;3在客户端的Python解释器的源码文件中添加Python模块钩子及其对应的注册脚本;4开发者端将主程序和加密后的Python字节码文件发布给客户端,并提供新的Python解释器的源码文件;5客户端对添加Python模块钩子及其对应的注册脚本后的Python解释器的源码文件进行编译,得到编译后的Python解释器;6客户端利用编译后的Python解释器执行主程序。本发明能够有效抵抗反编译,提高对Python软件程序的保护强度。

著录项

  • 公开/公告号CN106599628A

    专利类型发明专利

  • 公开/公告日2017-04-26

    原文格式PDF

  • 申请/专利权人 合肥康捷信息科技有限公司;

    申请/专利号CN201611123379.0

  • 发明设计人 顾乃杰;陈悟;王小强;王岩;

    申请日2016-12-08

  • 分类号G06F21/14(20130101);

  • 代理机构34101 安徽省合肥新安专利代理有限责任公司;

  • 代理人陆丽莉;何梅生

  • 地址 230000 安徽省合肥市望江西路和创新大道交叉口中国科学技术大学先进技术研究院综合大楼A526

  • 入库时间 2023-06-19 02:00:58

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2023-07-11

    专利权的转移 IPC(主分类):G06F21/14 专利号:ZL2016111233790 登记生效日:20230628 变更事项:专利权人 变更前权利人:合肥康捷信息科技有限公司 变更后权利人:赵志铎 变更事项:地址 变更前权利人:230000 安徽省合肥市望江西路和创新大道交叉口中国科学技术大学先进技术研究院综合大楼A526 变更后权利人:730000 甘肃省兰州市城关区段家滩路1288号2503

    专利申请权、专利权的转移

  • 2019-04-02

    授权

    授权

  • 2017-05-24

    实质审查的生效 IPC(主分类):G06F21/14 申请日:20161208

    实质审查的生效

  • 2017-04-26

    公开

    公开

说明书

技术领域

本发明涉及软件保护领域,尤其涉及一种保护Python字节码文件的方法。

背景技术

Python是一种面向对象,解释型的计算机程序设计语言,它具有开发高效,易用的特点,目前已经被大量的公司用来实现应用程序和大型网站。Python源代码不像C/C++源码被编译成二进制文件,python解释器首先将python文件编译为字节码,表示为.pyc文件,字节码文件在加载后会被解释器解释执行,字节码文件中包含了字节码序列信息,另外还存储了很多python程序运行时信息包括定义的字符串、常量等。由于字节码文件是一种可以解析的序列化文件,目前已经有很多优秀的反编译工具例uncompyle2,Decompile++可以对绝大部分字节码文件进行反编译并得到可读性很高的Python源码,攻击者可以使用这些工具反编译字节码文件获取Python程序中实现的算法和执行逻辑的关键信息,侵犯Python软件的知识产权。

因此,有效保护业务中较为关键的Python字节码文件不能被反编译,提高逆向工程的难度,是Python程序软件保护领域需要解决的一个重要问题。

发明内容

本发明为克服现有技术中存在的不足之处,提供一种基于模块钩子的Python字节码文件保护方法,以期能够有效抵抗反编译,防止反编译工具成功反编译出Python应用程序的源码,提高对Python软件程序的保护强度,保护基于Python开发的应用程序的知识产权。

本发明为达到上方发明目的,采用如下技术方案:

本发明一种基于模块钩子的Python字节码文件保护方法,是应用于开发者端和客户端之间;所述客户端利用Python解释器执行所述开发者端提供的Python应用程序的主程序;所述应用程序中包含所述主程序和若干个Python字节码文件;所述主程序在执行过程中按默认方式导入若干个Python字节码文件,从而得到所述Python应用程序的执行结果;其特点是,

所述Python字节码文件保护方法是按如下步骤进行:

步骤1、对所述开发者端提供的Python字节码文件进行加密处理,得到加密后的Python字节码文件;

步骤1.1、使用随机数发生器生成对称密钥K;

步骤1.2、根据所述对称密钥K,使用对称加密算法对所述Python字节码文件进行加密,得到密文F;

步骤1.3、在所述密文F的前端添加识别标签,得到标签密文F′;

步骤1.4、利用Shamir(t,n)门限方案将所述对称密钥K分解成n份影子信息;并将所述n份影子信息随机打乱后写入所述密文F和识别标签之间,从而得到混合密钥的密文F*作为加密后的Python字节码文件;

步骤2、设计Python模块钩子及其对应的注册脚本;

步骤2.1、根据所述Python模块钩子的协议规定,定义所述查找器为包含有查找所述混合密钥密文F*功能的find_module函数的类;定义所述加载器为包含有加载混合密钥密文F*功能的load_module函数的类;定义模块钩子的注册函数为能将实例化的查找器类插入到查找器的存储列表sys.meta_path中的函数;

由所述查找器、加载器和模块钩子的注册函数组成所述Python模块钩子;

步骤2.2、定义一个sitecustomize.py文件,在所述sitecustomize.py文件中添加导入所述Python模块钩子的语句,再添加调用所述模块钩子的注册函数的语句,从而得到所述Python模块钩子所对应的注册脚本;

步骤3、在所述客户端的Python解释器的源码文件中添加所述Python模块钩子及其对应的注册脚本:

步骤3.1、利用Cython工具将所述Python模块钩子转换为.c文件,再编译成.so共享库文件后,将所述.so共享库文件复制到Python解释器源码文件中的site-package目录下;

步骤3.2、将所述Python模块钩子所对应的注册脚本复制到所述Python解释器的源码文件中的site-package目录下,从而得到新的Python解释器的源码文件;

步骤4、所述开发者端将主程序和加密后的Python字节码文件发布给所述客户端,并将所述新的Python解释器的源码文件提供给所述客户端;

步骤5、所述客户端对添加Python模块钩子及其对应的注册脚本后的Python解释器的源码文件进行编译,得到编译后的Python解释器;

步骤6、所述客户端利用编译后的Python解释器执行所述主程序;

步骤6.1、编译后的Python解释器执行所述Python模块钩子的注册脚本,从而在所述sys.meta_path列表中插入所述实例化的查找器类,完成所述Python模块钩子的注册;

步骤6.2、在主程序在执行过程中导入若干个加密后的Python字节码文件时,触发所述sys.meta_path列表中实例化的查找器类;

步骤6.3、所述查找器利用find_module函数对加密后的Python字节码文件进行判断,若加密后的Python字节码文件为混合密钥的密文F*,则利用所述加载器的load_module函数对所述混合密钥的密文F*进行加载后,执行步骤6.4;否则,按照默认方式进行加载和导入;

步骤6.4、所述加载器的load_module函数在所述混合密钥密文F*中获取随机打乱后的n份影子信息,并在n份影子信息中随机获取t份影子信息后,利用Shamir(t,n)门限方案还原出对称密钥K;

步骤6.5、所述加载器利用所对称密钥述K在内存中对所述密文F进行解密,得到所述Python字节码文件;

步骤6.6、所述加载器在内存中提取所述Python字节码文件中的代码对象code object,从而完成所述加密后的Python字节码文件的加载和导入。

和已有的反编译技术相比,本发明的优势体现在:

1、本发明保护方法通过Python模块钩子实现了较为可靠安全的对Python字节码文件进行加密保护的方法,其技术特征在于加密端提供了密钥保护方案,保证了加密的安全可靠性,解密端不需要通过特定的解密算法和密钥进行解密,只需要使用含有设计好的Python模块钩子的解释器直接解释执行包含有加密字节码文件的Python应用程序。本方法在加密端使用对称加密算法对Python程序编译生成的字节码文件进行加密,并利用Shamir门限分存方案,将密钥分解成几份影子信息隐藏在加密的Python字节码文件中,大大提高了加密的可靠性和安全性。解密端对客户端完全透明的,用户只需要使用含有实现模块钩子及其注册脚本的Python解释器来执行包含加密后的字节码文件的Python应用程序。Python主程序导入加密模块时,会触发模块钩子定义的查找器,查找器会调用模块钩子中定义的加载器,加载器使用Shamir方案提取出密钥然后根据密钥在内存中解密字节码文件,最后提取出模块中的code object进行加载,按照这种方式执行应用程序的执行逻辑和未加密之前是完全一样的,从而解决了Python混淆器没有改变代码的结构,不可避免程序的关键信息还是会被某些反编译工具提取出来的问题,能够有效的防止反编译工具成功反编译出python字节码文件对应的源程序代码,这种方法对于Python应用程序的执行完全没有影响,在性能方面加密后的业务模块也不会造成很大的影响,能够满足公司保护Python软件的知识产权的要求。

2、本方案运用Shamir(t,n)门限方案和密钥隐藏技术来进行密钥的有效保护。使用对称加密算法对文件进行加密保护,最重要的就是对密钥进行有效的保护和隐藏,本方案在Shamir密钥分存算法使用上有所创新,传统方法是把密钥分解成多个影子信息分给多个参与者掌管,而本方案的技术特征的是将加密字节码文件使用的密钥用Shamir(t,n)门限方案分解成n份影子信息,随机打乱然后隐藏在加密后的字节码文件的前端,在解密端从加密后的字节码文件读取随机打乱后的n份影子信息,并在n份影子信息中随机获取t份影子信息后,利用Shamir(t,n)门限方案还原出对称密钥,这样加密端和解密端就能够得到完全相同的密钥,使得解密操作能够顺利在内存执行。从安全性的角度来看,通过将密钥分存隐藏的方式大大提高了逆向工程追踪密钥的难度,并且每个字节码文件生成的密钥都不相同,从而解决了传统加密方式中密钥容易被获取,从而被攻击者解密还原出原有字节码文件的信息的问题,使得加密安全性大大加强。

3、本方案提出了并实现了一种利用模块钩子机制来实现可识别加载加密字节码文件的Python解释器的方法,是用户只需要使用该解释器直接执行应用程序中的主程序,主程序在执行过程中按模块钩子中定义的查找器和加载器定义的查找和加载方法来导入应用程序中的加密后的Python字节码文件,得到Python应用程序的执行结果。本方案实现了一个包含有查找器类、加载器类和模块钩子的注册函数组成Python模块钩子,在执行主程序之前首先进行模块钩子的注册操作,将实例化的查找器类插入到查找器的存储列表sys.meta_path中的,主程序在导入加密模块时会触发此查找器,查找器中定义的find_module函数能够根据加密标签识别查找到加密后的字节码文件,然后根据加载器中的load_module函数从加密的字节码文件中获取随机打乱后的n份影子信息,并在n份影子信息中随机获取t份影子信息后,利用Shamir(t,n)门限方案还原出对称密钥并在内存中进行解密,得到Python字节码原始文件信息后提取出其中的code object完成加载和导入。与传统的在客户端进行解密的方法相比,本方案使用的模块钩子的解密操作完全是在内存中进行,从而解决了原始的字节码文件信息会以某种文件的形式出现在客户端的问题,这种方式对客户端完全透明,加密后的业务代码模块能够和非加密模块在客户端看来按照完全相同的方式进行导入,导入加密字节码的过程在内存中最终只会出现一个code object对象,内存中不会有任何源代码的信息出现,使得解密端在安全性上大大增强。

4、本方案设计设计实现了钩子模块的注册脚本并复制到Python解释器源码中,通过这种技术能够实现在不修改应用程序源代码的条件下使得解释器正常识别和导入加密模块。注册脚本具体为一个sitecustomize.py文件,它是Python中一个特殊的用于进行默认设置的脚本,Python开始运行时会先运行该脚本中的代码,在sitecustomize.py文件中添加导入Python模块钩子的语句,再添加调用模块钩子的注册函数的语句,最后将写好的注册脚本拷贝到Python解释器源码中的site-packages目录下。为了让模块钩子发挥作用需要在主程序导入其它加密模块之前先注册钩子,这种方式实现了在Python执行应用程序中的主程序时默认会先执行注册脚本完成模块钩子的注册,与传统的注册方法相比,这种方式不需要修改任何应用程序的源代码,避免了需要用户手动去在主程序添加注册模块钩子代码的语句操作,提高了解密端使用的便捷性。

5、本方案将模块钩子编译成共享库文件并复制到Python解释器源码文件中,得到新的Python解释器的源码文件提供给用户,用户使用这个特别定制的解释器来执行包含加密字节码文件的Python应用程序。本方案利用Cython工具将Python模块钩子转换为.c文件,再将.c文件编译成.so共享库,然后将.so共享库文件复制到Python解释器源码文件中的site-package目录下。由于模块钩子是由Python语言实现,它包含的算法和实现逻辑的信息是解密端核心部分,所以保证模块钩子的信息至关重要,这种处理方法将Python模块钩子编译成共享库文件,而共享库文件本身很难被反编译工具反编译,从而能够很好地保护模块钩子所包含的算法和实现逻辑的信息,用户只需要重新编译安装新的Python解释器源码文件就使用编译好的Python解释器可以直接去执行包含加密模块的Python应用程序。

附图说明

图1为本发明的原理说明图;

图2为本发明的加密流程图;

图3为本发明的Python解释器解密加载流程图。

具体实施方式

本实施例中,一种基于模块钩子的Python字节码文件保护方法,是应用于开发者端和客户端之间;客户端利用Python解释器执行开发者端提供的Python应用程序的主程序;应用程序中包含主程序和若干个Python字节码文件;主程序在执行过程中按默认方式导入若干个Python字节码文件,从而得到Python应用程序的执行结果;如图1所示,本发明的技术方案可以使用户像使用未加密字节码文件的应用程序一样运行包含加密字节码文件的应用程序,不影响应用程序正常运行,虚线展示的是整个含有加密字节码文件的Python应用程序运行的步骤,实线是使用者感觉到的Python应用程序的运行步骤。

具体的说,Python字节码文件保护方法是按如下步骤进行:

步骤1、对开发者端提供的Python字节码文件进行加密处理,得到加密后的Python字节码文件;

步骤1.1、使用随机数发生器生成对称密钥K,本方案对于不同的字节码会生成不同的对称密钥,这样的目的是使得解密端对每个Python字节码都是使用不同的密钥,各个字节码文件解密过程是独立的,提高了攻击者破解的难度;

步骤1.2、根据对称密钥K,使用对称加密算法对Python字节码文件进行加密,得到密文F;

步骤1.3、在密文F的前端添加识别标签,得到标签密文F′;

步骤1.4、利用Shamir(t,n)门限方案将对称密钥K分解成n份影子信息;并将n份影子信息随机打乱后写入密文F和识别标签之间,从而得到混合密钥的密文F*作为加密后的Python字节码文件;如图2所示,本发明利用Shamir(t,n)门限分存方案将加密密钥打散隐藏在加密的Python字节码文件中,加密后的字节码文件由以下几部分组成:开头前几字节设置加密标记,分存的密钥影子信息,加密的字节码密文信息。这样做的目的在一方面是为了保护密钥信息,使攻击者很难在字节码察觉出来被打散的密钥信息并提取出这些信息来还原密钥,另一方面可以使得在解密端能够读打散的影子信息,然后通过影子信息进行还原密钥操作,得到和加密端完全相同的密钥进行对称算法的解密。

步骤2、设计Python模块钩子及其对应的注册脚本;

步骤2.1、根据Python模块钩子的协议规定,定义查找器为包含有查找混合密钥密文F*功能的find_module函数的类;查找器根据Python模块钩子机制的要求要实现find_module方法,这个方法根据path(模块路径信息)和name(模块名称)两部分信息来实现查找加密字节码文件。

定义加载器为包含有加载混合密钥密文F*功能的load_module函数的类;当查找到一个加密模块时,会把path和name作为参数,生成一个加载器对象,这个对象定义的load_moule方法会首先分析提取出来密钥信息和初始化加密信息,然后根据这两部分信息对字节码文件进行解密,解密后需要提取出来字节码文件的代码文件code>

定义模块钩子的注册函数为能将实例化的查找器类插入到查找器的存储列表sys.meta_path中的函数;Python解释器导入字节码文件时时会遍历sys.meta_path列表,找到里面存储的查找器则调用查找器的find_module方法,直到有一个查找器实例返回一个加载器,然后调用加载器的load_module方法加载模块。

由查找器、加载器和模块钩子的注册函数组成Python模块钩子;设计Python模块钩子是解密端核心,其目的是实现在不修改应用程序源代码的条件下使得解释器正常识别和导入加密模块,它是一种扩展Python导入功能的机制,使得加密后的字节码文件能够和非加密字节码文件按照完全相同的方式进行导入。

步骤2.2、定义一个sitecustomize.py文件,在sitecustomize.py文件中添加导入Python模块钩子的语句,再添加调用模块钩子的注册函数的语句,从而得到Python模块钩子所对应的注册脚本;sitecustomize.py文件是Python中一个特殊的用于进行默认设置的脚本,Python开始运行时会先运行该脚本中的代码,通过这种方式可以实现在执行应用程序的主程序脚本时,会自动先执行这个sitecustomize.py脚本,完成模块钩子的注册。

步骤3、在客户端的Python解释器的源码文件中添加Python模块钩子及其对应的注册脚本:

步骤3.1、利用Cython工具将Python模块钩子转换为.c文件,再编译成.so共享库文件后,将.so共享库文件复制到Python解释器源码文件中的site-package目录下。Cython工具提供将Python程序转换成C语言的功能,再使用gcc编译器将C程序转换编译成.so文件。将编译成.so共享库文件可以保证其中解密过程的实现不能被轻易反编译出来。将编译后的模块钩子拷贝到Python解释器源码目录下的site-package目录下,这样能够使系统在任何地方执行脚本都能够自动找到Python模块钩子;

步骤3.2、将Python模块钩子所对应的注册脚本复制到Python解释器的源码文件中的site-package目录下,从而得到新的Python解释器的源码文件;

步骤4、开发者端将主程序和加密后的Python字节码文件发布给客户端,并将新的Python解释器的源码文件提供给客户端;

步骤5、客户端对添加Python模块钩子及其对应的注册脚本后的Python解释器的源码文件进行编译,得到编译后的Python解释器。通过这种方式用户无需手动进行解密操作,只需要编译解释器并使用这个解释器去解释执行含有加密模块的主程序;

步骤6、客户端利用编译后的Python解释器执行主程序,主程序是不需要加密的,它是启动应用程序的程序,它会导入所有的加密字节码文件;

步骤6.1、编译后的Python解释器执行Python模块钩子的注册脚本,从而在sys.meta_path列表中插入实例化的查找器类,完成Python模块钩子的注册,如图3的流程图所示,注册是模块钩子进行解密步骤的第一步,它是解密端能够进一步查找和加载的前提;

步骤6.2、在主程序在执行过程中导入若干个加密后的Python字节码文件时,触发sys.meta_path列表中实例化的查找器类;

步骤6.3、如图3所示,查找器在被触发后就会调用find_module函数进行查找。查找器利用find_module函数对加密后的Python字节码文件进行判断,若加密后的Python字节码文件为混合密钥的密文F*,则利用加载器的load_module函数对混合密钥的密文F*进行加载后,执行步骤6.4;否则,按照默认方式进行加载和导入;如

步骤6.4、如图3所示,查找成功后加载器会完成后续的解密和加载步骤。加载器的load_module函数在混合密钥密文F*中获取随机打乱后的n份影子信息,并在n份影子信息中随机获取t份影子信息后,利用Shamir(t,n)门限方案还原出对称密钥K,还原密钥是第一步也是最重要的一步,还原的密钥和解密端使用的密钥完全相同,这样可以保证解密操作成功解密;

步骤6.5、加载器利用所对称密钥述K在内存中对密文F进行解密,得到Python字节码文件;

步骤6.6、加载器在内存中提取Python字节码文件中的代码对象code object,从而完成加密后的Python字节码文件的加载和导入,如图3所示,加载器的load_module方法完成了提取密钥,在内存中解密字节码文件,解析字节码文件的代码对象code object,实现最后的加载四个环节,通过这种加载方式实现了在不修改应用程序源代码的条件下使得解释器正常加载加密字节码文件,不影响主程序的正常执行,应用程序的执行逻辑和字节码文件未加密之前是完全一样的。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号