angr入门
angr是一个多架构的二进制分析频台,具备对二进制文件动态符号执行能力和多种静态分析能力
何为符号执行
符号执行就是在运行程序时,用符号来替代真实值。符号执行相较于真实值执行的优点在于,当使用真实值执行程序时,我们能够遍历的程序路径只有一条, 而使用符号进行执行时,由于符号是可变的,我们就可以利用这一特性,尽可能的将程序的每一条路径遍历,这样的话,必定存在至少一条能够输出正确结果的分支, 每一条分支的结果都可以表示为一个离散关系式,使用约束求解引擎即可分析出正确结果。
例如
1 2 3 4 5 6
| int a; cin >> a; int b = a * 2; if(b == 114514){ cout << "flag"; }
|
这里可以整合为 x * 2 == 114514
利用angr求解
- 装载二进制文件到分析平台
- 转换二进制文件为中间语言(IR)
- 分析
装载二进制文件
angr的二进制装载组件是CLE,它负责装载二进制对象
1 2 3 4 5 6 7 8
| import angr proj = angr.Project("/bin/true")
print(b.entry)
print(b.loder.min_addr(), b.loader.max_addr())
print(b.filename)
|
中间语言(IR)
angr选择VEX作为中间语言来统一各个平台不同的代码
angr_ctf做题笔记
00_angr_find
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import angr
proj = angr.Project("./00_angr_find", auto_load_libs = False) flag_path = 0x08048678 false_path = 0x08048666 state = proj.factory.entry_state() simg = proj.factory.simgr(state)
simg.explore(find = flag_path, avoid = false_path)
if simg.found: ans = simg.found[0] sol = ans.posix.dumps(0) print(sol.decode("utf-8")) else: raise Exception('Could not find the solution')
|
01_angr_avoid
1 2 3 4 5 6 7 8 9 10 11 12 13
| import angr
proj = angr.Project("./01_angr_avoid", auto_load_libs=False) state = proj.factory.entry_state() simg = proj.factory.simgr(state) flag_path = 0x80485E0 false_path = 0x80485A8 simg.explore(find = flag_path, avoid = false_path)
if simg.found: ans = simg.found[0] sol = ans.posix.dumps(0) print(sol.decode("utf-8"))
|
02_angr_find_condition
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import angr
proj = angr.Project("./02_angr_find_condition", auto_load_libs=False) state = proj.factory.entry_state() simg = proj.factory.simgr(state)
def flag_path(state): return b"Good Job." in state.posix.dumps(1)
def false_path(state): return b"Try again." in state.posix.dumps(1)
print(simg.explore(find = flag_path, avoid = false_path))
if simg.found: ans = simg.found[0] sol = ans.posix.dumps(0) print(sol.decode("utf-8"))
|
03_angr_symbolic_registers