pyinstaller反编译

经过一上午的实验,梳理一下pyinstaller打包成的可执行文件如何反编译为python源代码

工具与环境

Python3.7以下版本

用uncompyle6就可以了,支持2.4-3.8的全部版本
在做实验之前,我的pyinstxtractor还是1.9版本,讲一下v1.9和v2.0的区别
2.0加了几个功能:
    支持 3.6 版本的pyinstaller
    支持 Python 3.7, 3.8
    自动修复main.pyc(入口文件)
如果没有自动修复的话,则需要从别的文件中补一点十六进制头

对于python3.7以前的版本,一般补struct文件的前十二组数字
对于python3.7以后的版本,直接从反编译出来的一堆pyc依赖文件里,拿出前十二组数字补
反编译过程->使用pyinstxtractor将可执行文件反编译为pyc文件->使用uncompyle6将pyc反编译为py文件

Python3.7.6 & Python3.7.7

按照上述流程来一遍,可能会出报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ decompyle3 conf.conf.pyc
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/xdis/load.py", line 208, in load_module_from_file_object
co = marshal.loads(bytecode)
ValueError: bad marshal data (unknown type code)
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/xdis/load.py", line 208, in load_module_from_file_object
co = marshal.loads(bytecode)
ValueError: bad marshal data (unknown type code)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/bin/decompyle3", line 11, in <module>
load_entry_point('decompyle3==3.3.2', 'console_scripts', 'decompyle3')()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/decompyle3-3.3.2-py3.7.egg/decompyle3/bin/decompile.py", line 190, in main_bin
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/decompyle3-3.3.2-py3.7.egg/decompyle3/main.py", line 302, in main
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/decompyle3-3.3.2-py3.7.egg/decompyle3/main.py", line 181, in decompile_file
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/xdis/load.py", line 116, in load_module
get_code=get_code,
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/xdis/load.py", line 222, in load_module_from_file_object
"Ill-formed bytecode file %s\n%s; %s" % (filename, kind, msg)
ImportError: Ill-formed bytecode file conf.conf.pyc
<class 'ValueError'>; bad marshal data (unknown type code)
* 根据 https://github.com/countercept/python-exe-unpacker/issues/14 修改xdis源码即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Open the file /usr/local/lib/python3.7/site-packages/xdis/load.py

Find lines:

if my_magic_int == magic_int:
bytecode = fp.read()
co = marshal.loads(bytecode)

Replace with:
if my_magic_int == magic_int:
fp.seek(12)
bytecode = fp.read()
co = marshal.loads(bytecode)

fp.seek(12) skips reading of the first 12 bytes and makes the decompiler work again.

Python3.8.1 & Python3.8.2

按照上述流程来一遍,可能会出报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ uncompyle6 conf.conf.pyc
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/xdis/load.py", line 219, in load_module_from_file_object
co = xdis.unmarshal.load_code(fp, magic_int, code_objects)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/xdis/unmarshal.py", line 108, in load_code
"expecting code indicator 'c'; got '%s'" % (fp.name, c)
TypeError: File conf.conf.pyc doesn't smell like Python bytecode:
expecting code indicator 'c'; got ''
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/xdis/load.py", line 219, in load_module_from_file_object
co = xdis.unmarshal.load_code(fp, magic_int, code_objects)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/xdis/unmarshal.py", line 108, in load_code
"expecting code indicator 'c'; got '%s'" % (fp.name, c)
TypeError: File conf.conf.pyc doesn't smell like Python bytecode:
expecting code indicator 'c'; got ''

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/bin/uncompyle6", line 11, in <module>
load_entry_point('uncompyle6==3.6.5', 'console_scripts', 'uncompyle6')()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uncompyle6-3.6.5-py3.7.egg/uncompyle6/bin/uncompile.py", line 194, in main_bin
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uncompyle6-3.6.5-py3.7.egg/uncompyle6/main.py", line 327, in main
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uncompyle6-3.6.5-py3.7.egg/uncompyle6/main.py", line 187, in decompile_file
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/xdis/load.py", line 124, in load_module
get_code=get_code,
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/xdis/load.py", line 229, in load_module_from_file_object
"Ill-formed bytecode file %s\n%s; %s" % (filename, kind, msg)
ImportError: Ill-formed bytecode file conf.conf.pyc
<class 'TypeError'>; File conf.conf.pyc doesn't smell like Python bytecode:
expecting code indicator 'c'; got ''
这个的原因是我在Win10上使用pyinstaller打包后,把main.exe复制到了Mac上,使用Mac上的Python 3.7.4 运行了pyinstxtractor,导致反编译失败 pyinstxtractor也会提示出来
1
2
3
[!] Warning: This script is running in a different Python version than the one used to build the executable.
[!] Please run this script in Python38 to prevent extraction errors during unmarshalling
[!] Skipping pyz extraction

Python3.9.x

看文档说还不支持,没试

科学的反编译方法

  • 对于每个特定的Python版本使用pyinstaller打包出的可执行文件,尽量使用同版本的Python版本运行pyinstxtractor
  • 保持decompile3或uncompyle6最新,保持xdis最新
作者

Dawnnnnnn

发布于

2020-04-17

更新于

2022-07-07

许可协议

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

评论