参考博客
buu-[RoarCTF2019]polyre(控制流平坦化,虚假控制流程)-CSDN博客
[RoarCTF2019]Polyre | bypass ollvm - 暖暖草果 - 博客园 (cnblogs.com)
buu-[RoarCTF2019]polyre(控制流平坦化,虚假控制流程)-CSDN博客
进来第一时间看见这个
我还以为是angr
跑了大半年,什么都没跑出来
后面发现这是控制流平坦化(没接触过)
https://github.com/cq674350529/deflat
这里去下载整个文件
放在unbuntu里面
python3 deflat.py -f ./polyre --addr 0x400620
命令行执行
中间等个一两分钟
就得到了这个文件
IDA打开
比之前好多了
这个有很多都是假
就是说根本不会运行
我们用IDA python简化(我不会,网上抄的脚本)
st = 0x0000000000400620 #main开始
end = 0x0000000000402144 #main结束def patch_nop(start,end):for i in range(start,end):ida_bytes.patch_byte(i, 0x90) #修改指定地址处的指令 0x90是最简单的1字节nopdef next_instr(addr):return addr+idc.get_item_size(addr) #获取指令或数据长度,这个函数的作用就是去往下一条指令addr = st
while(addr<end):next = next_instr(addr)if "ds:dword_603054" in GetDisasm(addr): #GetDisasm(addr)得到addr的反汇编语句while(True):addr = nextnext = next_instr(addr)if "jnz" in GetDisasm(addr):dest = idc.get_operand_value(addr, 0) #得到操作数,就是指令后的数ida_bytes.patch_byte(addr, 0xe9) #0xe9 jmp后面的四个字节是偏移ida_bytes.patch_byte(addr+5, 0x90) #nop第五个字节offset = dest - (addr + 5) #调整为正确的偏移地址 也就是相对偏移地址 - 当前指令后的地址ida_bytes.patch_dword(addr + 1, offset) #把地址赋值给jmp后print("patch bcf: 0x%x"%addr)addr = nextbreakelse:addr = next
怎么理解这个脚本,我感觉还是要等到再次遇见这种题,对比一下
运行后就可以得到一个正常的代码
我还是不会
()
wp说这是CRC32
ok,有借口了
保存一下脚本就算了吧
secret = [0xBC8FF26D43536296, 0x520100780530EE16, 0x4DC0B5EA935F08EC,0x342B90AFD853F450, 0x8B250EBCAA2C3681, 0x55759F81A2C68AE4]
key = 0xB0004B7679FA26B3
flag = ""
# 产生CRC32查表法所用的表
for s in secret:for i in range(64):sign = s & 1 # 数乘以二,必为偶数,再异或上奇数,得奇数 所以最后一位为1的数还原前为负。if sign == 1:s ^= keys //= 2# 防止负值除2,溢出为正值if sign == 1:s |= 0x8000000000000000 # 让数回到负数j = 0while j < 8:flag += chr(s & 0xFF) # &0xff可以将高的24位置为0,低8位保持原样。s >>= 8j += 1
print(flag)