python pyc文件解析_pyc文件

2022-09-07 10:47:34 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

code object¶

在我们导入 python 脚本时在目录下会生成个一个相应的 pyc 文件,是pythoncodeobj的持久化储存形式,加速下一次的装载。

文件结构¶

pyc文件由三大部分组成

最开始4个字节是一个Maigc int, 标识此pyc的版本信息

接下来四个字节还是个int,是pyc产生的时间

序列化的 PyCodeObject,结构参照include/code.h,序列化方法python/marshal

pyc完整的文件解析可以参照

关于co_code

python3.6 以上参数永远占1字节,如果指令不带参数的话则以0x00代替,在运行过程中被解释器忽略,也是Stegosaurus技术原理;而低于python3.5的版本中指令不带参数的话却没有0x00填充

例题¶

首先尝试pycdc反编译失败

# Source Generated with Decompyle

# File: imgenc.pyc (Python 2.7)

import sys

import numpy as np

from scipy.misc import imread, imsave

def doit(input_file, output_file, f):

Unsupported opcode: STOP_CODE

img = imread(input_file, flatten = True)

img /= 255

size = img.shape[0]

# WARNING: Decompyle incomplete

注意到是python2.7,也就是说指令序列共占1字节或3字节(有参数无参数)

使用pcads得到

imgenc.pyc (Python 2.7)

67 STOP_CODE

68 STOP_CODE

69 BINARY_DIVIDE

70 JUMP_IF_TRUE_OR_POP 5

73 LOAD_CONST 3: 0

76 LOAD_CONST 3: 0

79 BINARY_DIVIDE

定位到出错的地方,观察发现 LOAD_CONST LOAD_CONST BINARY_DIVIDE STORE_FAST opcodes (64 03 00 64 03 00 15 7d 05 00)被破坏了,根据上下文线索修复后

00000120 64 04 00 6b 00 00 72 ce 00 64 03 00 64 03 00 15 |d..k..r..d..d…|

00000130 7d 05 00 64 03 00 64 03 00 15 7d 05 00 64 03 00 |}..d..d…}..d..|

00000140 64 03 00 15 7d 05 00 64 03 00 64 03 00 15 7d 05 |d…}..d..d…}.|

00000150 00 64 03 00 64 03 00 15 7d 05 00 64 03 00 64 03 |.d..d…}..d..d.|

00000160 00 15 7d 05 00 64 03 00 64 03 00 15 7d 05 00 64 |..}..d..d…}..d|

00000170 03 00 64 03 00 15 7d 05 00 64 03 00 64 03 00 15 |..d…}..d..d…|

00000180 7d 05 00 64 03 00 64 03 00 15 7d 05 00 64 03 00 |}..d..d…}..d..|

00000190 64 03 00 15 7d 05 00 64 03 00 64 03 00 15 7d 05 |d…}..d..d…}.|

000001a0 00 64 03 00 64 03 00 15 7d 05 00 64 03 00 64 03 |.d..d…}..d..d.|

000001b0 00 15 7d 05 00 64 03 00 64 03 00 15 7d 05 00 6e |..}..d..d…}..n|

接下来根据修复好的python源代码得到flag即可

延伸:

Tools¶

将python字节码转换为可读的python 源代码,包含了反汇编(pycads)和反编译(pycdc)两种工具

允许我们在Python字节码文件(pyc或pyo)中嵌入任意Payload。由于编码密度较低,因此我们嵌入Payload的过程既不会改变源代码的运行行为,也不会改变源文件的文件大小

原理是在python的字节码文件中,利用冗余空间,将完整的payload代码分散隐藏到这些零零碎碎的空间中.

评论

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/147972.html原文链接:https://javaforall.cn

0 人点赞