Python逆向

参考链接:
https://www.bilibili.com/video/BV1JL4y1p7Tt/?spm_id_from=333.999.0.0
https://bbs.kanxue.com/thread-282542.htm
https://blog.youkuaiyun.com/weixin_35967330/article/details/114390031?spm=1001.2014.3001.5501
https://0xd13a.github.io/ctfs/0ctf2017/py/

前言:

可以关注一下个人博客:https://www.cnblogs.com/N1ng
python作为Reverse中的高级语言题目,占比逐渐上升,于是想着专门写一篇关于python逆向的文章。
这里分为四部分:直接反编译,pyc字节码,exe解包和加花的pyc
觉得看不懂的可以点击下方链接查看水番正文师傅的视频。d=====( ̄▽ ̄*)b
https://www.bilibili.com/video/BV1JL4y1p7Tt/?spm_id_from=333.999.0.0

不同版本的python魔数头

Python 版本 十六进制文件头
Python 2.7 03f30d0a00000000
Python 3.0 3b0c0d0a00000000
Python 3.1 4f0c0d0a00000000
Python 3.2 6c0c0d0a00000000
Python 3.3 9e0c0d0a0000000000000000
Python 3.4 ee0c0d0a0000000000000000
Python 3.5 170d0d0a0000000000000000
Python 3.6 330d0d0a0000000000000000
Python 3.7 420d0d0a000000000000000000000000
Python 3.8 550d0d0a000000000000000000000000
Python 3.9 610d0d0a000000000000000000000000
Python 3.10 6f0d0d0a000000000000000000000000
Python 3.11 a70d0d0a000000000000000000000000

接下来我们需要先了解一下PyCodeObject(Python代码的编译结果,PyCodeObject对象可以由虚拟机加载后直接运行,而pyc文件就是PyCodeObject对象在硬盘上的保存形式)

名称 大小 作用
Magic long 魔数,区分python不同版本的字节码
Mtime long 修改时间
Type_code byte 表示PyCodeObject对象
co_argcount/co_nlocals/co_stacksize/co_flags long PyCodeObject结构体各个域
Type_string byte 字符串
co_code size long PyCodeObject的co_code
co_code value bytes
Type_list byte 列表
co_consts size long 列表元素个数
Type_int byte co_consts[0]是一个整型
co_consts[0] long
Type_string byte co_consts[1]是一个字符串
co_consts[1] size long
co_consts[1] value bytes
Type_code byte co_consts[2]是PyCodeObject
co_consts[2]

也可以去直接看这篇文章:https://www.bilibili.com/video/BV1JL4y1p7Tt/?spm_id_from=333.999.0.0

直接反编译

一般使用uncompyle6或者Pycdc将pyc文件反编译成py文件

uncompyle6

下载:https://github.com/rocky/python-uncompyle6
命令:pip install uncompyle6
检测:uncompyle6 --version
注意:下载的uncompyle6的版本最好别高于所使用的python版本
使用命令:uncompyle6 -o output_file.py your_file.pyc(-o目标生成python文件名原pyc文件名)

pycdc

下载:https://github.com/extremecoders-re/decompyle-builds
使用命令:pycdc -o output_file.py your_file.pyc

在线的反编译网站:

https://tool.lu/pyc/
https://toolkk.com/tools/pyc-decomplie
https://www.lddgo.net/string/pyc-compile-decompile

pyc字节码

前言

  1. pyc字节码有点类似于汇编语言

  2. dis库:用于反汇编Python字节码,将python函数或代码对象的字节码指令序列转换成可读形式,显示每个字节码指令的操作码和操作数,以及相应行号和位置信息
    dis.dis函数作用:接受python函数对象或者代码作为参数;

  3. marshal:Python 标准库中的一个模块,提供了对 Python 对象进行序列化(转换为字节流)和反序列化(从字节流恢复为对象)功能

  4. 不同python版本的pyc文件头:
    python2的pyc文件前4个字节是固定的魔数(03 F3 0D 0A),紧接着后4个字节表示编译这个.pyc的解释器版本号
    python3的pyc文件前4个字节是固定的魔数(33 0D 0D 0A),紧接着两个字节时间戳表示.py文件最后修改时间,紧接着后4个字节源文件大小,最后是源文件名的字符串,以null字节结尾
    注意:Python3的pyc文件头部并非固定的 16 个字节,而是一个不确定的长度,至少是 12 个字节,加上源文件名字符串的长度

pyc转字节码

如何获取pyc字节码:

import dis,marshal
f=open("文件.pyc","rb").read()
code=marshal.loads(f[8:])
dis.dis(code)

不理解的可以对照官方文档搜索去还原字节码的含义,这里列举几个常见的:

名称 含义
LOAD_CONST 加载const 变量,比如数值,字符串等等, 一般用于传递给函数作为参数
LOAD_FAST 一般用于加载局部变量的值,也就是读取值,用于计算或者函数调用传传等
STORE_FAST 一般用于保存值到局部变量
CALL_FUNCTION CALL_FUNCTION n,其中 n 表示函数调用时传递的参数数量表示在此处调用了一个函数,并且传递了n个参数

例题

[羊城杯 2020]Bytecode
  4           0 LOAD_CONST               0 (3)
              3 LOAD_CONST               1 (37)
              6 LOAD_CONST               2 (72)
              9 LOAD_CONST               3 (9)
             12 LOAD_CONST               4 (6)
             15 LOAD_CONST               5 (132)
             18 BUILD_LIST               6
             21 STORE_NAME               0 (en)

  5          24 LOAD_CONST               6 (101)
             27 LOAD_CONST               7 (96)
             30 LOAD_CONST               8 (23)
             33 LOAD_CONST               9 (68)
             36 LOAD_CONST              10 (112)
             39 LOAD_CONST              11 (42)
             42 LOAD_CONST              12 (107)
             45 LOAD_CONST              13 (62)
             48 LOAD_CONST               7 (96)
             51 LOAD_CONST              14 (53)
             54 LOAD_CONST              15 (176)
             57 LOAD_CONST              16 (179)
             60 LOAD_CONST              17 (98)
             63 LOAD_CONST              14 (53)
             66 LOAD_CONST              18 (67)
             69 LOAD_CONST              19 (29)
             72 LOAD_CONST              20 (41)
             75 LOAD_CONST              21 (120)
             78 LOAD_CONST              22 (60)
             81 LOAD_CONST              23 (106)
             84 LOAD_CONST              24 (51)
             87 LOAD_CONST               6 (101)
             90 LOAD_CONST              25 (178)
             93 LOAD_CONST              26 (189)
             96 LOAD_CONST               6 (101)
             99 LOAD_CONST              27 (48)
            102 BUILD_LIST              26
            105 STORE_NAME               1 (output)

  7         108 LOAD_CONST              28 ('welcome to GWHT2020')
            111 PRINT_ITEM          
            112 PRINT_NEWLINE       

  9         113 LOAD_NAME                2 (raw_input)
            116 LOAD_CONST              29 ('please input your flag:')
            119 CALL_FUNCTION            1
            122 STORE_NAME               3 (flag)

 10         125 LOAD_NAME                3 (flag)
            128 STORE_NAME               4 (str)

 12         131 LOAD_NAME            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值