【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))