反编译 pyinstaller 产生的可执行文件
在一次计算中使用别人发布的由python编写然后编译打包的二进制程序进行操作时,总是报错"缺少链ID",但检查pdb文件已经添加了链ID。 为查明报错原因,对此二进制可执行文件进行了反编译。下面记录了操作过程:
python是解释型语言,故python编译打包成的可执行文件很容易被反编译,而像C,C++这样的编译型语言得到的可执行文件,则较难被反编译。 反编译pyinstaller 产生的可执行文件,可以分为两个步骤,一是由可执行文件获取pyc(pyo)文件,二是由pyc(pyo)文件得到py文件。
获取pyc文件
在Linux上运行pyintaller打包的可执行文件时,它会将打包好的文件解压到临时文件夹(/tmp)中的_MEIxxxxxx
路径中暂时存放,执行完毕之后再删除,所以会存在解压缩的时间。然而这个_MEIxxxxxx路径中主要是.so文件,并不含有源码。
但是pyinstaller自带脚本archive_viewer.py,可以由可执行文件解压得到pyc文件:
1
python archive_viewer.py exefilename
1
2
3
4U: go Up one level
O <name>: open embedded archive name
X <name>: extract name
Q: quit
列表中有两个部分需要关注,一个是out00-PYZ.pyz,其中包含主程序引用到的所有库;一个是主程序对应的文件名,其中会包含主程序。
比如,一个显示天气的程序,其主程序名称为show.py,其中调用了calc.py,则需要
1
2x show 提取到 show.pyc
o out00-PYZ.pyz 然后查看调用的库,然后 x calc 提取到 calc.pyc show.pyc和calc.pyc
从pyc获取py文件
方法
方法比较多,比如 1. 在线程序,比如python反编译,在线pyc反编译等 2. uncompyle6,是python脚本,故而可以批量运行,使用方法为
uncompyle6 file.pyc 3. easypythondecompiler等
注意
pyinstaller编译成pyc时,会把pyc的magic value去掉,如果使用easypythondecompiler的话,需要再把magic value补上(使用
010 Editor
编辑器)。magic value一共8个字节,前四个对应于编译时所用python的版本,后四个对应于编译时间,比如python2.7
的03 f3 0d 0a 01 23 45 67,python3.4
的ee 0c 0d 0a 01 23 45 67.如果不知道编译时所用的python版本,可以通过一个trick来寻找:在可执行文件包含的前几个文件对应的pyc文件(比如
pyimod01_os_path)中,前4个字节已经存在。
如此,便可反编译出show.py和calc.py等文件。
Ref: - Get Python Code From PYINSTALLER - python-pyinstaller-reverse-engineer