angr也可以将符号写在内存里,控制内存中的值,结合任意位置开始有奇效,但就是慢sym-write
p = angr.Project('./issue', load_options={"auto_load_libs": False})
state = p.factory.entry_state(add_options={angr.options.SYMBOLIC_WRITE_ADDRESSES})
u = claripy.BVS("u", 8)
state.memory.store(0x804a021, u)
因为最近好像要开始0ctf了,再分析一道0ctf的题目,0ctf_trace
这个题目两个文件,一个.bin的看起来像是二进制文件,其中trace是MIPS指令集。上万行,头大。
首先通过grep jal可以得到所调用的所有函数的起始地址,接着grep jr r31得到函数的结束地址
trace中总共三个函数,有一个函数运行了100多次,虽然每个函数还是很长就是了
然后分析函数得到Flag的地址,程序首先对常量字符初始化了,然后加上了一串未知字符串,就是flag
#!/usr/bin/env python2 from __future__ import print_function
import struct
import angr MAIN_START = 0x4009d4
MAIN_END = 0x00400c18 FLAG_LOCATION = 0x400D80
FLAG_PTR_LOCATION = 0x410EA0 def load_trace():
res = []
delay_slots = set()
with open("./trace_8339a701aae26588966ad9efa0815a0a.log") as f:
for line in f:
if line.startswith('[INFO]'):
addr = int(line[6:6+8], 16) res.append(addr) if ("move r1, r1" in line):
delay_slots.add(addr) return res, delay_slots def main():
trace_log, delay_slots = load_trace() project = angr.Project("./data.bin", load_options={
'main_opts': {
'backend': 'blob',
'base_addr': 0x400770,
'arch': 'mipsel',
},
}) state = project.factory.blank_state(addr=MAIN_START)
state.memory.store(FLAG_LOCATION, state.solver.BVS("flag", 8*32))
state.memory.store(FLAG_PTR_LOCATION, struct.pack("<I", FLAG_LOCATION)) sm = project.factory.simulation_manager(state)
choices = [state] print("Tracing...")
for i, addr in enumerate(trace_log):
if addr in delay_slots:
continue for s in choices:
if s.addr == addr:
break else:
raise ValueError("couldn't advance to %08x, line %d" % (addr, i+1)) if s.addr == MAIN_END:
break if s.addr + 4 in delay_slots:
choices = project.factory.successors(s, num_inst=2).successors
else:
choices = project.factory.successors(s, num_inst=1).successors state = s print("Running solver...") solution = state.solver.eval(state.memory.load(FLAG_LOCATION, 32), cast_to=bytes).rstrip(b'\0').decode('ascii')
print("The flag is", solution) return solution def test():
assert main() == "0ctf{tr135m1k5l96551s9l5r}" if __name__ == "__main__":
main()