• python源码安全--将py编译成so


    1. 应用场景

    Python是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,使用其开发产品快速高效。
    python的解释特性是将py编译为独有的二进制编码pyc文件,然后对pyc中的指令进行解释执行,但是pyc的反编译却非常简单,可直接反编译为源码,当需要将产品发布到外部环境的时候,源码的保护尤为重要.

    2. 准备工作

    环境是可为linux/centos,我Windows10本地是Bash on Ubuntu on Windows,用起来很方便,命令行打bash即进入命令行
    思路是先将py转换为c代码,然后编译c为so文件
    所以要安装以下内容

    python 安装:cython

    pip install cython
    

    linux 安装:python-devel,gcc

    yum install python-devel
    yum install gcc
    

    3. 代码编译

    3.1 第一种办法:

    执行命令:cython test.py

    结果:会在同一目录下面生成test.c文件

    执行命令: gcc -c -fPIC -I /usr/include/python2.7 test.c

    结果: 在同一目录下面生成test.o文件

    执行命令: gcc -shared test.o -c test.so

    结果: 在同一目录下面生成test.so文件

    最后,生成的test.so文件就是需要的文件

    3.2 第二种办法:

    [setup.py]
    from distutils.core import setup
        from Cython.Build import cythonize
    
        setup(
            name = "test",
            ext_modules = cythonize("test.py")
        )
    
    • 执行命令: python setup.py build_ext --inplace

    第二种办法是对单独文件进行编译,下面介绍一种批量的办法:

    #-*- coding:utf-8 -*-_
    import os
    import re 
    from distutils.core import Extension, setup
     
    from Cython.Build import cythonize
    from Cython.Compiler import Options
     
     
    # __file__ 含有魔术变量的应当排除,Cython虽有个编译参数,但只能设置静态。
    exclude_so = ['__init__.py', 'run.py']
    sources = 'backend'
     
     
    extensions = []
    remove_files = []
    for source,dirnames,files in os.walk(sources):
        for dirpath, foldernames, filenames in os.walk(source):
            if 'test' in dirpath:
                break;
            for filename in filter(lambda x: re.match(r'.*[.]py$', x), filenames):
                file_path = os.path.join(dirpath, filename)
                if filename not in exclude_so:
                    extensions.append(
                            Extension(file_path[:-3].replace('/', '.'), [file_path], extra_compile_args = ["-Os", "-g0"],
                                      extra_link_args = ["-Wl,--strip-all"]))
                    remove_files.append(file_path[:-3]+'.py')
                    remove_files.append(file_path[:-3]+'.pyc')
    
    Options.docstrings = False
    compiler_directives = {'optimize.unpack_method_calls': False, 'always_allow_keywords': True}
    setup(  
            # cythonize的exclude全路径匹配,不灵活,不如在上一步排除。
            ext_modules = cythonize(extensions, exclude = None, nthreads = 20, quiet = True, build_dir = './build',
                                    language_level = 2, compiler_directives = compiler_directives))
    
    # 删除py和pyc文件
    for remove_file in remove_files:
    
        if os.path.exists(remove_file):
            os.remove(remove_file)
    
    • 执行命令: python setup.py build_ext --inplace
    • 结果:最后生成.so文件,删除中间结果。

    平时主要使用第一种方法,第二种暂未尝试

  • 相关阅读:
    N皇后问题(回溯递归思想)
    链表大合集(二) 栈和队列的实现
    我是林荫
    蒟蒻林荫小复习——莫队
    神奇脑洞题解——[HAOI2011]Problem b
    蒟蒻林荫小复习——莫比乌斯反演
    蒟蒻林荫小复习——关于有限制区间元素查询的一些解法
    蒟蒻林荫小复习——K短路的A*解法
    蒟蒻林荫小复习——2-SAT的染色法求最小答案序列
    蒟蒻林荫小复习——克鲁斯卡尔重构树
  • 原文地址:https://www.cnblogs.com/TaoLeonis/p/14644798.html
Copyright © 2020-2023  润新知