bad_python
从题目可以知道这是一道python逆向
附件是.pyc文件
.pyc文件
.pyc 文件是 Python 将 .py 源代码编译后生成的字节码文件,主要有以下几个特点和作用:
- 加速执行:直接执行 .pyc 字节码,可以跳过反复编译的步骤,直接运行已编译好的字节码,从而加快执行速度;
- 隐藏源代码:包含编译后的字节码,而不会包含原始的源代码,可对源代码进行加密或者保护源代码不被用户访问;
- 跨平台运行:不同平台编译的 .pyc 字节码文件可在其它平台上运行,可以将 Python 程序打包成 .pyc 文件在不同系统上分发和运行;
- 冗余检查:Python解释器会根据 .py 文件的修改时间来检查 .pyc 文件是否过期;如果 .py 文件没有改动,.pyc
- 可以直接重用,避免重复编译; 支持单文件运行:可以只发布 .pyc文件让用户直接运行,而不需要随附源代码,一定程度上保护代码;
- 节省内存:只加载 .pyc 文件可以减少内存开销,因为不需要加载源码。
总体来说,.pyc 文件提高了执行效率、跨平台性,并提供了代码保护和优化内存使用等好处,所以 Python 自动使用 .pyc 字节码文件,但开发者仍可以访问和修改原始源代码。
但是,使用反编译工具(uncompyle6)可以将其反编译为 .py 即 Python 程序源代码:
uncompyle6安装教程
1、使用 pip 安装该反编译包(默认已有 python 环境):由于我的电脑python和pip环境变量有问题,所以我的cmd语法不能使用pip,而是得用python -m pip
python -m pip install uncompyle
2、进入 .pyc 文件所在的文件夹,反编译单个文件:
uncompyle6 test.pyc > test.py
3、反编译目录中的所有 .pyc 文件:
import glob
import uncompyle6
pycs = glob.glob('./transforms/*.pyc')
for pyc in pycs:
uncompyle6.main.decompile_file(pyc, outstream=open(pyc.replace('.pyc', '.py'), 'w'))
结果发现无法返编译成功,通过题目名字知道肯定是哪损坏了

附件名字是pyre.cpython-36.pyc,所以应该是用python3.6编译的,说实话,一开始没反应过来
用二进制编辑工具打开这个附件,我这里用的是winhex

第一行这么多0肯定不对,查一下正常3.6python编译后的pyc文件头部

复制正常文件的头到pyre-cpython-36.pyc,就可以成功编译了。得到如下代码
# uncompyle6 version 3.9.0
# Python bytecode version base 3.6 (3379)
# Decompiled from: Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 12:30:02) [MSC v.1900 64 bit (AMD64)]
# Embedded file name: pyre.py
# Compiled at: 2024-01-05 10:16:56
# Size of source mod 2**32: 52 bytes
from ctypes import *
from Crypto.Util.number import bytes_to_long
from Crypto.Util.number import long_to_bytes
def encrypt(v, k):
v0 = c_uint32(v[0])
v1 = c_uint32(v[1])
sum1 = c_uint32(0)
delta = 195935983
for i in range(32):
v0.value += (v1.value << 4 ^ v1.value >> 7) + v1.value ^ sum1.value + k[sum1.value & 3]
sum1.value += delta
v1.value += (v0.value << 4 ^ v0.value >> 7) + v0.value ^ sum1.value + k[sum1.value >> 9 & 3]
return (
v0.value, v1.value)
if __name__ == '__main__':
flag = input('please input your flag:')
k = [255, 187, 51, 68]
if len(flag) != 32:
print('wrong!')
exit(-1)
a = []
for i in range(0, 32, 8):
v1 = bytes_to_long(bytes(flag[i:i + 4], 'ascii'))
v2 = bytes_to_long(bytes(flag[i + 4:i + 8], 'ascii'))
a += encrypt([v1, v2], k)
enc = [
'4006073346', '2582197823', '2235293281', '558171287', '2425328816',
'1715140098', '986348143', '1948615354']
for i in range(8):
if enc[i] != a[i]:
print('wrong!')
exit(-1)
print('flag is flag{%s}' % flag)
喂给chatgpt,获得脚本
from ctypes import c_uint32
from Crypto.Util.number import long_to_bytes
def decrypt(v, k):
v0 = c_uint32(v[0])
v1 = c_uint32(v[1])
sum1 = c_uint32(195935983 * 32) # 反向 TEA,需要初始化 sum
delta = 195935983
for i in range(32):
v1.value -= ((v0.value << 4) ^ (v0.value >> 7)) + v0.value ^ sum1.value + k[(sum1.value >> 9) & 3]
sum1.value -= delta
v0.value -= ((v1.value << 4) ^ (v1.value >> 7)) + v1.value ^ sum1.value + k[sum1.value & 3]
return (v0.value, v1.value)
# 已知加密后的数据
enc = [4006073346, 2582197823, 2235293281, 558171287, 2425328816, 1715140098, 986348143, 1948615354]
k = [255, 187, 51, 68]
flag = b''
for i in range(0, len(enc), 2):
v1, v2 = decrypt([enc[i], enc[i+1]], k)
flag += long_to_bytes(v1) + long_to_bytes(v2)
print("flag is:", flag.decode())

1万+

被折叠的 条评论
为什么被折叠?



