有幸跟着主队打比赛,逆向就出了一题。虽说比较简单,但是还是写了很久,记录一下吧。
还是得感谢队友的帮助…
Run of the Mill
一大堆位操作
首先是想到了符号执行,会发现路径爆炸。
换个思路:逆序运行。
Method 1
直接使用IDA的伪码会有异代码,如下
v4 = _m_pxor((__m64)0x82A766A24751FB61ui64, _m_pxor((__m64)0x9823CC120C3B05F0ui64, *(__m64 *)flag)); *(__m64 *)flag = v4; *(_WORD *)&flag[4] = __ROR2__(WORD2(v4.m64_u64), 3);
等同于
*(__m64 *)flag = _m_pxor((__m64)0x82A766A24751FB61ui64, _m_pxor((__m64)0x9823CC120C3B05F0ui64, *(__m64 *)flag)); *(_WORD *)&flag[4] = __ROR2__(*(_WORD *)&flag[4], 3);
如下
*(_WORD *)&flag[27] = (*(_DWORD *)&flag[26] >> 8) ^ 0x2F6E;
等同于
*(_WORD *)&flag[27] = (*(_WORD *)&flag[27] ^ 0x2F6E;
还有一些其他的语句需要修改。
脚本进行初步逆序,手动修改部分代码后,g++编译运行
这里文件过大就不展示了,上一个附件
Method 2
ida python脚本分析指令(队伍里其他师傅写的,不要脸的拿来抄了)
import re import idautils enc_ins = [] def match_offset(asm_text): r1 = re.search(r"flag\+([0-9A-F]*)h", asm_text) r2 = re.search(r"flag\+([0-9A-F])", asm_text) r3 = re.search(r"flag", asm_text) if r1: return r1.groups(0)[0] elif r2: return r2.groups(0)[0] elif r3: return "offset_is_zero" else: return 0 def match_imm(asm_text): re2 = re.search(r", (([0-9A-F]*)h|[0-9A-F])", asm_text) if re2: return re2.groups(0)[0] for ins in idautils.FuncItems(0x401000): asm_text = GetDisasm(ins) if 'flag' in asm_text: flag = "" for s in ['add', 'sub', 'pxor', 'xor', 'rol', 'ror']: if s in asm_text: flag = s break if flag == 'pxor': offset = match_offset(asm_text) if offset == "offset_is_zero": enc_ins.append((hex(ins), "pxor", '0')) continue if offset: enc_ins.append((hex(ins), "pxor", offset)) continue if flag in ['add', 'sub', 'xor', 'rol', 'ror']: offset = match_offset(asm_text) if offset == "offset_is_zero": imm = match_imm(asm_text) if imm: if 'dword' in asm_text: l = 4 enc_ins.append((hex(ins), flag, '0', imm, l)) continue elif 'word' in asm_text: l = 2 enc_ins.append((hex(ins), flag, '0', imm, l)) continue else: l = 1 enc_ins.append((hex(ins), flag, '0', imm, l)) continue if offset: imm = match_imm(asm_text) if imm: if 'dword' in asm_text: l = 4 enc_ins.append((hex(ins), flag, offset, imm, l)) continue elif 'word' in asm_text: l = 2 enc_ins.append((hex(ins), flag, offset, imm, l)) continue else: l = 1 enc_ins.append((hex(ins), flag, offset, imm, l)) continue print("!!", hex(ins), asm_text) print("*" * 999) for i in enc_ins: print(i, end=', ')
获取pxor key
import re import idautils import binascii import struct def read_xmm_reg(name): rv = idaapi.regval_t() idaapi.get_reg_val(name, rv) return (struct.unpack('Q', rv.bytes())[0]) rmap = {} while ida_dbg.step_over(): wait_for_next_event(WFNE_ANY, -1) rip = idc.get_reg_value("rip") if rip > 0x411810: break asm_text = GetDisasm(rip) if 'pxor' in asm_text: rmap[rip] = read_xmm_reg('mm0') print(hex(rip), hex(rmap[rip])) print(rmap)
写个脚本逆出代码后,相同办法g++编译运行
脚本及代码参下附件
发表回复