angr学习笔记

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