【Angr源码分析】0. 概述

参考链接:

Angr框架的总体架构包含如下几个部分:

  • 加载器—CLE:用于解析加载二进制文件,识别文件格式,从ELF/PE头中提取架构、代码段和数据段等程序信息

  • 架构数据库—Archinfo:根据程序架构信息,加载对应的CPU架构模型,包括寄存器、位宽、大小端等数据

  • 翻译器—PyVEX:将程序机器码翻译成中间语言VEX,VEX是开源二进制插桩工具Valgrind所使用的中间语言,angr需要处理不同的架构,所以它选择一种中间语言来进行它的分析

  • 模拟执行引擎—SimEngine:对VEX指令进行解释执行,支持具体值执行和符号值执行,执行时支持自定义函数Hook和断点,支持自定义路径探索策略

  • 约束求解器—Claripy:将符号执行中生成的路径约束转化成SMT公式,使用Z3进行求解

  • OS模拟器—SimOS:用于模拟程序与系统环境交互,提供了许多模拟的libc函数和系统调用,用户也可以自行编写Hook函数进行模拟


下面是一个从 https://github.com/jakespringer/angr_ctf 上下载的测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import angr
import sys


def main(argv):
path_to_binary = "./testcases/02_angr_find_condition"
project = angr.Project(path_to_binary)
initial_state = project.factory.entry_state(
add_options={angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY,
angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS}
)
simulation = project.factory.simgr(initial_state)

def is_successful(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Good Job.'.encode() in stdout_output # :boolean

def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return 'Try again.'.encode() in stdout_output # :boolean

simulation.explore(find=is_successful, avoid=should_abort)

if simulation.found:
solution_state = simulation.found[0]
print(solution_state.posix.dumps(sys.stdin.fileno()).decode())
else:
raise Exception('Could not find the solution')


if __name__ == '__main__':
main(sys.argv)

后面也会用这个例子分析。