Python exe 文件反编译为 Python 脚本
off999 2024-10-07 12:06 43 浏览 0 评论
前言
- 将 Python 可执行文件(.exe)反编译为 Python 脚本是一项有趣的技术挑战,可以帮助我们理解程序的工作原理,以及可能包含的逻辑和算法。虽然反编译不是一项简单的任务,并且对于使用各种保护措施的程序可能无效,但对于一般情况下的 Python 可执行文件,我们可以尝试使用一些工具来进行反编译。
- 下面我们就来学习如何将 Python 可执行文件(.exe)反编译为 Python 脚本。
版本
- Python 3.9
反编译
- 反编译是将已编译的程序代码还原为其原始源代码的过程。在 Python 中,由于其解释性质,通常没有像编译语言那样生成的二进制文件,但是我们可以将 Python 脚本转换为字节码文件(.pyc),而 .exe 文件通常是由 pyinstaller、cx_Freeze 等工具编译生成的。
Python 可执行文件(.exe)反编译
- Python 可执行文件(.exe)反编译为 Python 脚本主要分为两个步骤,(1)从 .exe 文件中提取 pyc 文件 (2)将 pyc 文件转换为 Python 脚本。
打包一个简单的 .exe 可执行文件
# student.py
class Student:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def get_name(self):
return self.name
def get_age(self):
return self.age
def get_gender(self):
return self.gender
def set_name(self, name):
self.name = name
def set_age(self, age):
self.age = age
def set_gender(self, gender):
self.gender = gender
def display_info(self):
print("Name:", self.name)
print("Age:", self.age)
print("Gender:", self.gender)
# main.py
import time
from student import Student
if __name__ == "__main__":
# Create a student object
student1 = Student("Alice", 20, "Female")
# Display student information
student1.display_info()
# Update student information
student1.set_age(21)
student1.display_info()
time.sleep(10)
# 使用 pyinstaller 构建可执行 .exe
pyinstaller --onefile -p venv/Lib/site-packages .\print-student\main.py提取 pyc 文件
使用脚本提取
- pyi-archive_viewer 是 PyInstaller 自己提供的工具,它可以直接提取打包结果exe中的pyc文件。
- 详细介绍可参考官方文档:https://pyinstaller.readthedocs.io/en/stable/advanced-topics.html#using-pyi-archive-viewer
# 使用 pyi-archive_viewer 查看文件并提取
> pyi-archive_viewer .\main.exe
Options in 'main.exe' (PKG/CArchive):
pyi-contents-directory _internal
Contents of 'main.exe' (PKG/CArchive):
position, length, uncompressed_length, is_compressed, typecode, name
0, 199, 269, 1, 'm', 'struct'
199, 2008, 3700, 1, 'm', 'pyimod01_archive'
2207, 7671, 17413, 1, 'm', 'pyimod02_importers'
9878, 1760, 4029, 1, 'm', 'pyimod03_ctypes'
11638, 644, 1074, 1, 'm', 'pyimod04_pywin32'
12282, 603, 851, 1, 's', 'pyiboot01_bootstrap'
12885, 229, 295, 1, 's', 'main'
......
4721057, 408332, 1123832, 1, 'b', 'unicodedata.pyd'
5129389, 702999, 702999, 0, 'z', 'PYZ-00.pyz'
?
U: go up one level
O <name>: open embedded archive with given name // 打开包查看文件
X <name>: extract file with given name // 提取文件
S: list the contents of current archive again
Q: quit
? x main
Output filename? main.pyc
? o PYZ-00.pyz
Contents of 'PYZ-00.pyz' (PYZ):
is_package, position, length, name
0, 17, 2647, '_compat_pickle'
......
0, 543553, 531, 'student'
0, 544084, 19733, 'subprocess'
0, 563817, 27425, 'tarfile'
0, 591242, 5936, 'textwrap'
0, 597178, 15612, 'threading'
0, 612790, 1398, 'token'
0, 614188, 8969, 'tokenize'
0, 623157, 6659, 'tracemalloc'
0, 629816, 27711, 'typing'
1, 657527, 70, 'urllib'
0, 657597, 13861, 'urllib.parse'
0, 671458, 2188, 'uu'
0, 673646, 26812, 'zipfile'
? x student
Output filename? student.pyc
? ls
U: go up one level
O <name>: open embedded archive with given name
X <name>: extract file with given name
S: list the contents of current archive again
Q: quit
? q- 在上面的操作中,我们使用 pyi-archive_viewer 提取了 main.pyc、和 student.pyc 文件,当时大家可以很清楚的看到弊端,即需要一个一个手动提取,对于大项目这是十分麻烦的,推荐使用下面的工具提取。
使用工具提取
- 我们可以使用开源项目 Python-exe-unpacker 中的脚本 pyinstxtractor.py 脚本进行提取,地址:https://github.com/countercept/Python-exe-unpacker
\print-student> Python pyinstxtractor.py .\main.exe
DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
[*] Processing .\main.exe
[*] Pyinstaller version: 2.1+
[*] Python version: 309
[*] Length of package: 5835756 bytes
[*] Found 59 files in CArchive
[*] Beginning extraction...please standby
[*] Found 81 files in PYZ archive
[*] Successfully extracted pyinstaller archive: .\main.exe
You can now use a python decompiler on the pyc files within the extracted directory将 .pyc 文件转换为 Python 脚本
入口运行类
- 对于从 pyinstaller 提取出来的 pyc 文件并不能直接反编译,入口运行类共16字节的 magic 和 时间戳被去掉了。如果直接进行反编译,例如执行 uncompyle6 main.pyc,则会报出如下错误:
ImportError: Unknown magic number 227 in main.pyc- 我们可以使用支持16进制编辑的文本编辑器进行处理,比如:UltraEdit32
- 可以看到前16个字节都被去掉了,其中前四个字节是magic,这四个字节会随着系统和Python版本发生变化,需要保持一致。后四个字节包括时间戳和一些其他的信息,都可以随意填写。我们可以通过 UltraEdit32 向提取的文件添加回信息。
- 这里我写了一个 python 脚本实现这个过程:
// 读取从pyz目录抽取的pyc文件的前4个字节作基准
pyz_dir = "./main.exe_extracted/PYZ-00.pyz_extracted"
for pyc_file in os.listdir(pyz_dir):
if pyc_file.endswith(".pyc"):
file = f"{pyz_dir}/{pyc_file}"
break
with open(file, "rb") as f:
head = f.read(4)
// 补全入口类文件
if os.path.exists("pycfile_tmp"):
shutil.rmtree("pycfile_tmp")
os.mkdir("pycfile_tmp")
main_file_result = "pycfile_tmp/main.pyc"
with open("./main.exe_extracted/main.pyc", "rb") as read, open(main_file_result, "wb") as write:
write.write(head)
write.write(b"\0" * 12)
write.write(read.read())非入口运行类
- 对于非入口运行的pyc文件从12字节开始缺4个字节。
# 补全非入口类文件
pyz_dir = "main.exe_extracted/PYZ-00.pyz_extracted"
for pyc_file in os.listdir(pyz_dir):
pyc_file_src = f"{pyz_dir}/{pyc_file}"
pyc_file_dest = f"pycfile_tmp/{pyc_file}"
print(pyc_file_src, pyc_file_dest)
with open(pyc_file_src, "rb") as read, open(pyc_file_dest, "wb") as write:
write.write(read.read(12))
write.write(b"\0"*4)
write.write(read.read())转换补全后的 pyc 文件
uncompyle6 反编译
pip install uncompyle6
uncompyle6 xxx.pyc>xxx.py
如:uncompyle6 .\pycfile_tmp\main.pyc
# uncompyle6 version 3.9.0
# Python bytecode version base 3.9.0 (3425)
# Decompiled from: Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)]
# Embedded file name: main.py
Unsupported Python version, 3.9.0, for decompilation
# Unsupported bytecode in file .\pycfile_tmp\main.pyc
# Unsupported Python version, 3.9.0, for decompilation- 由于我使用的是 3.9.0 版本,uncompyle6 不再支持 decompilation,有兴趣的朋友可以去试试。
在线工具
- 我们也可以使用一些在线工具进行解密,比如:https://ctfever.uniiem.com/tools/pyc-decompiler
可能遇到的问题
PYZ-00.pyz_extracted 文件为空
- 构建 .exe 文件 Python 版本和解压包时使用的版本不一致,比如我使用 Python 2.7 进行解包:
>Python .\pyinstxtractor.py .\main.exe
[*] Processing .\main.exe
[*] Pyinstaller version: 2.1+
[*] Python version: 312
[*] Length of package: 7675728 bytes
[*] Found 60 files in CArchive
[*] Beginning extraction...please standby
[!] Warning: The script is running in a different python version than the one used to build the executable
Run this script in Python312 to prevent extraction errors(if any) during unmarshalling
[!] Unmarshalling FAILED. Cannot extract PYZ-00.pyz. Extracting remaining files.
[*] Successfully extracted pyinstaller archive: .\main.exe
You can now use a python decompiler on the pyc files within the extracted directory
# 查看解压后的文件
\print-student\main.exe_extracted\PYZ-00.pyz_extracted> ls
\print-student\main.exe_extracted\PYZ-00.pyz_extracted>如何防止exe被反编译
- 我们可以在打包命令后面添加 --key 参数来进行加密,例如:
pyinstaller --onefile -p venv/Lib/site-packages .\print-student\main.py --key '1234'- 再次解压,抽取的中间结果变为了 .pyc.encrypted,无法正常反编译。
思考
- Bytecode encryption was removed in PyInstaller v6.0. Please remove your --key=xxx argument. For the rationale and alternatives see https://github.com/pyinstaller/pyinstaller/pull/6999
- 可以看到在 PyInstaller v6.0 加密参数已经被废弃,大家可以思考一下原因。
总结
- 反编译 Python 可执行文件可以帮助我们理解程序的工作原理和逻辑,但在实践中可能会受到许多因素的限制。对于复杂的程序,反编译可能只是了解其工作原理的第一步,可能需要进一步的分析和研究。最后,我们需要明白技术没有好坏,需要谨守道德和法律的底线。
相关推荐
- 安全教育登录入口平台(安全教育登录入口平台官网)
-
122交通安全教育怎么登录:122交通网的注册方法是首先登录网址http://www.122.cn/,接着打开网页后,点击右上角的“个人登录”;其次进入邮箱注册,然后进入到注册页面,输入相关信息即可完...
- 大鱼吃小鱼经典版(大鱼吃小鱼经典版(经典版)官方版)
-
大鱼吃小鱼小鱼吃虾是于谦跟郭麒麟的《我的棒儿呢?》郭德纲说于思洋郭麒麟作诗的相声,最后郭麒麟做了一首,师傅躺在师母身上大鱼吃小鱼小鱼吃虾虾吃水水落石出师傅压师娘师娘压床床压地地动山摇。...
-
- 哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)
-
要想将ppt免费转换为pdf的话,我们建议大家可以下一个那个wps,如果你是会员的话,可以注册为会员,这样的话,在wps里面的话,就可以免费将ppt呢转换为pdfpdf之后呢,我们就可以直接使用,不需要去直接不需要去另外保存,为什么格式转...
-
2026-02-04 09:03 off999
- 电信宽带测速官网入口(电信宽带测速官网入口app)
-
这个网站看看http://www.swok.cn/pcindex.jsp1.登录中国电信网上营业厅,宽带光纤,贴心服务,宽带测速2.下载第三方软件,如360等。进行在线测速进行宽带测速时,尽...
- 植物大战僵尸95版手机下载(植物大战僵尸95 版下载)
-
1可以在应用商店或者游戏平台上下载植物大战僵尸95版手机游戏。2下载教程:打开应用商店或者游戏平台,搜索“植物大战僵尸95版”,找到游戏后点击下载按钮,等待下载完成即可安装并开始游戏。3注意:确...
- 免费下载ppt成品的网站(ppt成品免费下载的网站有哪些)
-
1、Chuangkit(chuangkit.com)直达地址:chuangkit.com2、Woodo幻灯片(woodo.cn)直达链接:woodo.cn3、OfficePlus(officeplu...
- 2025世界杯赛程表(2025世界杯在哪个国家)
-
2022年卡塔尔世界杯赛程公布,全部比赛在卡塔尔境内8座球场举行,2022年,决赛阶段球队全部确定。揭幕战于当地时间11月20日19时进行,由东道主卡塔尔对阵厄瓜多尔,决赛于当地时间12月18日...
- 下载搜狐视频电视剧(搜狐电视剧下载安装)
-
搜狐视频APP下载好的视频想要导出到手机相册里方法如下1、打开手机搜狐视频软件,进入搜狐视频后我们点击右上角的“查找”,找到自已喜欢的视频。2、在“浏览器页面搜索”窗口中,输入要下载的视频的名称,然后...
- 永久免费听歌网站(丫丫音乐网)
-
可以到《我爱音乐网》《好听音乐网》《一听音乐网》《YYMP3音乐网》还可以到《九天音乐网》永久免费听歌软件有酷狗音乐和天猫精灵,以前要跳舞经常要下载舞曲,我从QQ上找不到舞曲下载就从酷狗音乐上找,大多...
- 音乐格式转换mp3软件(音乐格式转换器免费版)
-
有两种方法:方法一在手机上操作:1、进入手机中的文件管理。2、在其中选择“音乐”,将显示出手机中的全部音乐。3、点击“全选”,选中所有音乐文件。4、点击屏幕右下方的省略号图标,在弹出菜单中选择“...
- 电子书txt下载(免费的最全的小说阅读器)
-
1.Z-library里面收录了近千万本电子书籍,需求量大。2.苦瓜书盘没有广告,不需要账号注册,使用起来非常简单,直接搜索预览下载即可。3.鸠摩搜书整体风格简洁清晰,书籍资源丰富。4.亚马逊图书书籍...
- 最好免费观看高清电影(播放免费的最好看的电影)
-
在目前的网上选择中,IMDb(互联网电影数据库)被认为是最全的电影网站之一。这个网站提供了各种类型的电影和电视节目的海量信息,包括剧情介绍、演员表、评价、评论等。其还提供了有关电影制作背后的详细信息,...
- 孤单枪手2简体中文版(孤单枪手2简体中文版官方下载)
-
要将《孤胆枪手2》游戏的征兵秘籍切换为中文,您可以按照以下步骤进行操作:首先,打开游戏设置选项,通常可以在游戏主菜单或游戏内部找到。然后,寻找语言选项或界面选项,点击进入。在语言选项中,选择中文作为游...
欢迎 你 发表评论:
- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
