angr进阶(5)内存操作

angr也可以将符号写在内存里,控制内存中的值,结合任意位置开始有奇效,但就是慢sym-write

1     p = angr.Project('./issue', load_options={"auto_load_libs": False})
2     state = p.factory.entry_state(add_options={angr.options.SYMBOLIC_WRITE_ADDRESSES})
3     u = claripy.BVS("u", 8)
4     state.memory.store(0x804a021, u)

 因为最近好像要开始0ctf了,再分析一道0ctf的题目,0ctf_trace

这个题目两个文件,一个.bin的看起来像是二进制文件,其中trace是MIPS指令集。上万行,头大。

首先通过grep jal可以得到所调用的所有函数的起始地址,接着grep jr r31得到函数的结束地址

trace中总共三个函数,有一个函数运行了100多次,虽然每个函数还是很长就是了

然后分析函数得到Flag的地址,程序首先对常量字符初始化了,然后加上了一串未知字符串,就是flag

 1 #!/usr/bin/env python2
 2 
 3 from __future__ import print_function
 4 import struct
 5 import angr
 6 
 7 MAIN_START = 0x4009d4
 8 MAIN_END = 0x00400c18
 9 
10 FLAG_LOCATION = 0x400D80
11 FLAG_PTR_LOCATION = 0x410EA0
12 
13 def load_trace():
14     res = []
15     delay_slots = set()
16     with open("./trace_8339a701aae26588966ad9efa0815a0a.log") as f:
17         for line in f:
18             if line.startswith('[INFO]'):
19                 addr = int(line[6:6+8], 16)
20 
21                 res.append(addr)
22 
23                 if ("move r1, r1" in line):
24                     delay_slots.add(addr)
25 
26     return res, delay_slots
27 
28 def main():
29     trace_log, delay_slots = load_trace()
30 
31     project = angr.Project("./data.bin", load_options={
32         'main_opts': {
33             'backend': 'blob',
34             'base_addr': 0x400770,
35             'arch': 'mipsel',
36         },
37     })
38 
39     state = project.factory.blank_state(addr=MAIN_START)
40     state.memory.store(FLAG_LOCATION, state.solver.BVS("flag", 8*32))
41     state.memory.store(FLAG_PTR_LOCATION, struct.pack("<I", FLAG_LOCATION))
42 
43     sm = project.factory.simulation_manager(state)
44     choices = [state]
45 
46     print("Tracing...")
47     for i, addr in enumerate(trace_log):
48         if addr in delay_slots:
49             continue
50 
51         for s in choices:
52             if s.addr == addr:
53                 break
54 
55         else:
56             raise ValueError("couldn't advance to %08x, line %d" % (addr, i+1))
57 
58         if s.addr == MAIN_END:
59             break
60 
61         if s.addr + 4 in delay_slots:
62             choices = project.factory.successors(s, num_inst=2).successors
63         else:
64             choices = project.factory.successors(s, num_inst=1).successors
65 
66     state = s
67 
68     print("Running solver...")
69 
70     solution = state.solver.eval(state.memory.load(FLAG_LOCATION, 32), cast_to=bytes).rstrip(b'').decode('ascii')
71     print("The flag is", solution)
72 
73     return solution
74 
75 def test():
76     assert main() == "0ctf{tr135m1k5l96551s9l5r}"
77 
78 if __name__ == "__main__":
79     main()
原文地址:https://www.cnblogs.com/61355ing/p/10525437.html