Python逆向
对于针对的python
的逆向常见主要有三种情况
exe
windows编程最终结果一般都是要生成exe
可执行文件,通过python
编程所生成的exe
与通过c/c++
编程生成的exe
虽然同为exe
,但若都使用OD
、IDA pro
的方式来进行逆向的话,很明显python
所生成的exe
文件会为逆向工作造成极大的困扰。但是,python
有专门逆向python
生成exe
文件的库
pyinstaller
第一种库是pyinstaller
这是一个可以将python脚本打包成exe的库,能打包自然也能解包
它包含了一个archive_viewer.py
的文件可以对打包为exe文件的python程序解包。
实例
写一个脚本hello.py
1 | print 'hello,world' |
通过pyinstaller
将其打包为exe
,下面的命令会在hello.py的目录下生成一个dist文件夹
1 | python pyinstaller --onefile --nowindowed hello.py |
然后对其进行解包操作
1 | python path/archive_viewer.py path/dist/hello.exe |
path分别为各个文件自己的路径
一般会反编译出很多模块,根据各个模块的名字来找目标模块,用x name
提取。可以得到目标的pyc文件(缺少magic header
)
pyinstxtractor
url: https://github.com/extremecoders-re/pyinstxtractor
第二种并非库,而是大佬写的一个反编译脚本,直接将脚本下载至所要反编译的exe文件目录下。
cmd运行
1 | python pyinstxtractor.py xxx.exe |
即可生成拆解目录xxx.exe_extracted
,在其中寻找目标文件xxx.pyc
。此pyc会自动根据运行时的python版本为其添加magic header
。(是本地运行时的python版本的,而非目标版本的)
结果
该反编译仅将exe反编译为pyc文件,且pyc文件的前8个字节是被删除的,需要用如winhex这样的文件手动添加文件头。这8个字节前四个是python编译时的版本,python2.7为03 f3 0d 0a
,python3.4为ee 0c 0d 0a
,其余版本的python对应的文件头自行查询;后四个字节是编译时的时间戳,随便写。
针对pyc的构造而言,主要分为两块:
- magic header。文件头
- code data。代码编译后的字节码数据,也即python版汇编
magic header的话可以去google的仓库查看google收录的每个版本对应的version字段数据(https://github.com/google/pytype/blob/main/pytype/pyc/magic.py)
也可以直接在自己本地安装的python官方库代码中查看,位置:
importlib._bootstrap_external.MAGIC_NUMBER
在MAGIC_NUMBER
变量上方包含本地版本及以前所有版本的magic version
数据
pyc
拥有pyc文件后,有三种方式反编译py文件:在线工具、python库、easy python decompiler、手撸
这里只说python库uncompyle
在线工具
根据本人使用经验大胆推测就是在服务器跑了一个加料的uncompyle6
uncompyle6
这里注意,因为官方精力不足的问题导致其完美支持的版本仅只支持到 3.8 版本的python,所以其对更高版本的python适配不大行,硬要用的话勉强也可以用一下。但,更高的版本需要自行解决bug问题。另外,查了下源码发现原理上讲强行使用也仅支持到3.9版本。不过python是一个非跨代情况下高版本适配低版本的语言,换句人话讲就是同世代下的高版本可以先简单理解成低版本的超集,这样子理解的话即便是超过了3.9的版本也存在可以反编译出源码的可能,最多就是涉及新添加的语言特性的部分无法识别报错或者直接在反编译中无视掉。
可以直接用pip安装
install: pip install uncompyle6
usage: uncompyle6.exe xxx.pyc > xxx.py
用以上命令即可拿到对应的py脚本(可能是残缺版)
手撸
适配任何版本的万能解决方案,就是费时间费手费眼。
python官方提供了marshal
、dis
两个库用于将python代码编译为python字节码以及将字节码对象反编译为python汇编代码。
官方手册(https://docs.python.org/zh-cn/3/library/dis.html#dis.Bytecode)中则有当前指定版本下汇编指令的功能,接下来就是喜闻乐见的肉眼反汇编为python源码的过程。python的汇编转换还是蛮简单的(不是)
py
py脚本都拿到了,还要说啥,代码审计去吧