Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Python exe 文件反编译为 Python 脚本

Python exe 文件反编译为 Python 脚本

原创
作者头像
Lorin 洛林
发布于 2024-04-20 17:32:10
发布于 2024-04-20 17:32:10
1.3K00
代码可运行
举报
文章被收录于专栏:Python 技术小屋Python 技术小屋
运行总次数: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 可执行文件

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 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 文件

使用脚本提取

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 使用 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
代码运行次数:0
运行
AI代码解释
复制
\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,则会报出如下错误:
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
ImportError: Unknown magic number 227 in main.pyc
  • 我们可以使用支持16进制编辑的文本编辑器进行处理,比如:UltraEdit32
差异对比
差异对比
  • 可以看到前16个字节都被去掉了,其中前四个字节是magic,这四个字节会随着系统和Python版本发生变化,需要保持一致。后四个字节包括时间戳和一些其他的信息,都可以随意填写。我们可以通过 UltraEdit32 向提取的文件添加回信息。
  • 这里我写了一个 python 脚本实现这个过程:
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
// 读取从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个字节。
差异对比
差异对比
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
# 补全非入口类文件
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 反编译
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
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,有兴趣的朋友可以去试试。
在线工具
反编译结果
反编译结果

可能遇到的问题

PYZ-00.pyz_extracted 文件为空

  • 构建 .exe 文件 Python 版本和解压包时使用的版本不一致,比如我使用 Python 2.7 进行解包:
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
>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 参数来进行加密,例如:
代码语言:python
代码运行次数:0
运行
AI代码解释
复制
 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 可执行文件可以帮助我们理解程序的工作原理和逻辑,但在实践中可能会受到许多因素的限制。对于复杂的程序,反编译可能只是了解其工作原理的第一步,可能需要进一步的分析和研究。最后,我们需要明白技术没有好坏,需要谨守道德和法律的底线。

个人简介

👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.

🚀 我对技术的热情是我不断学习和分享的动力。我的博客是一个关于Java生态系统、后端开发和最新技术趋势的地方。

🧠 作为一个 Java 后端技术爱好者,我不仅热衷于探索语言的新特性和技术的深度,还热衷于分享我的见解和最佳实践。我相信知识的分享和社区合作可以帮助我们共同成长。

💡 在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。我也将分享一些编程技巧和解决问题的方法,以帮助你更好地掌握Java编程。

🌐 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。

📖 保持关注我的博客,让我们共同追求技术卓越。

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
为什么黑客都喜欢通过YouTube 传播木马/恶意软件
年初时就有研究人员提醒,上传到 YouTube 上与 AI 生成有关的视频表面在传播破解软件,其实是传播恶意软件。尽管 AI 生成的视频热度在下降,但这种攻击媒介仍然可行,且会被攻击者持续利用。
FB客服
2024/03/18
2550
为什么黑客都喜欢通过YouTube 传播木马/恶意软件
新Zloader感染链改进隐身和检测逃避技术
ZLoader(又称 Terdot)于 2016 年被首次发现,是臭名昭著的 Zeus 银行木马的一个变种。目前,该恶意软件仍然在积极开发中,平均每周发布 1 到 2 个新版本。
FB客服
2021/10/11
8740
Adobe Flash零日漏洞(CVE-2018-4878)在野攻击完全分析报告
背景 2018年1月31日,韩国计算机应急响应小组发布了一则关于Adobe Flash Player的 0day 漏洞警告,并称早在2017年11月中旬,就有黑客利用该漏洞实施有针对性的攻击。 2018年2月1日, Adobe官方发布了Adobe Flash Player系列产品的安全通告(APSA18-01),一个最新的AdobeFlash零日漏洞被发现针对韩国地区的人员发起攻击,该0day漏洞编号为CVE-2018-4878。 2018年2月5日,Adobe官方发布漏洞补丁,修复CVE-2018-487
FB客服
2018/02/23
1.3K0
Adobe Flash零日漏洞(CVE-2018-4878)在野攻击完全分析报告
KBOT研究报告
KBOT通过Internet或本地网络或受感染的外部媒介攻击用户计算机。受感染的文件启动后在系统中写入启动程序和任务调度程序,然后进行web注入窃取受害者的银行和个人数据。KBOT可以下载额外的窃取模块,把所有的用户信息发送给C&C服务器,包括密码/登录、钱包数据、文件列表和已安装的应用程序等。恶意软件将其所有文件和收集的数据存储在RC6加密的虚拟文件系统中,因此很难被检测到。
FB客服
2020/02/27
1.3K0
WSP ( CVE-2022-24934 ) APT
我们最近发现了一个APT我们正在调用的活动Operation Dragon Castling。该活动的目标是似乎在投注的公司South East Asia,更具体地说是位于Taiwan、Philippines和的公司Hong Kong。有了适度的信心,我们可以将活动归因于一个Chinese speaking APT group,但不幸的是不能将攻击归因于特定的群体,并且不确定攻击者的目标是什么。
Khan安全团队
2022/03/25
4.8K1
窃密恶意软件通过仿冒盗版软件下载网站进行传播
攻击者正在针对寻求下载盗版软件的用户进行攻击,由于用户自己知道获取与使用盗版软件是违法的,许多下载盗版软件的用户都不会对下载来源进行安全审查,这些用户最终可能会付出更大的代价。 介绍 自从 Napster 在互联网上发布盗版已经有二十余年,海盗湾种子下载站出现也近十年。尽管许多国家都针对此发布了相关的法律与禁令,但是盗版依旧屡禁不止,许多人都会下载与使用。互联网上也有很多宣传破解软件的的广告,出现在 Google 的搜索结果与网站的广告位中。 【Google 搜索结果中的仿冒盗版下载网站】 安全研究
FB客服
2023/03/30
8240
窃密恶意软件通过仿冒盗版软件下载网站进行传播
NuggetPhantom分析报告
近期,绿盟威胁情报中心(NTI)在一次应急响应中,发现一起使用模块化恶意工具集“NuggetPhantom(掘金幽灵)”的安全事件。据我们观测,本次安全事件背后的组织最早出现于2016年底,其曾在2016年底的“天翼校园客户端蓝屏事件”以及2017年底的“天翼校园客户端挖矿程序事件”中有所行动。
绿盟科技研究通讯
2019/12/11
1.1K0
NuggetPhantom分析报告
探索编译的V8 JavaScript在恶意软件中的应用
为了静态分析编译后的JavaScript文件,研究人员使用了一个新开发的定制工具「View8」,专门用于将V8字节码反编译为高级可读语言。借助View8,研究人员成功反编译了数千个恶意编译的V8应用程序,涵盖各种恶意软件类型,如远程访问工具(RAT),窃取程序,挖矿程序甚至勒索软件。
FB客服
2024/07/22
3450
探索编译的V8 JavaScript在恶意软件中的应用
【最新】LuaJIT 32/64 位字节码,从编译到使用全纪录
网上关于 LuaJIT 的讨论,已经显得有些陈旧。如果你对 LuaJIT 编译 Lua 源文件为具体的 32位或64位字节码,极其具体使用感兴趣的话,不妨快速读一下这篇文章。此文章针对尝试在 iOS 或 Android 上使用 LuaJIT 的小伙伴。限于篇幅,此处假定,你可以成功在 iOS/Android App 中集成了 LuaJIT,并且已经可以执行源码形式的 Lua 文件。
ios122
2018/07/31
3.5K0
Lua和Luajit
一、什么是lua&luaJit lua(www.lua.org)其实就是为了嵌入其它应用程序而开发的一个脚本语言, luajit(www.luajit.org)是lua的一个Just-In-Time也就是运行时编译器,也可以说是lua的一个高效版。 二、优势 1)lua是一个免费、小巧、简单、强大、高效、轻量级的嵌入式的脚本语言,lua当前的发行版本5.3.1只有276k。 2)它是用C语言开发的项目,所以可以在大部分的操作系统上运行 3)lua是目前速度最快的脚本语言,既可以提升语言的灵
全栈程序员站长
2022/11/08
1.7K2
针对交易软件 TradingView 的供应链攻击
RedLine、RecordBreaker、ArkeiStealer、Vidar、Satacom、BatLoader 等窃密类恶意软件通常使用恶意软件即服务(MaaS)模式进行销售,并且不断更新升级攻击方式。
FB客服
2023/02/10
6630
针对交易软件 TradingView 的供应链攻击
Quantum 构建工具使用新的 TTP 投递 Agent Tesla
Zscaler 的研究人员发现暗网上正在出售名为 Quantum Builder 的构建工具,该工具可以投递 .NET 远控木马 Agent Tesla。与过去的攻击行动相比,本次攻击转向使用 LNK 文件。
FB客服
2022/11/14
1.6K0
Quantum 构建工具使用新的 TTP 投递 Agent Tesla
RomCom 攻击者使用投毒的应用程序攻击乌克兰与英国
被称为 RomCom 的攻击者正在利用 SolarWinds、KeePass 与 PDF Technologies 等公司的软件作为诱饵,开展一系列的攻击行动。研究人员发现攻击者通过虚假软件针对乌克兰军事机构发起攻击,并且投递 RomComRAT 远控木马。 RomCom 在攻击行动中仿冒了 SolarWinds Network Performance Monitor、KeePass Open-Source Password Manager 与 PDF Reader Pro 这几款软件。 根据恶意网站的服务
FB客服
2023/03/29
5050
RomCom 攻击者使用投毒的应用程序攻击乌克兰与英国
研究传播 Dridex 新变种的 Excel 文档
Dridex也称为 Bugat 或 Cridex,可以从失陷主机上窃取敏感信息并执行恶意模块(DLL)的木马。
FB客服
2021/10/11
1.4K0
Windows 11更新要小心了,恶意软件已经盯上它
2022年年初,微软官方一再发布消息催促用户及时更新Windows 11系统,并表示Windows 11 系统的推广部署工作已经进入尾声。微软此前曾承诺在2022年年中完成Windows 11的推广工作,现在看来,该公司很有可能与这一最初的时间表保持一致。而一旦错过了这个推广期,后续用户很有可能无法继续享受免费更新Windows 11系统的服务。
FB客服
2022/02/25
5670
Windows 11更新要小心了,恶意软件已经盯上它
Lazarus针对COVID-19发起攻击
随着COVID-19影响持续升级,攻击者正在试图通过任何手段加速疫苗研发。有证据表明,Lazarus正在通过攻击与COVID-19研究有关的实体来获取此类情报。他们在9月底攻击了一家制药公司和COVID-19有关的政府部门。
FB客服
2021/02/07
9230
[译] APT分析报告:04.Kraken新型无文件APT攻击利用Windows错误报告服务逃避检测
这是作者新开的一个专栏,主要翻译国外知名的安全厂商APT报告文章,了解它们的安全技术,学习它们溯源APT组织的方法,希望对您有所帮助。前文分享了APT组织Fin7 / Carbanak的Tirion恶意软件,包括OpBlueRaven行动。这篇文章将介绍一种新型无文件APT攻击Kraken,它会利用Windows错误报告服务逃避检测。其中,DllMain函数反分析检查,以确保它不在分析/沙箱环境或调试器中运行非常值得我们学习。
Eastmount
2021/12/03
1.1K0
[译] APT分析报告:04.Kraken新型无文件APT攻击利用Windows错误报告服务逃避检测
Naikon APT组织分析
近期Check Point发现Naikon APT组织正在对亚太地区(APAC)国家政府进行网络攻击活动,使用了名为Aria-body的新后门控制受害者的网络。本报告将详细分析Naikon APT组织在过去5年中使用的战术,技术,程序和基础设施。
FB客服
2020/06/03
1.1K0
新型OpcJacker恶意软件通过虚假的VPN传播恶意广告
趋势科技研究人员发现了一种新型恶意软件,将其命名为 "OpcJacker"(取其opc配置设计“opc”和加密货币劫持“hijack”能力英文前后缀opc-jack而成),该恶意软件自2022年下半年以来一直传播。OpcJacker是一个有趣的恶意软件,因为它的配置文件使用一个自定义的文件格式来定义窃取者的行为。具体来说,该文件格式类似于自定义的虚拟机代码,配置文件中存在的十六进制数字标识符使得窃密器可运行所需的功能。使用这种设计的目的可能是为了使研究人员更难理解和分析恶意软件的代码流。 恶意软件OpcJa
FB客服
2023/04/26
1.1K0
新型OpcJacker恶意软件通过虚假的VPN传播恶意广告
Turla的新武器:TinyTurla
Turla 也被称为 Snake、Venomous Bear、Uroburos 和 WhiteBear,是一个臭名昭著的 APT 组织。据信该组织来自俄罗斯,2004 年以来就一直活跃。
FB客服
2021/10/11
6990
相关推荐
为什么黑客都喜欢通过YouTube 传播木马/恶意软件
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验