Python3如何反编译EXE
1. 需求分析
只⽀持通过py2exe和pyinstaller ⼯具编译⽣成的EXE⽂件
公司内部使⽤Python编写的代码,最终需要在发布前编译成windows执⾏的.EXE⽂件,所以今天在⽹上看到有相关⽜⼈,github开源写了⼀个反编译代码程序,可以将Windows EXE⽂件反编译处pyc⽂件,最终再将pyc⽂件转换成可以编译查看的py⽂件,觉得⽐较⽜,今天测试⼀下,看看效果如何,已经整个操作步骤是怎样的,做⼀个留存。
2. 环境描述
两个测试使⽤环境来完成反编译:
本地主测试是Mac,Python版本3.7.5
⼀台Windows10,主要⽤来安装16进制编译器,⽅便我们来可视化分析,⽬前这个16进制编译器010Editor 只能安装到windows系统下,所以使⽤了windows10系统,主要的作⽤是在这。
3. 步骤分解
主要的步骤分为以下⼏个步骤来完成整个反编译过程。
这⾥再确认下我们的最终需求,将EXE可执⾏⽂件反编译成最终可视、可编辑的py结尾的Python代码⽂件
有了⽬标之后,那我们整理具体的操作步骤,并进⾏细化分解
1. 获取可执⾏的EXE⽂件
2. 下载反编译程序包
3. 分析EXE可执⾏⽂件的打包⼯具(是否为py2exe和pyinstaller)
4. 执⾏解包操作
5. 执⾏反编译操作
4. 操作步骤
4.1. 获取可执⾏EXE⽂件
豆腐干豆腐干4.2. 下载反编译程序包
github下载连接地址:
# git /countercept/python-exe-unpacker.git
(venv_3.7.5) CarltonXu@CarltonXus-MacBook-Pro # cd python-exe-unpacker
(venv_3.7.5) CarltonXu@CarltonXus-MacBook-Pro # ls -tlr
total 160
-rw-r--r-- 1 CarltonXu wheel 35096 Apr 7 20:41 LICENSE
-rw-r--r-- 1 CarltonXu wheel 4110 Apr 7 20:41 README.md
-rw-r--r-- 1 CarltonXu wheel 12392 Apr 7 20:41 pyinstxtractor.py
-rw-r--r-- 1 CarltonXu wheel 15377 Apr 7 20:41 python_exe_unpack.py
-rw-r--r-- 1 CarltonXu wheel 97 Apr 7 20:
drwxr-xr-x 3 CarltonXu wheel 96 Apr 7 20:42 __pycache__
4.2.1. 安装依赖包
在代码下载后,需要安装运⾏代码所需要的依赖包,执⾏下⾯指令即可完成安装
腾达登录界面
(venv_3.7.5) CarltonXu@CarltonXus-MacBook-Pro # sudo pip3 install -
Password:
WARNING: The directory '/Urs/CarltonXu/Library/Caches/pip' or its parent directory is not owned or is not writable by the current ur. The cache has be en disabled. Check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Looking in indexes: /simple/
Requirement already satisfied: pefile==2017.9.3 in /Urs/CarltonXu/workspace/venv_3.7.5/lib/python3.7/site-packages (from - (line 1)) ( 2017.9.3)
Requirement already satisfied: unpy2exe==0.3 in /Urs/CarltonXu/workspace/venv_3.7.5/lib/python3.7/site-packages (from - (line 2)) (0. 3)
Collecting uncompyle6==2.11.5
Downloading /packages/35/a5/f0b734adba414239e144007904207b2fa2ce3ac0b4c87f4a7b0edcf74c0b/uncompyle6-2.11.5.tar.g z (1.4 MB)
|████████████████████████████████| 1.4 MB 2.2 MB/s
Requirement already satisfied: xdis==3.5.5 in /Urs/CarltonXu/workspace/venv_3.7.5/lib/python3.7/site-packages (from - (line 4)) (3.5.5) Requirement already satisfied: pycrypto==2.6.1 in /Urs/CarltonXu/workspace/venv_3.7.5/lib/python3.7/site-packages (from - (line 5)) (2 .6.1)
Requirement already satisfied: configparr==3.5.0 in /Urs/CarltonXu/workspace/venv_3.7.5/lib/python3.7/site-packages (from - (line 6 )) (3.5.0)
Requirement already satisfied: future in /Urs/CarltonXu/workspace/venv_3.7.5/lib/python3.7/site-packages (from pefile==2017.9.3->- (li ne 1)) (0.18.2)
Collecting spark-parr<1.7.0,>=1.6.1
Downloading /packages/f3/4e/a95a1ff543744bfaa33449b301fe74272556db2e852c5c3852517a5024be/spark_parr-1.6.1-py3-none-any.whl (17 kB)
Requirement already satisfied: six in /Urs/CarltonXu/workspace/venv_3.7.5/lib/python3.7/site-packages (from uncompyle6==2.11.5->- ( line 3)) (1.13.0)
Collecting argpar
Downloading /packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argpar-1.4.0-py2.py3-none-any.whl (23 kB)
Requirement already satisfied: click in /Urs/CarltonXu/workspace/venv_3.7.5/lib/python3.7/site-packages (from spark-parr<1.7.0,>=1.6.1->uncompyle6 ==2.11.5->- (line 3)) (7.0)
Using legacy 'tup.py install' for uncompyle6, since package 'wheel' is not installed.
Installing collected packages: spark-parr, argpar, uncompyle6
Attempting uninstall: spark-parr
Found existing installation: spark-parr 1.8.9
Uninstalling spark-parr-1.8.9:
Successfully uninstalled spark-parr-1.8.9
Attempting uninstall: uncompyle6
Found existing installation: uncompyle6 3.7.4
Uninstalling uncompyle6-3.7.4:
Successfully uninstalled uncompyle6-3.7.4
在沙漠中心Running tup.py install for uncompyle6 ... done
Successfully installed argpar-1.4.0 spark-parr-1.6.1 uncompyle6-2.11.5
月饼品牌
冰柜
4.3. 分析EXE⽂件属性
这⾥分析EXE⽂件属性其实就是看EXE是否为py2exe及pyinstaller⼯具打包出来的,其实这个动作在执⾏解包动作的时候会进⾏precheck 动作,如果检测失败会终⽌并提⽰,我们看下代码⾥⾯怎么做检测的。
⽂件路径:python-exe-unpacker/pyinstxtractor.py
检测的逻辑,如果是通过pyinstaller打包的,会在EXE⽂件的添加⼀个Magic number,这个Magic number就是b"MEI\014\013\012\013\016" 划算成16进制就是 “4d45490c0b0a0b0e”
# 转换成16进制
In [30]: MAGIC = b'MEI\014\013\012\013\016'
In [31]: de('hex')伤感英语网名
Out[31]: '4d45490c0b0a0b0e'
时间作文
检测公式:(⽂件⼤⼩ - PYINSTALL COOKIE SIZE)字节之后的 8个字节是否为b"MEI\014\013\012\013\016"
琅字怎么读
下⾯我们再通过010Edit⼯具打开EXE⽂件,找到最后位置的8个字节看看16进制显⽰的值
最后我们看到代码解析EXE⽂件和通过010Editor⼯具解析,EXE⽂件是属于pyinstaller进⾏打包的,那我们就可以进⾏后续操作了4.4. 执⾏解包操作
解包操作通过下载的python-exe-unpacker说明,执⾏以下指令即可。
# (venv_3.7.5) ✘ CarltonXu@CarltonXus-MacBook-Pro # python python_exe_unpack.py -i /Urs/CarltonXu/
[*] On Python 3.7
[*] Processing /Urs/CarltonXu/
[*] Pyinstaller version: 2.1+
[*] This exe is packed using pyinstaller
[*] Unpacking the binary now
[*] Python version: 37
[*] Length of package: 17411420 bytes
[*] Found 1631 files in CArchive
[*] plea standby
[*] Found 754 files in PYZ archive
[*] Successfully extracted pyinstaller exe.
最终执⾏完成,看到成功后,如果没有-o指定输出⽬录的话,默认会在当前⽬录输出/⽬录,此⽬录下便是解包后的代码,有⼀堆的⽂件和⼀个⽬录
下⾯输出的⽬录也就是源代码⽬录,但是⽬录下⾯全是pyc⽂件,我们还注意到此⽬录下还有⼀个PYZ-00.pyz_extracted⽂件夹,⾥⾯都是引⼊的依赖库,当然程序的源代码在下这个下⾯,当然也是我们需要反编译的对象。
4.4. 执⾏反编译操作
前边我们看到找到了pyc⽂件,下⾯⾃然就是对它进⾏解密了。pyc其实是python程序执⾏过程中产⽣的缓存⽂件,我们直接运⾏python 代码时也会看到。对于这种格式的反编译是⽐较简单的,⽹上有许多⼯具,甚⾄还有很多及开源代码,我们也可以使⽤最长⽤的uncompyle6⼯具来恢复py⽂件,操作试试。