总结python源文件编译、反编译、加密混淆
本文更新地址
一、编译
- 1. 编译为 pyc
- 2. 编译为 pyo 或者 opt-n.pyc 文件
- 3. 编译成 pyd 或 so 链接库
- 编译方法一
- 编译方法二
- 编译方法三
- 使用建议
二、打包
- 1. PyInstaller
- 2. 压缩成 pyz
三、反编译
- 1. pyc 、pyo 文件反编译
- 在线网站:https://tool.lu/pyc/
- uncompyle6
- 其他 Python 反编译工具 uncompyle2, decompyle2, DePython, unpyc, uncompyle, pycdc
- 2. exe 反编译
- 1. pyc 、pyo 文件反编译
四、混淆加密
- 1. 代码混淆
- 1.1 在线网站:http://pyob.oxyry.com/
- 1.2 Intensio-Obfuscator
- 1.3 pyminifier
- 1.4 Opy
- 1.5 pyobfuscate
- 2.加密
- 定制 python 解释器
- 修改 opcode
- PyArmor
- 1. 代码混淆
一、编译
提示:编译过程中所有文件路径最好不要出现中文
1. 编译为 pyc
说明
pyc 是由 py 文件经过编译后生成的二进制字节码(byte code)文件;
pyc 文件的加载速度比 py 文件快;
pyc 文件是一种跨平台的字节码,由 python 的虚拟机来执行;
pyc 文件的内容跟 python 版本相关,不同的 python 版本编译生成不同的 pyc 文件,只能在相同版本环境下执行;
.pyc 文件结构介绍参考:https://www.iteye.com/topic/382423、https://yq.aliyun.com/articles/599833#
.pyc 文件的前 8 个字节含义:- 四个字节的 magic number - 四个字节的 timestamp
头四个是 magic number 很多 pyc 都在这个上面做文章,这修改成不合法的,然后你反编译就是败了,你可以找你自己编译成功的 pyc 头直接覆盖掉他的头 8 个字节就可以了, timestamp 是文件的修改时间,主要是当源码有改变的时候 python 就可以重新生成 pyc 文件.
编译方法
利用compileall
和py_compile
来预编译 python 代码:
这两个从某种意义上是互通的,python 预装了这两个东西,
python -m compileall test.py #把单个.py文件编译为字节码文件
python -m compileall /path/src/ #批量生成字节码文件,/path/src/是包含.py文件名的路径python -m py_compile test.py #把单个.py文件编译为字节码文件
python -m py_compile /path/src/ #批量生成字节码文件,仅将/path/src/的下一层.py文件编译,不会递归执行
上面的 py_compile 针对文件夹是会有一些问题,但理论上这种语法应该是可以的。
可根据项目需要写成编译脚本:
- compileall
对于 compileall 更详细的参数以及命令解析可以参考的链接:https://docs.python.org/3/library/compileall.html
import compileall# compileall.compile_file编译单个文件;
compileall.compile_file('main.py')#compile_dir 函数编译文件夹下的py文件
compileall.compile_dir('Lib/', force=True)# 使用多处理器编译
compileall.compile_dir('Lib/', workers=2)# Perform same compilation, excluding files in .svn directories.
import re
compileall.compile_dir('Lib/', rx=re.compile(r'[/\\][.]svn'), force=True)# pathlib.Path objects can also be used.
import pathlib
compileall.compile_dir(pathlib.Path('Lib/'), force=True)
- py_compile
函数原型:
py_compile.compile(file, cfile=None, dfile=None, doraise=False, optimize=-1, invalidation_mode=None):
- file: 表示需要编译的 py 文件的路径
- cfile: 表示编译后的 pyc 文件名称和路径,默认为直接在 file 文件名后加 c 或者 o,o 表示优化的字节码
- dfile: 错误消息保存的路径,默认为源文件名
- doraise: 如果为
True
,编译发生错误时则会引发一个 PyCompileError; 如果为False
, 编译文件出错时,则会有输出一个错误信息,而不会引发异常 - optimize: 编译优化等级,可取-1, 0, 1, 2. 值-1 表示使用当前解释器的优化等级,就像命令行参数-O 的个数。
import py_compilepy_compile.compile(r'Downloads/md5.py')
'Downloads/__pycache__/md5.cpython-37.pyc'
使用
与 py 文件一样使用,最好将文件名中间类似 cpython-36 的部分去掉,否则可能出现导包错误 ModuleNotFoundError:
2. 编译为 pyo 或者 opt-n.pyc 文件
说明
源代码文件经过优化编译后生成的文件,无法用文本编辑器进行编辑
Python3.5 之后,不再使用.pyo 文件名,而是使用类似“xxx.opt-n.pyc 的文件名;
编译成 pyc 和 pyo 本质上和 py 没有太大区别,只是对于这个模块的加载速度提高了,并没有提高代码的执行速度。
编译方法
pyo 文件其实很简单,就是上面 pyc 命令的改版:
python -O -m py_compile file.py
python -O -m py_compile /path/src/
python -O -m compileall file.py
python -O -m compileall /path/src/或者
python -OO -m py_compile file.py
python -OO -m py_compile /path/src/
python -OO -m compileall file.py
python -OO -m compileall /path/src/
运行
与 py 文件一样运行、导入
python sample.cpython-36.pyo
from sample import *
3. 编译成 pyd 或 so 链接库
说明
pyd 格式是 D 语言(C/C++综合进化版本)生成的二进制文件,是 python 的动态链接库;
参考信息:https://docs.python.org/3/faq/windows.html?highlight=pyd#is-a-pyd-file-the-same-as-a-dll
windows 编译环境鄙人用的 Visual Studio 2019
编译方法一
Cython
利用 Cython 模块,根据编译环境不同生成不同文件。
- 前提安装 Cython
pip intall Cython
- 编辑一个 setup.py 文件,写入以下代码并运行
注意:程序所在的目录路径不能包含中文文字
# 脚本文件
from distutils.core import setup
from Cython.Build import cythonizesetup(name = 'Hello world app',ext_modules = cythonize("test.py"),
)
然后我们就退回到目录下运行命令,就会在 windows 上生成 pyd 文件,或者 linux 上生成 so 文件:
python setup.py build_ext --inplace
- build_ext 是指明 python 生成 C/C++的扩展模块(build C/C++ extensions
- –inplace 的意思是在当前文件目录下生成.pyd 文件,不加这一句就会在 build 文件夹中生成
最终生成如下文件:
其中,build 是生成过程使用到的临时文件。test.c 也是临时文件
注:可能会出现“Unable to find vcvarsall.bat”错误
参考这里
- 修改 Python 安装目录的文件设置
- How to deal with the pain of “unable to find vcvarsall.bat”
附:编译选定文件夹下所有 py 文件脚本
import os
import re
import shutil
from distutils.core import Extension, setupfrom Cython.Build import cythonize
from Cython.Compiler import Options# __file__ 含有魔术变量的应当排除,Cython虽有个编译参数,但只能设置静态。
exclude_so = ['__init__.py']
sources = ['.'] # 选定文件夹extensions = []
for source in sources:# 递归遍历文件夹(深度优先)for dirpath, foldernames, filenames in os.walk(source):# 删除pyc文件if '__pycache__' in foldernames:foldernames.remove('__pycache__')shutil.rmtree(os.path.join(dirpath, '__pycache__'))for filename in filter(lambda x: re.match(r'.*[.]py$', x), filenames):file_path = os.path.join(dirpath, filename)print(file_path, end='\t')if filename not in exclude_so:temp = re.sub(r'[/\\]', '.', file_path[:-3]).strip('.')print(temp)extensions.append(Extension(temp, [file_path], extra_compile_args=["-Os", "-g0"],extra_link_args=["-Wl,--strip-all"]))
Options.docstrings = False
compiler_directives = {'optimize.unpack_method_calls': False}
setup(# cythonize的exclude全路径匹配,不灵活,不如在上一步排除。# language_level是python的主版本号ext_modules=cythonize(extensions, exclude=None, nthreads=20, quiet=True, build_dir='./build',language_level=3, compiler_directives=compiler_directives))
编译方法二
安装 easycython
这个最方便只要一行代码就可以搞定。
https://github.com/cjrh/easycython
pip install easycython
这个模块也会自动安装依赖的 cython
转换步骤
将 .py 文件重命名为.pyx
运行命令
easycython *.pyx
上面会将当前文件夹下所有的.pyx 文件生成为.pyd (Linux 下是.so)
html 文件可以查看 .py 文件与 .c 文件的转换对照关系。
编译方法三
Nuitka:用户手册
100%兼容标准 python2/python3,静态编译你的 python 程序
鄙人还没来得及仔细研究。。。
使用建议
同样的,最好重命名 pyd 文件名,将中间的部分删除,前后部分不要动
可以通过import test
使用该文件
个人建议:将核心的代码编译为 pyd 或者 so 文件,然后再写一个简单的 main.py 去 import 调用这些链接库文件,达到隐藏核心代码的作用。
另外,cython 在 jupyter notebook 里使用真的很刺激
总结python源文件编译、反编译、加密混淆相关推荐
- python编译反编译,你不知道的心机与陷阱
谈到python的文件后缀,说眼花缭乱也不为过.来看看你遇到过哪些类型! .py 如果这个不知道,呵呵-那请出门左拐,你还是充钱那个少年,没有一丝丝改变.接着打游戏去吧- .pyc 这个后缀应该算是除 ...
- python代码编译反编译
一.编译 自带模块py_compile 可以把.py代码编译成pyc文件 py文件中导入使用 import py_compilepy_compile.compile(r'code01.py') 在终端 ...
- 方便无阻且全面的python程序exe反编译,可以不使用十六进制编辑器完成的常规反编操作
Python源代码能够被pyinstaller打包为脱离Python环境的exe可执行文件,然而,在有些特殊情况下,比如剖析病毒,数据恢复,需要反过来把可执行文件反编译为Python源代码,这个过程是 ...
- andriod的apk文件相关的编译反编译工具
1.smali-1.2.6.jar 用途:.smali文件 转成 classes.dex文件 说明:.smali文件,类似于.class文件,可以用普通文本编辑器查看和修改. 用法举例:命令行:jav ...
- jar包修改编译反编译操作
1.首先下载一个反编译工具JD-GUI(自己用的是这款) 2.获取到你要改的jar包文件 3.先把jar包直接解压暂时放在一个目录里(本人准备修改这个文件) 4.再把jar包拖进JD-GUI进行解码然 ...
- linux deb反编译,反编译vivoCamera
引言 最近要开发一个相机小视频的功能.可以直接分享到WeChat上,和vivo相机的小视频模式类似.网上so了很多关于微信小视频开放接口,无奈没有可用的资料,就想反编译vivoCamera,看看它关于 ...
- android 编译 反编译工具-apk改之理
http://pan.baidu.com/s/1eQrcza6
- python pyc文件解析_如何反编译pyc文件
如何将.pyc和.pyo文件反编译为.py文件 pyc大约在python2刚出的时候有.后来就很少找得到了.有一次,不小心把.py删除了,通过pyc还把代码还原了. 你搜索uncompyle2, de ...
- Java后端知识之代码混淆-避免反编译工具获取原码
java, 代码混淆, 编译, 反编译 本文是向大家介绍java后端小知识,它能够实现编译后的class代码加密,能够避免使用反编译工具获取源码. 本文介绍java代码编译成class后,怎么避免用反 ...
- 迷你播放器--第一阶段(7)--安全攻防第一战--对抗反编译,代码混淆和对抗动态调试
迷你播放器--第一阶段(7) 安全攻防第一战--对抗反编译,代码混淆和对抗动态调试; 本文章为CSDN作者原创,转载请保留出处:http://blog.csdn.net/lrs0304/article ...
最新文章
- Flex DataGrid可编辑对象实现Enter跳转
- Typeface 字体样式
- 依赖注入的细节_value子标签_特殊字符的注入
- pythonresponse对象的属性_Scrapy中response属性以及内容提取
- hbase linux 命令,在linux下操作hbase
- solr集群搭建,zookeeper集群管理
- c# 基础连接已经关闭: 连接被意外关闭,错误的解决
- python中不可以用来表示字符串_在Python中,不可以用来表示字符串的符号是____________。...
- react sql格式化_为SQL Server数据库损坏做准备; 初步React与分析
- F - Prime Path
- 士林变频器面板如何调速度_必读干货丨西威变频器DRIVE OVERLOAD故障处理
- 学习成果区块链问世,中科宇创为人才能力认证提供权威账本
- 计算机硬盘格式化三个步骤,格式化计算机的硬盘驱动器步骤
- 80端口被屏蔽解决方法
- 计算机中桌面中不显示U盘图标,电脑桌面右下角不能显示u盘图标解决方法
- 云计算第四次作业—web网站的搭建
- app开发入门篇-近期uniapp ; 封装request
- 计算机往届生考研失败找工作,考研二战失败如何找工作 考研往届生找工作的方法...
- Unicode双向算法详解(bidi算法)(一)
- div完成田字格布局
热门文章
- MongoDB:count 结果不准确的原因与解决方法
- 马托石头问题-java(大马中马小马托石头)
- 时域特征提取_时域分析——无量纲特征值含义一网打尽
- 京东裁员的背后,只会“点点点”的你,真的能度过这一次疫情带来的裁员潮吗?
- Python爬虫入门(爬取豆瓣电影信息小结)
- WordPress 主题模板QUX9.1.4开心版无授权限制 DUX二开增强主题
- 圣墟 第一百二十九章 异类直播
- matlab cbfreeze,Matlab:如何在同一图中为不同的表面指定不同的色图/色块
- “凡尔赛文学”是奢侈品电商的“取款机”?
- 梦幻手游服务器维护摆摊公示时间,梦幻西游手游摆摊攻略 卖家关注公示期最重要...