近期阅读了一篇很感兴趣的文章,为免后续文章被删无法再阅读,现自己写一下哈~

原文章:爆强!将 exe 文件反编译成 Python 脚本!

这篇文章跟自己的另一篇文章,正好形成技术上的互逆过程,也同时欢迎阅读指正

python代码文件封装为可执行exe文件_py_IA&IM的博客-CSDN博客1.安装依赖库pip install pywin32pipinstall pyinstaller(安装失败可换为:pipinstall pyinstaller --no-use-pep517)或可通过python第三方库网站下载后安装。验证pyinstaller安装成功:2.python文件生成可执行exe文件windows+R键 -> cmd -> 控制台界面切入python文件所在的目录执行命令:pyinstaller -F python文件名.py,生成..https://blog.csdn.net/qq_40794377/article/details/108425780

————————————————————————————————————————————————————————————

最近遇到了一个问题,自己打包好的exe文件还在,但是Python源文件不知什么时候被误删了。现在想改动一下功能,重写Python脚本工程量也太大了,怎么办?

今天我将教大家如何反编译exe文件,即将自己或别人写好的exe,还原成Python源码。

以最近写Python一键自动整理归类文件为例进行演示,运行所需的代码和文件都会在文末提供给大家。

打包成单文件所使用的命令为:

pyinstaller -Fw --icon=h.ico auto_organize_gui.py --add-data="h.ico;/"

打包成文件夹所使用的命令为:

pyinstaller -w --icon=h.ico auto_organize_gui.py --add-data="h.ico;."

不管是哪种打包方式都会留下一个exe文件。

首先我们需要从exe文件中抽取出其中的pyc文件:

抽取exe中的pyc文件

抽取pyinstaller打包的exe中的pyc文件,提取pyc文件有两种方法:

  1. 通过 pyinstxtractor.py 脚本提取pyc文件

  2. 通过 pyi-archive_viewer 工具提取pyc文件

脚本提取pyc文件

pyinstxtractor.py 脚本可以在github项目 python-exe-unpacker 中下载,地址:

https://github.com/countercept/Python-exe-unpacker

下载该项目后把其中的pyinstxtractor.py脚本文件复制到与exe同级的目录。

然后进入exe所在目录的cmd执行:

Python pyinstxtractor.py auto_organize_gui.exe

执行后便得到exe文件名加上_extracted后缀的文件夹:

对两种打包方式产生的exe提取出的文件结构稍有区别:

工具提取pyc文件

pyi-archive_viewer是PyInstaller自己提供的工具,它可以直接提取打包结果exe中的pyc文件。

详细介绍可参考官方文档:ttps://pyinstaller.readthedocs.io/en/stable/advanced-topics.html#using-pyi-archive-viewer

执行pyi-archive_viewer [filename]即可查看 exe 内部的文件结构:

pyi-archive_viewer auto_organize.exe

操作命令:

U: go Up one level
O <name>: open embedded archive name
X <name>: extract name
Q: quit

然后可以提取出指定需要提取的文件:

要提取其他被导入的pyc文件,则需要先打开PYZ-00.pyz

很显然,使用PyInstaller的pyi-archive_viewer 工具操作起来比较麻烦,一次只能提取一个文件,遇到子模块还需执行一次打开操作。

所以后面我也只使用pyinstxtractor.py 脚本来提取pyc文件。

反编译pyc文件为py脚本

有很多对pyc文件进行解密的网站,例如:

  • https://tool.lu/pyc/

不过我们直接使用 uncompyle6 库进行解码,使用pip可以直接安装:

pip install uncompyle6

uncompyle6可以反编译.pyc后缀结尾的文件,两种命令形式:

  1. uncompyle6 xxx.pyc>xxx.py

  2. uncompyle6 -o xxx.py xxx.pyc

以前面编码过程中生成的缓存为例进行演示:

uncompyle6 auto_organize.cpython-37.pyc>auto_organize.py

执行后便直接将.pyc文件反编译成Python脚本了:

从编译结果看注释也被保留了下来:

对于不是pyc后缀结尾的文件,使用uncompyle6反编译时会报出 must point to a Python source that can be compiled, or Python bytecode (.pyc, .pyo) 的错误。

所以我们需要先对提取出的内容人工修改后缀:

运行入口pyc文件反编译

对于从pyinstaller提取出来的pyc文件并不能直接反编译,入口运行类共16字节的 magic 和 时间戳被去掉了。

如果直接进行反编译,例如执行 uncompyle6 auto_organize_gui.exe_extracted/auto_organize_gui.pyc

会报出如下错误:ImportError: Unknown magic number 227 in auto_organize_gui.exe_extracted\auto_organize_gui.pyc

使用支持16进制编辑的文本编辑器查看一探究竟,这里我使用UltraEdit32

分别打开正常情况下编译出的pyc和从pyinstaller提取出来的pyc文件进行对比:

可以看到前16个字节都被去掉了,其中前四个字节是magic,这四个字节会随着系统和Python版本发生变化,必须一致。后四个字节包括时间戳和一些其他的信息,都可以随意填写。

我们先通过UltraEdit32向pyinstaller提取的文件添加头信息:

选择开头插入16个字节后,只需要替换前4个字节为当前环境下的magic:

然后执行:

uncompyle6 auto_organize_gui.exe_extracted/auto_organize_gui.pyc>auto_organize_gui.py

执行后可以看到文件已经顺利的被反编译:

依赖性pyc文件反编译

考虑再反编译导入的其他依赖文件:

先用UltraEdit32打开查看一下:

可以看到对于非入口运行的pyc文件是从12字节开始缺4个字节。

这里我们选择第13个字节再插入四个字节即可:

然后再执行:

uncompyle6 auto_organize_gui.exe_extracted/PYZ-00.pyz_extracted/auto_organize.pyc > auto_organize.py

然后成功的反编译出依赖的文件:

代码与原文件几乎完全一致:

批量反编译

如果一个exe需要被反编译的Python脚本只有3个以内的文件,我们都完全可以人工来操作。

但是假如一个exe涉及几十个甚至上百个Python脚本需要反编译的时候,人工操作未免工作量过于巨大,我们考虑将以上过程用Python实现,从而达到批量反编译的效果。

提取exe中的pyc

import os
import sys
import pyinstxtractorexe_file = r"D:/PycharmProjects/gui_project/dist/auto_organize_gui.exe"
sys.argv = ['pyinstxtractor', exe_file]
pyinstxtractor.main()
# 恢复当前目录位置
os.chdir("..")
[*] Processing D:/PycharmProjects/gui_project/dist/auto_organize_gui.exe
[*] Pyinstaller version: 2.1+
[*] Python version: 37
[*] Length of package: 9491710 bytes
[*] Found 984 files in CArchive
[*] Beginning extraction...please standby
[*] Found 157 files in PYZ archive
[*] Successfully extracted pyinstaller archive: D:/PycharmProjects/gui_project/dist/auto_organize_gui.exeYou can now use a Python decompiler on the pyc files within the extracted directory

预处理pyc文件修护校验头

def find_main(pyc_dir):for pyc_file in os.listdir(pyc_dir):if not pyc_file.startswith("pyi-") and pyc_file.endswith("manifest"):main_file = pyc_file.replace(".exe.manifest", "")result = f"{pyc_dir}/{main_file}"if os.path.exists(result):return main_filepyc_dir = os.path.basename(exe_file)+"_extracted"
main_file = find_main(pyc_dir)
main_file

读取从pyz目录抽取的pyc文件的前4个字节作基准:

pyz_dir = f"{pyc_dir}/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)
list(map(hex, head))
['0x42', '0xd', '0xd', '0xa']

校准入口类:

import shutil
if os.path.exists("pycfile_tmp"):shutil.rmtree("pycfile_tmp")
os.mkdir("pycfile_tmp")
main_file_result = f"pycfile_tmp/{main_file}.pyc"
with open(f"{pyc_dir}/{main_file}", "rb") as read, open(main_file_result, "wb") as write:write.write(head)write.write(b"\0"*12)write.write(read.read())

校准子类:

pyz_dir = f"{pyc_dir}/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())

开始反编译

from uncompyle6.bin import uncompileif not os.path.exists("py_result"):os.mkdir("py_result")
for pyc_file in os.listdir("pycfile_tmp"):sys.argv = ['uncompyle6', '-o',f'py_result/{pyc_file[:-1]}', f'pycfile_tmp/{pyc_file}']uncompile.main_bin()

完整代码下载见文末。

这样我们只需将Python脚本、exe文件和pyinstxtractor.py脚本文件 放置到同一文件夹下,运行我们的Python脚本。即可反编译exe。

可以看到已经完美的反编译出exe其中的Python脚本:

好了,相信大家已经明白了反编译的原理。那么既然是攻防,如何防止自己打包的exe被反编译呢?

如何防止exe被反编译呢

只需在打包命令后面加上--key命令即可,例如文章开头的命令可以更换为:

pyinstaller -Fw --icon=h.ico auto_organize_gui.py --add-data="h.ico;/" --key 123456

123456是你用来加密的密钥,可以随意更换。

该加密参数依赖tinyaes,可以通过以下命令安装:

pip install tinyaes

打包后再次执行反编译:

exe_file = r"D:/PycharmProjects/gui_project/dist/auto_organize_gui.exe"
uncompyle_exe(exe_file, True)

结果只有入口脚本反编译成功,被依赖的脚本均被加密,无法直接被反编译:

可以看到抽取的中间结果变成了.pyc.encrypted格式,无法直接被反编译:

可以看到,常规手段就无法直接反编译了。

这个时候还想反编译就需要底层的逆向分析研究了,或者pyinstaller的源码完整研究一遍,了解其加密处理的机制,看看有没有破解的可能。

将 exe 文件反编译成 Python 脚本相关推荐

  1. Python代码封装的可执行exe文件反编译为Py脚本

    起因是笔者有个课,教图形图像学,作业的代码调不出老师的效果,于是就又有了hack的想法,把老师给的用来演示的exe文件反编译.主要是根据这篇文章的方法来的.将 exe 文件反编译成 Python 脚本 ...

  2. 【干货】Python文件打包 .exe文件反编译

    一.Python文件 打包 成 .exe 可执行文件 第一步:安装pyinstaller 首先安装pyinstall,使用命令:pip3 install pyinstaller,当然有可能报错,如下图 ...

  3. python编译成exe和exe反编译成python

    先看文章概要.再看左侧目录,可准确找到需要内容 文章概要:python文件可编译成exe文件,exe文件也可通过反编译恢复为python文件.下面简单介绍如何生成exe和恢复python python ...

  4. 什么是pyc文件,把python的py文件编译成pyc文件,把pyc文件反编译成py文件。以及python编译的如何设置不生成pyc文件

    文章目录 1 什么是pyc文件 1.1 什么是pyc文件 1.2 pyc文件是怎么生成的,有什么好处 2 把python的py文件编译成pyc文件 2.1 使用python内置库py_compile把 ...

  5. so文件反编译为python代码_【反编译系列】四、反编译so文件(IDA_Pro)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 安卓应用程序的开发语言是java,但是由于java层的代码很容易被反编译,而反编译c/c++程序的难度比较大,所以现在很多安卓应用程 ...

  6. apk文件反编译成android代码

    文章主要介绍apktool,jd-gui,dex2j的编译步骤,若有其他需要可直接滑到文章最后有自动化工具下载地址.自动化工具不需要代码操作,直接拖动反编译出源代码. 1.Apk反编译步骤 准备工具 ...

  7. exe4j生成的exe文件反编译

    现在网络上越来越流行.net和java写的客户端的小应用程序,而且后缀是exe.本文讨论的是如何从exe4j封装的exe文件中将自己想要的jar抽取出来. exe4j一直是一种比较通用的java ex ...

  8. linux将py变成exe文件,使用py2exe将Python 脚本生成exe可执行文件

    使用Python的py2exe模块可以很容易地帮助我们将Python脚本生成可执行的exe程序.这样我们就可以让脚本脱离虚拟机的束缚,从而独立运行. 环境要求: python虚拟机,我使用的是pyth ...

  9. exe文件反编译为源文件

    准备一个16进制字节码编辑器,UltraEdit 用UltraEdit打开待还原的exe文件,你就会看到这个exe的字节文件. 确定swf的开头,把之前的所有内容全部删除掉. swf大部分都是以46 ...

  10. s19文件反编译成c语言,S19文件反编译器使用说明.ppt

    S19文件反编译器使用说明 S19 decoder Sep 2008 lzbing Decoder Find decoder.exe in codewarrior installation direc ...

最新文章

  1. 基于OpencvCV的情绪检测
  2. 【每周CV论文推荐】 初学高效率CNN模型设计应该读的文章
  3. Python开发【第一篇】:目录
  4. long long c语言_带你打开C语言的大门之C语言的变量
  5. Redis系统性介绍
  6. Android 代码实现查看SQLite数据库中的表
  7. c语言调用sqlite
  8. wps表格在拟合曲线找点_excel拟合曲线函数表达式,excel散点拟合出来的公式看不懂。请问怎么写入表格使用?...
  9. 三容水箱液位控制系统_过程控制实验-三容水箱液位控制系统
  10. 关于KX混响插件:REVERB R详解
  11. 保护电路:简单的限流保护电路图
  12. 使用阿里云接口进行银行卡三四要素实名认证(阿里云api接口java)
  13. css字的大小,css 中字体大小
  14. 对Proteus与Keil联调过程中遇到的怪异现象解决方法
  15. 打开ps显示计算机内存不足怎么办,ps显示内存不足怎么办,教你ps显示内存不足怎么办...
  16. LICEcap:GIF屏幕录制工具
  17. 【无线】【流程】QCA无线驱动收包流程分析
  18. 深度探索:使用FFmpeg实现视频Logo的添加与移除
  19. node安装后的设置(node_global和node_cache)
  20. 机器学习-白板推导系列(一)-绪论(机器学习的MLE(最大似然估计)和MAP(最大后验估计))

热门文章

  1. 春季个人训练赛 5(广工新生赛)
  2. RemObjects Elements Crack,用途软件开发工具链
  3. 2020成人高考计算机基础知识题库,成人高考计算机考试全套题库
  4. 【电子科技大学-微电子技术导论】学习笔记
  5. 交互式电子杂志_XFlip Enterprise(电子杂志相册制作器)
  6. 常见电脑病毒及解决措施
  7. 16S多样性组成谱研究,9.13分的Water Research轻松二连发!
  8. 制作 Pidgin QQ 表情包
  9. 这游戏为什么被称作是独立游戏的巅峰?
  10. 10分钟搞定工作周报