【2022 - 春秋杯冬季赛】Reverse writeup
# 【2022 - 春秋杯冬季赛】Reverse writeup
算是近几次做的最简单的逆向了。
godeep
go的程序,main_convert是将输入转换成按字节存放bits的数组。
在转换后会进入一系列函数,根据bit数组判断调用哪个函数。
解题的时候通过字符串的交叉引用,找到打印right的函数
通过不断选择函数调用类型的交叉引用获取路径,卡一下两个函数的位置就能获取判断条件。
这里选用的是idc.GetDisasm(cmpaddr+0xE) == 'retn'
注意下idc.get_name_ea_simple
函数似乎不能从ida生成的函数符号获取地址,需要自己重命名一次。
import idc
import idaapi
endaddr = idc.get_name_ea_simple("End")
addr = idc.get_name_ea_simple("Win")
flag = ''
while True:
if addr == endaddr:
break
for xref in XrefsTo(addr, 0):
if addr == 0xffffffffffffffff:
print("Bad")
exit(0)
if XrefTypeName(xref.type) == "Code_Near_Call":
print(xref.type, XrefTypeName(xref.type), 'from', hex(xref.frm), 'to', hex(xref.to))
cmpaddr = xref.frm
addr = idaapi.get_func(xref.frm).start_ea
if idc.GetDisasm(cmpaddr+0xE) == idc.GetDisasm(0x9CAA5E):
flag = flag + '0'
else:
flag = flag + '1'
print(flag[::-1])
baby_transform
算法是快速傅里叶变换。出题的形式很Crypto,给了flag.enc来解密。
import numpy as np
import struct
with open(r'./flag.enc', 'rb') as f:
d_str = f.read()
d_len = len(d_str) // 8
data = struct.unpack(d_len * 'd', d_str)
flag = np.ndarray([],dtype=np.complex128)
for i in range(0,len(data),2):
flag = np.append(flag, complex(data[i+1],data[i]))
flag = np.delete(flag,0)
a = np.fft.ifft(flag)
print(''.join([chr(round(x)) for x in a.real]))
baby_python
纯粹充数的题,非常基础的python字节码。
data = [204,141,44,236,111,140,140,76,44,172,7,7,39,165,70,7,39,166,165,134,134,140,204,165,7,39,230,140,165,70,44,172,102,6,140,204,230,230,76,198,38,175]
flag = [chr((x << 3 | x >> 5) & 0xff )for x in data]
print(''.join(flag))