Python打包生成的exe文件反编译

2023年2月18日 563点热度 0人点赞

因为pyinstaller方便、兼容性相对较好,所以我们会经常见到一些用pyinstaller打包的Python程序,在这里我们了解一下如何对这些打包好的exe文件进行反编译(即反编译出.py文件),也可以通过对抗去改进我们程序的保护措施。

工具

1、pyinstxtractor.py ---- 将.exe解包
github: https://github.com/countercept/python-exe-unpacker/blob/master/pyinstxtractor.py

2、uncompyle6 ---- .pyc转.py
执行命令:pip install uncompyle6

3、Hex Editor Neo ---- 16进制编辑(用其他也可以)

官网链接:https://www.hhdsoftware.com/hex-editor

exe解包

将上面准备的 pyinstxtractor.py 和exe文件(例如叫demo.exe)放到目录下
执行命令:python pyinstxtractor.py demo.exe

这里建议使用与打包这个文件一致的Python版本。如用python3.9打包的,最好也用python3.9来执行 pyinstxtractor.py (实际上不会有大问题,不过遇到问题可以尝试,命令行中会提示我们打包时所用的Python版本)
Python打包生成的exe文件反编译

执行完成后就可以在目录下见到一个,形如 demo.exe_extracted 的文件夹,里面的目录结构大概是
Python打包生成的exe文件反编译

将.pyc文件转为.py文件

打开 PYZ-00.pyz_extracted 文件夹,这里分两种情况:

如果目录下的文件名都是 .pyc.encrypted ,说明经过了加密(pyinstaller --key),当然了我们也是可以解密的,解密方法我放在下一篇文章里详细讲述

Python打包生成的exe文件反编译

如果都是.pyc,那说明没有加密,我们可以使用 uncompyle6 将其反编译成.py文件(也就是源码)

Python打包生成的exe文件反编译

以反编译 Client.pyc 文件为例,我们在该目录下启动命令行,然后键入
执行命令:uncompyle6 -o Client.py Client.pyc

执行完成后在目录会有一个 Client.py 文件,里面就是源代码,变量和方法名都不会变,说它是源代码没有问题。

通过以下两个方法可以找到关键代码:

1、暴力破解,先按照经验剔除掉一些文件,然后每个都反编译一个个检查。

2、先找到入口方法,然后通过检查其导入的库一步步找齐所有我们需要的文件。值得注意的是,程序入口不在这个文件夹里面。

程序入口

返回到上级目录,我们可以在里面看到这种,没有后缀名的文件:
Python打包生成的exe文件反编译

其中就有我们寻找的入口方法,当然我们不用每个都反编译一次,按照经验找到你觉得最有可能的那个文件(如main、client),我们就来处理这个文件。

首先我们可以把这个文件直接重命名,给他后缀加上.pyc,然后用上面的方法(uncompyle6)对它进行反编译,如果出现以下错误:

ImportError: Unknown magic number 227 in main_2016.pyc

这是因为它缺少了一段 magic head,我们需要手动将其补齐,就可以反编译了。

打开我们的 Hex Editor Neo,或者是其他十六进制编辑器也可以。用它打开我们目录下的2个文件,struct 和我们刚刚选的文件(下文以 main_2016 来举例,并且我已经提前将它的后缀名补上.pyc)。

对比这两个文件,我们可以发现 struct 文件中e3 00 00 00前面还有一段33 0d 0d 0a 70 79 69 30,这就是我们要补充上去的内容。有的教程说补8个字节,也有说补4个的,但最好根据实际情况来处理。

Python打包生成的exe文件反编译

我们复制struct文件中多出来的这一串,粘贴到 main_2016.pyc 的开头,如果你在使用Hex Editor Neo,要先打开右上方的插入模式
Python打包生成的exe文件反编译

粘贴过去之后,它是这个样子
Python打包生成的exe文件反编译

保存,然后按照上面的方法用 uncompyle6 反编译
执行命令:uncompyle6 -o main_2016.py main_2016.pyc
就可以看到源代码了

同时我们也看到了它import了 client2016 这个库,我们回到上一步的 PYZ-00.pyz_extracted 文件夹,不出意外你会找到 client2016.pyc ,它就是关键代码之一,将它反编译之后根据import的内容再慢慢凑齐所有关键代码。

至此,本文就结束了,关于破解被加密过的 .pyc.encrypted 文件的方法我放在下一篇中详细讲述。

胖二十

这个人很懒,什么都没留下

文章评论