pyc文件结构
文件格式:
03f3 0d0a magic表示python的版本信息,此处03f30d0a是python2.7的标识;
6206 b160 时间戳,编译的时间信息
63 Blockde的开头
后4字节0000 0000 :argcount参数个数
后4字节0000 0000: nlocals局部变量个数
后4字节1b00 0000: stacksize栈空间大小
后4字节4000 0000:flags
73:类型string
3501 0000 字节长度(小端模式)
之后即为opcode
参考:PYC文件格式分析
其中目前我们比较关注的是字节长度,因为如果修改了其源代码,则长度必随之改变,因此这个数值也要随之修改,并且注意他是小端序存储。
源码混肴:
可以反编译出来,但是反编译出来很难使人们看懂。比较著名的有AST语法树。
pyc混肴
对于可执行的pyc,我们可以使用pycdump工具进行转储,查看其字节码形式。
将相应pyc文件保存在pycdump文件夹下,运行 python dump.py test.py
这是一种直接跳转混肴:
前三个jump运行逻辑上没有问题,但是会导致反编译失败 其字节码为 0x71 0x**
我们可以插入许多这样类似的指令,任意的不合法指令(其实随机数据都可以),然后用一些 JUMP 指令去跳过这样的不合法指令,造成混肴的目的,并且不影响程序正常运行。
处理办法:我们将这三条指令删除,并且将code_string的长度减少6个字节。也就是上面的
3501 0000 字节长度(小端模式),然后保存。最后再使用uncompyle6反编译,进行分析。
重叠指令:
# 例1 Python单重叠指令
0 JUMP_ABSOLUTE [71 05 00] 5
3 PRINT_ITEM [47 -- --]
4 LOAD_CONST [64 64 01] 356
7 STOP_CODE [00 -- --]
# 例1 实际执行
0 JUMP_ABSOLUTE [71 05 00] 5
5 LOAD_CONST [64 01 00] 1
这里跳转到了第三行,但是没有执行第三行的所有代码,而是把他的操作数看成代码执行。
uncompyle6 -o total.py .\test.pyc
参考: