angr 系列教程(一)核心概念及模块解读
字数 1767 2025-08-24 20:49:31

angr 核心概念及模块详解

1. 概述

angr 是一个功能强大的二进制分析框架,用于执行符号执行、控制流分析、数据依赖分析等多种二进制分析任务。本教程将详细介绍 angr 的核心概念和主要模块。

2. 安装

安装 angr 可以通过 pip 直接安装:

pip install angr

3. 顶层接口

3.1 Project

Project 是 angr 模块的主类,用于包含一组二进制文件及其关系,并对其执行分析。

import angr
proj = angr.Project('/bin/true')

基本属性:

  • proj.arch - 架构信息
  • proj.entry - 入口地址
  • proj.filename - 文件名

3.2 Loader

CLE 模块用于将二进制文件载入虚拟地址空间,主要接口是 loader 类。

proj.loader  # 查看加载器信息
proj.loader.shared_objects  # 获取共享库信息
proj.loader.min_addr  # 最小地址
proj.loader.max_addr  # 最大地址

3.3 Factory

AngrObjectFactory,提供重要分析对象的接口:

# 获取基本块
block = proj.factory.block(proj.entry)
# 创建状态
state = proj.factory.entry_state()

3.4 States

SimState 对象代表程序的一个实例镜像,模拟执行某个时刻的状态。

state = proj.factory.entry_state()

访问寄存器和内存:

state.regs.rip  # 获取寄存器值
state.mem[proj.entry].int.resolved  # 读取内存

3.5 Simulation Managers

用于管理 state,执行运行、模拟等操作。

simgr = proj.factory.simulation_manager(state)
simgr.step()  # 执行一个基本块

3.6 Analyses

angr 内置分析方法:

proj.analyses.CFGFast()  # 快速控制流分析
proj.analyses.BackwardSlice()  # 后向切片分析

4. 核心模块详解

4.1 Loader 加载模块

4.1.1 已加载的对象

proj.loader.main_object  # 主对象
proj.loader.all_objects  # 所有对象

获取 ELF 信息:

obj.sections  # 分段信息
obj.plt  # PLT 表
obj.linked_base  # 预链接基址
obj.mapped_base  # 实际装载基址

4.1.2 符号和重定位

查找符号:

malloc = proj.loader.find_symbol('malloc')

符号地址:

  • .rebased_addr - 全局地址空间的地址
  • .linked_addr - 相对于预链接基址的地址
  • .relative_addr - 相对于对象基址的地址

4.1.3 加载选项

常用选项:

  • auto_load_libs - 是否自动加载依赖
  • skip_libs - 避免加载的库
  • except_missing_libs - 无法解析共享库时是否抛出异常
proj = angr.Project('/bin/true', load_options={"auto_load_libs": False})

4.1.4 pre-binary 选项

angr.Project('binary', 
    main_opts={'backend': 'blob', 'arch': 'i386'},
    lib_opts={'libc.so.6': {'backend': 'elf'}})

backend 类型:

  • elf - ELF 文件加载器
  • pe - PE 文件加载器
  • blob - 平面镜像加载器

4.2 符号函数摘要集

SimProcedures 用符号摘要替换库函数:

angr.SIM_PROCEDURES['libc']['malloc']  # malloc 摘要

4.3 Hooking

Hook 机制:

# 使用 SimProcedure 进行 hook
stub_func = angr.SIM_PROCEDURES['stubs']['ReturnUnconstrained']
proj.hook(0x10000, stub_func())

# 自定义 hook 函数
@proj.hook(0x20000, length=5)
def my_hook(state):
    state.regs.rax = 1

4.4 States 状态管理

4.4.1 状态预设

entry_state()  # 入口状态
blank_state()  # 空白状态
call_state()  # 函数调用状态
full_init_state()  # 完整初始化状态

4.4.2 访问寄存器

state.regs.rip  # 指令指针
state.regs.rax  # 通用寄存器

4.4.3 访问内存

# 使用 state.memory 接口
state.memory.store(0x4000, state.solver.BVV(0x1234, 128))
state.memory.load(0x4004, 6)  # 读取6字节

# 设置端序
state.memory.load(0x4000, 4, endness=archinfo.Endness.LE)

4.4.4 状态选项

# 添加选项
s.options.add(angr.options.LAZY_SOLVES)

# 创建时设置选项
s = proj.factory.entry_state(add_options={angr.options.LAZY_SOLVES})

4.4.5 状态插件

  1. history 插件:
for addr in state.history.bbl_addrs:  # 执行过的基本块地址
    print(hex(addr))
  1. callstack 插件:
state.callstack.func_addr  # 当前函数地址
state.callstack.ret_addr  # 返回地址

4.5 模拟管理器(Simulation Managers)

4.5.1 基本操作

simgr = proj.factory.simgr(state)
simgr.step()  # 执行一步
simgr.run()  # 执行到结束

4.5.2 stash 管理

特殊 stash:

  • active - 默认执行的状态
  • deadend - 无法继续执行的状态
  • pruned - 被剪枝的状态
  • unconstrained - 不受约束的状态

移动状态:

simgr.move(from_stash='deadended', to_stash='authenticated', 
          filter_func=lambda s: b'Welcome' in s.posix.dumps(1))

4.5.3 explore 探索

simgr.explore(find=lambda s: b"Congrats" in s.posix.dumps(1))
s = simgr.found[0]  # 获取找到的状态

4.5.4 explore 技术

# 使用 DFS 策略
tech = angr.exploration_techniques.DFS()
simgr.use_technique(tech)

其他技术:

  • LengthLimiter - 限制路径长度
  • Tracer - 跟踪动态轨迹
  • Oppologist - 处理不支持指令

4.6 求解引擎

4.6.1 位向量

# 创建具体值
one = state.solver.BVV(1, 64)  # 64位值1
# 创建符号变量
x = state.solver.BVS("x", 64)  # 64位符号变量x

4.6.2 符号约束

state.solver.add(x > y)  # 添加约束
state.solver.add(y > 2)
state.solver.add(10 > x)

4.6.3 约束求解

state.solver.eval(x)  # 求解一个可行解
state.solver.eval_one(x)  # 求解唯一解
state.solver.eval_upto(x, 5)  # 最多5个解
state.solver.min(x)  # 最小解
state.solver.max(x)  # 最大解

4.7 执行引擎

angr 使用多种引擎模拟代码执行:

  • failure engine - 处理不可继续状态
  • syscall engine - 处理系统调用
  • hook engine - 处理 hook
  • unicorn engine - 使用 Unicorn 引擎
  • VEX engine - 默认引擎

4.8 分析模块

4.8.1 CFG 分析

cfg = p.analyses.CFGFast()  # 快速静态分析
cfg = p.analyses.CFGEmulated()  # 动态模拟分析

4.8.2 后向切片

cfg = b.analyses.CFGEmulated(keep_state=True)
cdg = b.analyses.CDG(cfg)  # 控制依赖图
ddg = b.analyses.DDG(cfg)  # 数据依赖图
bs = b.analyses.BackwardSlice(cfg, cdg=cdg, ddg=ddg, targets=[(target_node, -1)])

4.8.3 函数识别

idfer = p.analyses.Identifier()
for addr, symbol in idfer.run():
    print(hex(addr), symbol)

5. 更新说明

已变更的接口:

  • SimuVEX 已被移除
  • Surveyors 已被移除
  • 使用 Simulation Manager 代替 Path Group
  • 求解引擎接口是 state.solver 而不是 state.se
  • CFGAccurate 更名为 CFGEmulated

6. 总结

angr 使用基本流程:

  1. 创建 project 并设置 state
  2. 新建符号量/位向量并在内存或其他地方设置
  3. 设置 Simulation Managers
  4. 运行,探索满足需要的路径
  5. 约束求解,获取执行结果

angr 是一个功能强大但复杂的框架,需要结合实践逐步掌握。建议参考官方文档和源码深入理解各模块的实现细节。

angr 核心概念及模块详解 1. 概述 angr 是一个功能强大的二进制分析框架,用于执行符号执行、控制流分析、数据依赖分析等多种二进制分析任务。本教程将详细介绍 angr 的核心概念和主要模块。 2. 安装 安装 angr 可以通过 pip 直接安装: 3. 顶层接口 3.1 Project Project 是 angr 模块的主类,用于包含一组二进制文件及其关系,并对其执行分析。 基本属性: proj.arch - 架构信息 proj.entry - 入口地址 proj.filename - 文件名 3.2 Loader CLE 模块用于将二进制文件载入虚拟地址空间,主要接口是 loader 类。 3.3 Factory AngrObjectFactory,提供重要分析对象的接口: 3.4 States SimState 对象代表程序的一个实例镜像,模拟执行某个时刻的状态。 访问寄存器和内存: 3.5 Simulation Managers 用于管理 state,执行运行、模拟等操作。 3.6 Analyses angr 内置分析方法: 4. 核心模块详解 4.1 Loader 加载模块 4.1.1 已加载的对象 获取 ELF 信息: 4.1.2 符号和重定位 查找符号: 符号地址: .rebased_addr - 全局地址空间的地址 .linked_addr - 相对于预链接基址的地址 .relative_addr - 相对于对象基址的地址 4.1.3 加载选项 常用选项: auto_load_libs - 是否自动加载依赖 skip_libs - 避免加载的库 except_missing_libs - 无法解析共享库时是否抛出异常 4.1.4 pre-binary 选项 backend 类型: elf - ELF 文件加载器 pe - PE 文件加载器 blob - 平面镜像加载器 4.2 符号函数摘要集 SimProcedures 用符号摘要替换库函数: 4.3 Hooking Hook 机制: 4.4 States 状态管理 4.4.1 状态预设 4.4.2 访问寄存器 4.4.3 访问内存 4.4.4 状态选项 4.4.5 状态插件 history 插件: callstack 插件: 4.5 模拟管理器(Simulation Managers) 4.5.1 基本操作 4.5.2 stash 管理 特殊 stash: active - 默认执行的状态 deadend - 无法继续执行的状态 pruned - 被剪枝的状态 unconstrained - 不受约束的状态 移动状态: 4.5.3 explore 探索 4.5.4 explore 技术 其他技术: LengthLimiter - 限制路径长度 Tracer - 跟踪动态轨迹 Oppologist - 处理不支持指令 4.6 求解引擎 4.6.1 位向量 4.6.2 符号约束 4.6.3 约束求解 4.7 执行引擎 angr 使用多种引擎模拟代码执行: failure engine - 处理不可继续状态 syscall engine - 处理系统调用 hook engine - 处理 hook unicorn engine - 使用 Unicorn 引擎 VEX engine - 默认引擎 4.8 分析模块 4.8.1 CFG 分析 4.8.2 后向切片 4.8.3 函数识别 5. 更新说明 已变更的接口: SimuVEX 已被移除 Surveyors 已被移除 使用 Simulation Manager 代替 Path Group 求解引擎接口是 state.solver 而不是 state.se CFGAccurate 更名为 CFGEmulated 6. 总结 angr 使用基本流程: 创建 project 并设置 state 新建符号量/位向量并在内存或其他地方设置 设置 Simulation Managers 运行,探索满足需要的路径 约束求解,获取执行结果 angr 是一个功能强大但复杂的框架,需要结合实践逐步掌握。建议参考官方文档和源码深入理解各模块的实现细节。