python程序 Cython加密

@[TOC]python程序加密

加密方法对比

加密手段优点缺点
发行 .pyc 文件简单方便,提高了一点源码破解门槛。平台兼容性好,.py 能在哪里运行,.pyc 就能在哪里运行解释器兼容性差,.pyc 只能在特定版本的解释器上运行。有现成的反编译工具,破解成本低
代码混淆简单方便,提高了一点源码破解门槛。兼容性好,只要源码逻辑能做到兼容,混淆代码亦能只能对单个文件混淆,无法做到多个互相有联系的源码文件的联动混淆。代码结构未发生变化,也能获取字节码
使用 py2exe能够直接打包成 exe,方便分发和执行。破解门槛比 .pyc 更高一些兼容性差,只能运行在 Windows 系统上。生成的可执行文件内的布局是明确、公开的,可以找到源码对应的 .pyc 文件,进而反编译出源码
使用 Cpython生成的二进制 .so 或 .pyd 文件难以破解。同时带来了性能提升兼容性稍差,对于不同版本的操作系统,可能需要重新编译。虽然支持大多数 Python 代码

Cpython 加密流程如下:

基础环境准备:

yum install gcc -y 
pip install Cython

使用 Cython 进行开发的步骤

构建一个测试项目test
1)编写文件hellotest.py cat …/test/hello/hellotest.py
class Hello:
  def test(self):
    return 'Hello World'

main.py 文件cat …/test/main.py

from hello.hellotest import Hello
h = Hello()
str = h.test()
print (t)
2)编写setup.py
from distutils.core import setup
from Cython.Build import cythonize


setup(name='Hello World app',
     ext_modules=cythonize('hello/hellotest.py')) #注意这里推荐使用相对路径,编译出的so文件在引用其他模块时可能会出现路径问题
3)编译为 .c 在进一步编译为 .so 或 .pyd

python setup.py build_ext --生成.so 文件
python setup.py build_ext --inplace

加密前目录结构
test/
├── hello
│   └── hellotest.py
├── main.py
└── setup.py
加密后目录结构

python setup.py build_ext

test/
├── build
│   ├── lib.linux-aarch64-3.7
│   │   └── hellotest.cpython-37m-aarch64-linux-gnu.so   
│   └── temp.linux-aarch64-3.7
│       └── hello
│           └── hellotest.o
├── hello
│   ├── hellotest.c
│   └── hellotest.py
├── main.py
└── setup.py
添加参数后加密后目录结构

python setup.py build_ext --inplace

test/
├── build
│   └── temp.linux-aarch64-3.7
│       └── hello
│           └── hellotest.o
├── hello
│   ├── hellotest.c
│   └── hellotest.py
├── hellotest.cpython-37m-aarch64-linux-gnu.so
├── main.py
└── setup.py
加密后期望结果:
test/
├── hello
│   └── hellotest.cpython-37m-aarch64-linux-gnu.so
├── main.py
└── setup.py
加密后测试结果
python main.py
Hello World

加密步骤: 加密 *.py 文件 ,so, 替换源文件,删除加密过程中生成的相关依赖
方法:蛮力法,逐个遍历
特殊要求: 排除文件,排除目录

1.获取当前目录所有py 文件相对路径
2.切分为 路径 文件
3.切换至 路径 执行加密 操作
4.删除生成的临时文件

梳理工具脚本如下:

encrypt.py

import os
import sys
from distutils.core import setup
from Cython.Build import cythonize






# 不需要编译的文件
global  exclude_list
exclude_list=['encrypt.py','main.py']
global pylist
pylist = []


# 功能,遍历搜索目录下所有 py 文件并返回列表
def search(basedir, target, exclude):
    # 主目录下的所有文件,文件夹集合
    items = os.listdir(basedir)
    for item in items:
        # 拼接
        path = os.path.join(basedir, item)
        # path 是目录,继续搜索
        if os.path.isdir(path):
            #print('[-]', path)
            search(path, target, exclude)
        # 不是目录,取最后一列值,判断是否以 target 结尾,并且为非排除文件
        elif path.split('/')[-1].endswith(target) and path.split('/')[-1] not in exclude:
            #print('[+]', path)
            pylist.append(str(path))
        else:
             pass
             # print('[!]',path)
    #print (pylist)
    return pylist


# 根据输入构建 setup.py 文件
def newSetupFile(exclude_list,filename):
    str = '''
import os
import sys
from distutils.core import setup
from Cython.Build import cythonize


exclude_list = {} # 不需要编译的py文件
if __name__ == '__main__':
    setup(ext_modules = cythonize('{}',exclude=exclude_list))


    '''.format(exclude_list,filename)
    file = open('setup.py',"w")
    file.write(str)
    file.close


# 清理setup 构建生成临时文件
def cleanSetupFile(filepath, filename):
    os.chdir(filepath)
    print('{}/{}'.format(filepath,filename))
    os.system("rm -rf build")
    os.remove(filename.split('.')[0]+'.c')
    os.remove('setup.py')
    os.remove(filename)


def main():
    # list = search('./', '.py', exclude_list)


    list = search(os.getcwd(), '.py', exclude_list)
    for filepath in list:
        os.path.split(filepath)
        filename=os.path.split(filepath)[1]
        filepath=os.path.split(filepath)[0]
        # 切换目录
        os.chdir(filepath)
        # 写入setup.py 文件
        newSetupFile(exclude_list,filename)
        os.system("python setup.py build_ext --inplace")
        cleanSetupFile(filepath, filename)


if __name__ == '__main__':
    print('\033[1;31;40m 加密py文件为{} 路径下所有py文件,如有排除请更新exclude_list 列表 \033[0m'.format(os.getcwd()))


    tag = input('请确认: \033[1;31;40m 加密后会删除源文件,请确认执行前是否备份: yes/no \033[0m')
    if tag == 'yes':
        main()
    else:
        print('\033[1;31;40m 请备份后执行加密操作 \033[0m')
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值