我们都知道可以使用Pyinstaller库可将
.py文件编译成.exe文件运行,这篇文章我们就从将脚本编译成.exe并将.exe的源码内容反编译出源文件,再顺便谈谈如何防止被逆向。
Python 3.6:https://www.python.org/downloads/release/python-360/
Pyinstaller库:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller==4.0
pyinstxtractor.py:下载地址:https://sourceforge.net/projects/pyinstallerextractor/
WinHex编辑器:下载地址:https://down.52pojie.cn/Tools/Editors/WinHex_v19.9.zip
uncompyle库:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple uncompyle6==3.9.0
tinyaes库:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tinyaes==1.0.3
python -V

测试脚本.py
import datetime# 函数
def test():print("====反编译源码的测试脚本====")input_text = input("请输入你想要打印的内容:")# 打印格式化时间和用户输入的内容print(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ") + input_text)if __name__ == '__main__':# 调用test()
首先安装打包程序所使用的库pyinstaller,这里用了清华源并且指定使用了4.0版本库
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller==4.0
找到脚本所在的文件夹,我的是C:\Users\YRJ\Desktop\a cd 到此路径下,并输入以下打包命令:
Pyinstaller -F 测试脚本.py
命令执行完毕后,会看到completed successfully.字段,表示.exe文件生成成功,在dist文件夹中。

首先我们下载反编译工具pyinstxtractor.py与我们要反编译的.exe文件放入同一个工作目录下,如下图所示:

然后我们继续在命令行cd到dist文件夹,输入以下命令并执行:
python pyinstxtractor.py 测试脚本.exe
执行完毕,看到Successfully字样,会生成测试脚本.exe_extracted文件夹,如下图所示:

进入该文件夹,里面有许许多多后缀为.dll和.pyd的文件,还有一个名为PYZ-00.pyz_extracted的文件夹,这个文件夹里放的是程序引入的依赖库,如果你引入过自己其他的.py文件,就可以用类似的方法将依赖的.py文件反编译出来,如下图所示:
在目录中我们要找到struct和与你的.exe文件同名的文件。如下图所示:

这两个文件是否带.pyc后缀和你使用的pyinstxtractor.py工具版本有关系。V2.0以前的版本,会生成两个不带.pyc后缀的文件,手动为它添加.pyc后缀即可。如下图所示:

当前这个测试脚本.pyc文件是没有Magic Number的,我们需要根据Python版本自行补全,由上图可知打包此程序的Python版本为3.6,我们接下来就需要查3.6版本的Magic Number。
查通用对照表:
enum PycMagic {MAGIC_1_0 = 0x00999902,MAGIC_1_1 = 0x00999903,MAGIC_1_3 = 0x0A0D2E89,MAGIC_1_4 = 0x0A0D1704,MAGIC_1_5 = 0x0A0D4E99,MAGIC_1_6 = 0x0A0DC4FC,MAGIC_2_0 = 0x0A0DC687,MAGIC_2_1 = 0x0A0DEB2A,MAGIC_2_2 = 0x0A0DED2D,MAGIC_2_3 = 0x0A0DF23B,MAGIC_2_4 = 0x0A0DF26D,MAGIC_2_5 = 0x0A0DF2B3,MAGIC_2_6 = 0x0A0DF2D1,MAGIC_2_7 = 0x0A0DF303,MAGIC_3_0 = 0x0A0D0C3A,MAGIC_3_1 = 0x0A0D0C4E,MAGIC_3_2 = 0x0A0D0C6C,MAGIC_3_3 = 0x0A0D0C9E,MAGIC_3_4 = 0x0A0D0CEE,MAGIC_3_5 = 0x0A0D0D16,MAGIC_3_5_3 = 0x0A0D0D17,MAGIC_3_6 = 0x0A0D0D33,MAGIC_3_7 = 0x0A0D0D42,MAGIC_3_8 = 0x0A0D0D55,MAGIC_3_9 = 0x0A0D0D61,
};
例如: Python 3.6的Magic Number,执行后可以得到0x0A0D0D33,则对应二进制码是33 0D 0D 0A
看struct.pyc文件:
将struct.pyc文件使用WinHex编辑器打开,它的前4位字节就是magic num与方法一的二进制码相同。如下图所示:

再打开测试脚本.pyc与struct.pyc对比头内容确定要添加的内容,如下图所示:

选中struct.pyc中框选的头内容,右键编辑→复制选块→十六进制数值。330D0D0A7079693001010000

打开测试脚本.pyc,直接在前面添加,上面复制的十六进制数值330D0D0A7079693001010000,光标点击第一个字母E右键编辑→剪贴板数据→粘贴→ASCII Hex→确定,然后保存即修改完毕!如下图所示:



安装.pyc转.py所使用的库uncompyle6,这里用了清华源并且指定使用了3.9.0版本库
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple uncompyle6==3.9.0
找到测试脚本.pyc所在的文件夹,cd 到此路径下,并输入以下打包命令:
uncompyle6 -o 测试脚本.py 测试脚本.pyc
命令执行完毕后,会看到successfully字段,表示.py源码文件已成功生成在同路径下。

通过对程序本来的源码和逆向得来的源码对比可知:简单的源码上基本一直,复杂写的源码上可能会有一点点瑕疵。
单就此次逆向的程序而言,比程序原本的源码就少了源码的注释,多了系统反编译时相关环境及版本的注释。

通过命令python 测试脚本.py执行逆向得来的源码,测试通过,发现功能正常。

首先安装加密打包程序所使用的库tinyaes,这里用了清华源并且指定使用了1.0.3版本库
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tinyaes==1.0.3
找到脚本所在的文件夹,我的是C:\Users\YRJ\Desktop\c cd 到此路径下,并输入以下打包命令:
pyinstaller -F 测试脚本.py --key 123456
命令执行完毕后,会看到completed successfully.字段,表示.exe文件生成成功,在dist文件夹中。

接着就安装前面写的逆向过程执行命令python pyinstxtractor.py 测试脚本.exe,结果只有入口脚本反编译成功,被依赖的脚本均被加密,无法直接被反编译,如下图所示:

PYZ-00.pyz_extracted文件夹内可以看到,抽取的中间结果变成了.pyc.encrypted格式,无法直接被反编译,未加密和加密的相关对比,如下图所示:

常规手段就无法直接反编译了。这个时候若还想反编译就需要底层的逆向分析研究或将pyinstaller的源码完整研究一遍,了解其加密处理的机制,看看有没有逆向的可能。
略
略
参考文章:
Python 反编译:pyinstxtractor工具和uncompyle6库的使用:https://blog.csdn.net/qq_63585949/article/details/126706526
Python Uncompyle6 反编译工具使用与Magic Number详解:https://blog.csdn.net/Zheng__Huang/article/details/112380221
python Magic Number对照表以及pyc修复方法:https://www.cnblogs.com/Here-is-SG/p/15885799.html
Pyinstaller打包的exe之一键反编译py脚本与防反编译:https://blog.51cto.com/u_11866025/5714478#pyc_223
winhex无法创建请确定文件夹存在文件没有受到保护:https://zhidao.baidu.com/question/135115576.html
Python 反编译:pycdc工具的使用:https://blog.csdn.net/qq_63585949/article/details/127080253
上一篇:最大化股票交易的利润