基于Cython和内置distutils库,实现python源码加密(非混淆模式)
起因
python本身只能做混淆,不能加密,多年的商业软件开发导致有某种“洁癖”:欲将py编译打包
尝试
- pyinstaller原理是freeze打包pyc文件,利用工具可完美逆行出源码
- 各种混淆脚本,版本兼容很差,配置繁琐
- cython 常规使用只能编译单个特殊模块
解决
反复尝试摸索后,还是利用了cython和distutils库,自动化识别并转换py到c源码并编译,放出源码供大家参考
"""
利用cython和distutils编译py到pyd[so] 注意安装cython及本地平台对应编译器
http://flywuya.cnblogs.com/
"""
import os
import shutil
from distutils.core import setup
from distutils.command.build_ext import build_ext
from Cython.Build import cythonize
BUILD_CONFIG = {
'SupportExt': ['.py', '.pyx'],
'CopyOnlyFile': ['__main__.py', '__init__.py'],
'CopyOnlyDir': ['assets'],
'IgnoreDir': ['dist', 'build', '__pycache__'],
}
def copy_tree(src, dst):
""" not like shutil.copytree, dst can be exists """
assert os.path.exists(src)
assert os.path.isdir(src)
os.makedirs(dst, exist_ok=True)
for fn in os.listdir(src):
s = os.path.join(src, fn)
t = os.path.join(dst, fn)
if os.path.isfile(s):
shutil.copy2(s, t)
elif os.path.isdir(s):
copy_tree(s, t)
def build_module(source_file, dst_dir, tmp_dir):
""" cythonize && build ext """
assert os.path.isfile(source_file)
assert not os.path.isabs(source_file)
assert os.path.exists(dst_dir)
os.makedirs(tmp_dir, exist_ok=True)
build_cython = os.path.join(tmp_dir, 'build.cython')
build_temp = os.path.join(tmp_dir, 'build.temp')
build_lib = dst_dir
ext_modules = cythonize(
source_file,
build_dir=build_cython,
language_level=3,
)
class build_here(build_ext):
def initialize_options(self):
super().initialize_options()
self.build_temp = build_temp
self.build_lib = build_lib
setup(
ext_modules=ext_modules,
script_args=['build_ext'],
cmdclass=dict(build_ext=build_here)
)
def build_modules(source_dir, dst_dir, tmp_dir):
""" scan && build modules in source_dir """
assert os.path.exists(source_dir)
assert not os.path.isabs(source_dir)
assert not os.path.isabs(dst_dir)
os.makedirs(dst_dir, exist_ok=True)
for root, dirs, files in os.walk(source_dir):
rel_pth = root[len(source_dir)+1:]
for ignore in BUILD_CONFIG['IgnoreDir']:
if ignore in dirs:
dirs.remove(ignore)
for dn in dirs:
if dn in BUILD_CONFIG['CopyOnlyDir']:
copy_tree(
os.path.join(root, dn),
os.path.join(dst_dir, rel_pth, dn)
)
dirs.remove(dn)
for fn in files:
_, ext = os.path.splitext(fn)
os.makedirs(
os.path.join(dst_dir, rel_pth),
exist_ok=True
)
if fn in BUILD_CONFIG['CopyOnlyFile']:
shutil.copy2(
os.path.join(root, fn),
os.path.join(dst_dir, rel_pth, fn)
)
elif ext.lower() in BUILD_CONFIG['SupportExt']:
build_module(
os.path.join(root, fn),
dst_dir,
os.path.join(tmp_dir, rel_pth),
)
else:
shutil.copy2(
os.path.join(root, fn),
os.path.join(dst_dir, rel_pth, fn)
)
if __name__ == "__main__":
# 这里填写要编译的目录
tasks = [
'app',
]
others = [
'requirements.txt',
'packages',
]
BUILD_CONFIG['CopyOnlyFile'].extend(['settings.py'])
for task in tasks:
build_modules(
task,
os.path.join('dist', task),
os.path.join('build', task),
)
for other in others:
if os.path.isfile(other):
bn = os.path.basename(other)
shutil.copy2(other, os.path.join('dist', bn))
elif os.path.isdir(other):
bn = os.path.basename(other)
copy_tree(other, os.path.join('dist', bn))
基于Cython和内置distutils库,实现python源码加密(非混淆模式)的更多相关文章
- 用内置的库turtle来画一朵花,python3
题目:用内置的库turtle来画一朵花 看了群主最后成像的图片,应该是循环了36次画方框,每次有10度的偏移. 当然不能提前看答案,自己试着写代码. 之前有用过海龟画图来画过五角星.奥运五环.围棋盘等 ...
- 查看python内部模块命令,内置函数,查看python已经安装的模块命令
查看python内部模块命令,内置函数,查看python已经安装的模块命令 可以用dir(modules) 或者用 pip list或者用 help('modules') 或者用 python -m ...
- 基于Zlib算法的流压缩、字符串压缩源码
原文:基于Zlib算法的流压缩.字符串压缩源码 Zlib.net官方源码demo中提供了压缩文件的源码算法.处于项目研发的需要,我需要对内存流进行压缩,由于zlib.net并无相关文字帮助只能自己看源 ...
- 基于Docker的TensorFlow机器学习框架搭建和实例源码解读
概述:基于Docker的TensorFlow机器学习框架搭建和实例源码解读,TensorFlow作为最火热的机器学习框架之一,Docker是的容器,可以很好的结合起来,为机器学习或者科研人员提供便捷的 ...
- 基于Ubuntu 14.04 LTS编译Android4.4.2源码
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/gobitan/article/details/24367439 基于Ubuntu 14.04 LTS ...
- Python源码剖析——01内建对象
<Python源码剖析>笔记 第一章:对象初识 对象是Python中的核心概念,面向对象中的"类"和"对象"在Python中的概念都为对象,具体分为 ...
- python 内置标准库socketserver模块的思考
socketserver模块简化了编写网络服务器的任务, 在很大程度上封装了一些操作, 你可以看成是事件驱动型的设计, 这很不错.它定义了两个最基本的类--服务器类 BaseServer, 请求处理类 ...
- 2.3 spring5源码系列---内置的后置处理器PostProcess加载源码
本文涉及主题 1. BeanFactoryPostProcessor调用过程源码剖析 2. 配置类的解析过程源码 3. 配置类@Configuration加与不加的区别 4. 重复beanName的覆 ...
- 基于vue实现一个简单的MVVM框架(源码分析)
不知不觉接触前端的时间已经过去半年了,越来越发觉对知识的学习不应该只停留在会用的层面,这在我学jQuery的一段时间后便有这样的体会. 虽然jQuery只是一个JS的代码库,只要会一些JS的基本操作学 ...
随机推荐
- 如何在centos环境下搭建java环境
在CentOS上安装Java环境:[1]使用yum安装java 现阶段做企业级项目开发一般都采用Java语言.开发的项目需要放在服务器上运行测试,若以CentOS系统为服务器系统,首先要解决就是Cen ...
- UVa 10118 Free Candies (记忆化搜索+哈希)
题意:有4堆糖果,每堆有n(最多40)个,有一个篮子,最多装5个糖果,我们每次只能从某一堆糖果里拿出一个糖果,如果篮子里有两个相同的糖果, 那么就可以把这两个(一对)糖果放进自己的口袋里,问最多能拿走 ...
- pyhon 去除列表中重复元素
Python set() 函数 描述 set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集.差集.并集等. 语法 set 语法: class set([iterabl ...
- 使用electron-packager electron-builder electron-updater 打包vue项目,支持在线更新
1.如何用electron-packager electron-builder打包vue项目,打包成桌面程序. 步骤一. 执行npm run build 打包你的vue项目. 打包成功后,生成dist ...
- swift 学习之 UIAlertViewController
// // PushViewController.swift // tab // // Created by su on 15/12/7. // Copyright © 2015年 tian. ...
- jmeter 调用jar包 本地加密
1.因为加密接口是有我们自己加密方式,所有加密包由开发提供,获得加密包后方式jmeter目录/lib/ext文件夹中 2.选择引入加密包 3.添加BeanShell Sampler和Debug Sam ...
- Default style sheet for HTML 4
http://www.w3.org/TR/CSS21/sample.html html, address, blockquote, body, dd, div, dl, dt, fieldset, f ...
- .NET中Debug模式与Release模式差别
Debug里的PDB是full,保存着调试和项目状态信息.有断言.堆栈检查等代码.Release 里的PDB是pdb-only,基本上:出什么错了+错误在哪行. 因为很多人把PDB理解成:调试文件.P ...
- expect+scp传输文件发现文件丢失
背景 使用expect+scp去跨机器传输文件,(别问我为什么,因为公司的测试机器都是通过堡垒机的,无法绕开堡垒机,只能暂时使用这个方法了),结果发现从A传递到B的tar.gz文件大小不一致了的,当时 ...
- Devexpress WPF教程
[视频专辑]酷炫界面开发神器DevExpress WPF视频教程(36集全) http://www.devexpresscn.com/post/620.html