zoukankan      html  css  js  c++  java
  • python代码编译总结用于代码加密

      基于一个自废武功式的决定,服务需要做成标准件在客户服务器上运行,因此调研了python代码加密的相关内容。py的代码混淆没有被采用,而是采用cython编译成二进制文件进而掩盖源码的方式对代码加密。

      准备工作:

        1.安装cython ,pip install cython

        2.Linux上安装gcc ,Win需要准备vc的环境,建议安装vs2019以上,自带部分vc环境

      setup脚本,请根据需要自行添加module_list:

    from distutils.core import setup
    from Cython.Build import cythonize
    import setuptools
    from distutils.extension import Extension
    
    setup(ext_modules=cythonize(module_list = [Extension('server', ['server.py'])]))

      module_list 中的Extension,每个文件根据路径和名称确定模块名。__init__.py不建议编译,因为模块名跟文件一一对应,将模块名指定为文件夹名称编译后运行时会找不到模块。可以使用os.walk()来遍历,批量处理文件路径和模块名称。

      Setup脚本使用当前的开发环境,终端命令如下:python setup.py build_ext --inplace

      build_ext 会创建build文件夹产生编译中间产物  --inplace 最终的编译结果(如.so文件)生成在原路径下。linux下会生成so文件,win下生成的是pyd文件,都是二进制文件,原调用方式不变。

    目录结构如下图:

     完整的setup.py代码如下:

    from distutils.core import setup
    from distutils.extension import Extension
    from Cython.Build import cythonize
    import os
    
    filelist = []
    ex_list = []
    for r, d, f in os.walk('onmt'):
        if '__' in r: continue 
        if 'templates' in r: continue # 不需要加密的文件夹    
        for ff in f:
            if ff.endswith('.c') or ff.endswith('.so'):
                os.remove(os.path.join(r, ff))
                continue
            if '__' in ff: continue
            filelist.append(os.path.join(r, ff))
    
    if __name__ == '__main__':
        for f in filelist:
            if '__' in f:
                continue
                #  不可以将__init__.py文件放入待加密列表
            else:
                ex_list.append(Extension(f.split('.py')[0].replace('/', '.'), [f])) # 详见说明1
            # ex_list.append(Extension(f.split('.py')[0].replace('/', '.').split('.')[-1], [f])) # 详见说明2 
        setup(ext_modules=cythonize(ex_list, compiler_directives={'language_level': 3}
    )) for f in filelist: os.remove(f) #删除源文件来验证编译是否成功,请一定要提前备份好代码

    说明:

    1. 将源文件路径中/转换为. 编译后再次读取时模块可能会出现找不到的情况。

            以onmt/bin/ server.py文件为例,此行代码执行的编译结果中.c临时文件里的模块名字为onmt.bin.server。注意此时so文件与原py文件在同一路径下。此时在server_run中使用onmt.bin.server引用so文件时可能会出错,so文件可能被python识别为onmt.bin.server.onmt.bin.server,导致模块找不到。

             2. 模块名称与文件名一致,不再包含原文件路径。

                以onmt/bin/server.py文件为例,此行代码执行的编译结果中.c临时文件里的模块名字是server。注意此时so文件与setup.py在同一路径下,需要人为将so文件移动到原文件对应路径下。此时在server_run中使用onmt.bin.server引用so文件也有无法找到模块的可能。

             鉴于以上两种情况皆有成功和失败的情况出现,较为稳妥的办法是使用原虚拟环境进行编译,在确认编译后so文件可以使用的情况下,导出原虚拟环境与编译后so文件一起使用。

    *********************************************************************************************************************************************

    参考资料:Python 2.7 cython cythonize py 编译成 pyd 谈谈那些坑 - ibingshan - 博客园 (cnblogs.com)

  • 相关阅读:
    vCenter6.7的简单安装与使用
    大家来找茬
    Android APP分享功能实现
    为免费app嵌入Admob广告
    Google Admob广告Android全攻略1
    开始Admob广告盈利模式详细教程
    android软件中加入广告实现方法
    onWindowFocusChanged重要作用 and Activity生命周期
    WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式
    android之intent显式,显式学习
  • 原文地址:https://www.cnblogs.com/cnDqf/p/15693700.html
Copyright © 2011-2022 走看看