从PyInstaller打包生成的EXE文件中提取Python源码

本文将详细讲解怎么使用pyi-archive_viewer和uncompyle6工具提取pyinstaller打包生成的EXE中的pyc文件,并将其正确的解码成py源码。

开始前准备

安装好PyInstaller环境,并已经将Python代码打包生成一个EXE文件;

PyInstaller安装好后,Python安装目录的Scripts文件夹下有这么一个工具: pyi-archive_viewer.exe

这个工具的作用是提取EXE文件中的PYC文件(也就是字节码),注意,这个工具只对 PyInstaller生成的EXE可执行文件有用;

运行:

pyi-archive_viewer c:\main.exe

c:\main.exe 是我已经打包好的文件;

你将会看到屏幕打印很多文件名,其中main就是我们需要的;注意,这里的main是我编译的python文件main.py,对于你们可能有所不同;

按照程序执行顺序,输入x,会提示extract name ?输入 main (main根据你编译的文件有所不同,注意看上一条信息),接着它又会问你 to filename?问你保存的文件名,我输入了 main.pyc

这时候,在 pyi-archive-viewer.exe 的当前目录下,生成了一个 main.pyc 的文件,这就是 Python的字节码文件。这个时候,我们还不能对这个字节码文件进行解码操作,原因是它并不是一个完整的文件,它缺少一个叫 IMAGE 头信息的东西,我们需要手动添加;

现在你需要一个十六进制的编辑工具。

用十六进制编辑工具打开文件后,你会在文件开头看到E3 00 00 00,记住它,等下我们需要在它前面添加 IMAGE 头。

这里来说一下PYC文件为什么会缺少 IMAGE头;那是因为PyInstaller 在编译时将它删了,但PyInstaller在编译内置库时,不会将他们的IMAGE头删除,很令人费解哈。所以我们可以提取内置库PYC文件中的IMAGE头。

在使用PyInstaller打包时,会在当前目录生成一个叫build的文件夹,进入build,找到一个叫base_library.zip 的文件夹,随便解压一个PYC文件出来,使用十六进制编辑器打开。

我选用了enum.pyc 这个文件。注意:每个人的文件内容都可能不同,这取决于Python的版本,也可能和操作系统版本有关。

还记得前面提到的E3 00 00 00么?在它之前的,就是我们需要的IMAGE头信息,每个人的长度都可能不同,在我这里,它占用了16位。

将这些信息写入main.pyc 文件E3 00 00 00的前面,如果你不懂怎么插入,我还真帮不了你,自己问度娘吧!

写入IMAGE 头后,PYC 文件才算完整,进入下一步!

解码

我们现在需要将PYC文件解码成python源代码;需要用到一个叫 uncompyle6 的工具;

使用pip3进行安装:

pip3 install uncompyle6

使用命令:

uncompyle6 -o c:\main.py main.pyc

-o 选项指定输出的源码路径;

至此整个提取与解码过程结束。

原创内容,如需转载,请注明出处;

本文地址: https://www.perfcode.com/p/720.html

分类: 计算机技术
推荐阅读:
Python将16进制HASH转换成二进制 将16进制的Hash(比如MD5、SHA1等值)转换位二进制的字符串其实很容易,只需要掌握这几个函数:
Rust module_path宏的用法和示例 在 Rust 语言中,module_path宏用于获取当前代码所在模块的路径。它返回一个&static str类型的字符串切片,表示当前代码所在的模块路径;这个路径是在编译时确定的。
VirtualBox的无缝模式真是太酷了 VirtualBox的无缝模式真的很酷,可以让虚拟机中的系统和Windows系统共享一个窗口,具体是个什么效果,请看下图:
Python暴力破解MD5加密字符串 首先,MD5是不可逆的消息摘要算法,也就是说,不能根据MD5值逆向解密出原信息;但是,MD5通常被用于对密码进行处理,而密码长度是有限的,我们只需要配对出这些组合的MD5值,就可以实现所谓的解密,这种方法也叫暴力破解;
requests中的超时(timeout)设定和捕获异常 为防止服务器不能及时响应,大部分发至外部服务器的请求都应该带着 timeout 参数。在默认情况下,除非显式指定了 timeout 值,requests 是不会自动进行超时处理的。如果没有 timeout,你的代码可能会挂起若干分钟甚至更长时间。
Python compile()函数 在 Python 中,compile() 是一个内置函数,用于将字符串或AST对象编译成字节码或代码对象。编译后的字节码或代码对象可以在多个 Python 解释器中执行,从而避免每次执行时重新编译代码。