反编译源码分析-总结python源文件编译、反编译、加密混淆

重新发布链接

本文更新地址

1. 编译

提示:编译时所有文件路径中最好不要出现英文

1.编译为pyc指令

前四个是神奇的数字。 很多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更详细的参数和命令分析,可以参考链接:

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.compile(文件,cfile=无,dfile=无,doraise=False,优化=-1,invalidation_mode=无):

import py_compile
py_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的动态链接库;

参考信息:#is-a-pyd-file-the-same-as-a-dll

Visual Studio 2019 for windows 编译环境兄弟

编译方法一

赛通

使用Cython模块根据不同的编译环境生成不同的文件。

pip intall Cython

注意:程序所在目录路径不能包含英文文本


# 脚本文件
from distutils.core import setup
from Cython.Build import cythonize
setup(
  name = 'Hello world app',
  ext_modules = cythonize("test.py"),
)

然后我们回到目录反编译源码分析,运行命令,在windows上会生成pyd文件,在linux上会生成so文件:

python setup.py build_ext --inplace

最终生成如下文件:

其中反编译源码分析,build是构建过程使用的临时文件。 test.c也是一个临时文件

注意:可能会出现“无法找到 vcvarsall.bat”错误

参考这里

附:编译所选文件夹下所有py文件脚本

import os
import re
import shutil
from distutils.core import Extension, setup
from 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

只需一行代码即可最方便地完成此操作。

pip install easycython

该模块还手动安装依赖的cython

转换步骤

将 .py 文件重命名为 .pyx

运行命令

easycython *.pyx

上面会将当前文件夹中的所有.pyx文件生成为.pyd(Linux下为.so)

html文件可以查看.py文件和.c文件的转换关系。

编译方法三

努伊特卡:用户指南

100%兼容标准python2/python3,静态编译你的python程序

我还没有时间仔细研究。 。 。

建议

同样,最好重命名pyd文件名,删除中间部分,前后部分保持不变

该文件可以通过导入测试使用

个人建议:将核心代码编译成pyd或者so文件,然后写一个简单的main.py导入并调用那些链接库文件,隐藏核心代码。

另外,cython在jupyter笔记本中使用确实令人兴奋

cython和python混合编程的使用可以参考:

二、包装

各种打包工具的对比如下(摘自《Freezing Your Code》一文)

解决方案WindowsLinuxOS XPython 3许可证单文件模式Zipfile导入Eggspkg_resources支持

bb 冻结

是的

是的

是的

麻省理工学院

是的

是的

是的

py2exe

是的

是的

麻省理工学院

是的

是的

py安装程序

是的

是的

是的

通用公共许可证

是的

是的

CX_冻结

是的

是的

是的

是的

PSF

是的

是的

py2应用程序

是的

是的

麻省理工学院

是的

是的

是的

其中pyInstaller和cx_Freeze都不错,stackoverflow上也有人建议使用cx_Freeze,比较方便。 新版本的pyInstaller似乎支持pkg_resources。

1.PyInstaller使用说明

官方维基

PyInstaller原理介绍

PyInstaller实际上是将python解析器和你自己的脚本打包成可执行文件,这与编译成真正的机器代码完全不同,所以不要指望打包成可执行文件会提高运行效率。 相反,它可能会降低运行效率,而且好处是不需要安装python以及你的脚本所依赖的库。 在Linux操作系统下,主要使用binutil工具包上的ldd和objdump命令。

PyInstaller进入你指定的脚本,首先分析该脚本所依赖的其他脚本,然后搜索、复制、收集所有相关的脚本,包括Python解析器,然后将此文件放到一个目录中,或者打包成上面的可执行文件。

如何使用

安装

pip install pyinstaller

PyInstaller 支持的常用选项

有关 PyInstaller 选项的详细信息,请参阅 pyinstaller -h。

基本用法:

生成完成后,会在该目录下看到多一个dist目录,在该目录下会看到一个test.exe文件

2.压缩成pyz指令

从Python 3.5开始,.pyz和.pyzw分别被定义为“Python Zip应用程序”和“Windows下的Python Zip应用程序”的扩展名。

添加了外部zipapp模块,方便管理,可以与Zip一起打包成可以直接执行.pyz文件的Python程序库。

Python API:(参数说明见官方文档)

zipapp.create_archive(source, target=None, interpreter=None, main=None, filter=None, compressed=False

基本用法

基本外壳用法:

$ python -m zipapp source [options]

【选项】参数选项:

3.7 版本中的新功能。

包装示例

python -m zipapp app -m "app:main"

即:指定将当前目录下app子目录下的所有Python源文件打包成一个归档包,

并通过-m选项指定使用app.py模块中的main函数作为程序入口。

如果不指定-m选项,则默认从模块中的__main__.py文件开始执行。

使用代码可以达到同样的效果:

import zipapp
zipapp.create_archive('app', 'app.pyz', main='app:main')

python -m zipapp myapp -p "/usr/bin/env python"

import zipapp
zipapp.create_archive('old_archive.pyz', 'new_archive.pyz', '/usr/bin/python3')


import zipapp
import io
temp = io.BytesIO()
zipapp.create_archive('myapp.pyz', temp, '/usr/bin/python2')
with open('myapp.pyz', 'wb') as f:
    f.write(temp.getvalue())

使用

$ python3 app.pyz

如果打包时指定了类库路径,可以这样做:

sudo chmod +x app.pyz
./app.pyz

3.反编译在线网站:

(效果好像不是很好)

反编译6

它是 decompyle、uncompyle 和 uncompyle2 的后继者。 就我个人而言,我认为效果很好。

pip install uncompyle6

 uncompyle6 models.pyc > models.py

递归反编译并保存/usr/lib/python1.5文件夹中的所有.pyc文件到/tmp

uncompyle6 -r -o /tmp /usr/lib/python1.5

反编译后的疗效可以说是比较理想的。 如果你的代码格式符合PEP8规范的要求,那么它基本上和源文件一样,但是各种注释都没有了。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 源码编译 反编译源码分析-总结python源文件编译、反编译、加密混淆 https://www.wkzy.net/game/167459.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务