大家好,我是小五🧐
今年年初的时候,我写了一篇:,相信解决了不少小伙伴的Pyinstaller打包问题。
不过我最近遇到了一个问题,自己打包好的exe文件还在,但是Python源文件不知什么时候被误删了。现在想改动一下功能,重写Python脚本工程量也太大了,怎么办?
请看下文:
作者简介
小小明,数据、Python爱好者。个人博客地址:https://blog.csdn.net/as
今天我将教大家如何反编译exe文件,即将自己或别人写好的exe,还原成Python源码。
以最近写Python一键自动整理归类文件为例进行演示,运行所需的代码和文件都会在文末提供给大家。
打包成单文件所使用的命令为:
打包成文件夹所使用的命令为:
不管是哪种打包方式都会留下一个exe文件。
首先我们需要从exe文件中抽取出其中的pyc文件:
抽取pyinstaller打包的exe中的pyc文件,提取pyc文件有两种方法:
脚本提取pyc文件
pyinstxtractor.py 脚本可以在github项目 python-exe-unpacker 中下载,地址:
https://github.com/countercept/Python-exe-unpacker
下载该项目后把其中的脚本文件复制到与exe同级的目录。
然后进入exe所在目录的cmd执行:
执行后便得到exe文件名加上后缀的文件夹:
对两种打包方式产生的exe提取出的文件结构稍有区别:
工具提取pyc文件
pyi-archive_viewer是PyInstaller自己提供的工具,它可以直接提取打包结果exe中的pyc文件。
详细介绍可参考官方文档:ttps://pyinstaller.readthedocs.io/en/stable/advanced-topics.html#using-pyi-archive-viewer
执行即可查看 exe 内部的文件结构:
操作命令:
然后可以提取出指定需要提取的文件:
要提取其他被导入的pyc文件,则需要先打开:
很显然,使用PyInstaller的pyi-archive_viewer 工具操作起来比较麻烦,一次只能提取一个文件,遇到子模块还需执行一次打开操作。
所以后面我也只使用pyinstxtractor.py 脚本来提取pyc文件。
有很多对pyc文件进行解密的网站,例如:
不过我们直接使用 库进行解码,使用pip可以直接安装:
uncompyle6可以反编译.pyc后缀结尾的文件,两种命令形式:
以前面编码过程中生成的缓存为例进行演示:
执行后便直接将.pyc文件反编译成Python脚本了:
从编译结果看注释也被保留了下来:
对于不是pyc后缀结尾的文件,使用uncompyle6反编译时会报出 must point to a Python source that can be compiled, or Python bytecode (.pyc, .pyo) 的错误。
所以我们需要先对提取出的内容人工修改后缀:
运行入口pyc文件反编译
对于从pyinstaller提取出来的pyc文件并不能直接反编译,入口运行类共16字节的 和 被去掉了。
如果直接进行反编译,例如执行 uncompyle6 auto_organize_gui.exe_extracted/auto_organize_gui.pyc
会报出如下错误:ImportError: Unknown magic number 227 in auto_organize_gui.exe_extractedauto_organize_gui.pyc
使用支持16进制编辑的文本编辑器查看一探究竟,这里我使用:
分别打开正常情况下编译出的pyc和从pyinstaller提取出来的pyc文件进行对比:
可以看到前16个字节都被去掉了,其中前四个字节是,这四个字节会随着系统和Python版本发生变化,必须一致。后四个字节包括时间戳和一些其他的信息,都可以随意填写。
我们先通过向pyinstaller提取的文件添加头信息:
选择开头插入16个字节后,只需要替换前4个字节为当前环境下的magic:
然后执行:
执行后可以看到文件已经顺利的被反编译:
依赖性pyc文件反编译
考虑再反编译导入的其他依赖文件:
先用打开查看一下:
可以看到对于非入口运行的pyc文件是从12字节开始缺4个字节。
这里我们选择第13个字节再插入四个字节即可:
然后再执行:
然后成功的反编译出依赖的文件:
代码与原文件几乎完全一致:
如果一个exe需要被反编译的Python脚本只有3个以内的文件,我们都完全可以人工来操作。
但是假如一个exe涉及几十个甚至上百个Python脚本需要反编译的时候,人工操作未免工作量过于巨大,我们考虑将以上过程用Python实现,从而达到批量反编译的效果。
提取exe中的pyc
预处理pyc文件修护校验头
读取从pyz目录抽取的pyc文件的前4个字节作基准:
校准入口类:
校准子类:
开始反编译
完整代码下载见文末。
这样我们只需将Python脚本、exe文件和脚本文件 放置到同一文件夹下,运行我们的Python脚本。即可反编译exe。
可以看到已经完美的反编译出exe其中的Python脚本:
好了,相信大家已经明白了反编译的原理。那么既然是攻防,如何防止自己打包的exe被反编译呢?
只需在打包命令后面加上命令即可,例如文章开头的命令可以更换为:
是你用来加密的密钥,可以随意更换。
该加密参数依赖tinyaes,可以通过以下命令安装:
打包后再次执行反编译:
结果只有入口脚本反编译成功,被依赖的脚本均被加密,无法直接被反编译:
可以看到抽取的中间结果变成了格式,无法直接被反编译:
可以看到,常规手段就无法直接反编译了。
这个时候还想反编译就需要底层的逆向分析研究了,或者pyinstaller的源码完整研究一遍,了解其加密处理的机制,看看有没有激活成功教程的可能。
下载地址
如果大家想测试exe反编译,手头又没有合适的文件,可以在「凹凸数据」后台回复“反编译”即可获得以下文件:
如果今天的文章有帮助到大家,记得给个一键三连啦~~~
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/2446.html