angr项目中的Hook与SimProcedure技术详解

angr项目中的Hook与SimProcedure技术详解

【免费下载链接】angr A powerful and user-friendly binary analysis platform! 【免费下载链接】angr 项目地址: https://gitcode.com/gh_mirrors/an/angr

什么是Hook和SimProcedure

在angr符号执行引擎中,Hook和SimProcedure是两项强大的功能,它们允许开发者修改程序的执行行为。简单来说:

  • Hook:可以理解为在特定代码位置插入的"钩子",当执行流到达该位置时,会触发我们自定义的处理逻辑
  • SimProcedure:是angr提供的一种高级Hook机制,专门用于模拟或替换函数的行为

快速入门示例

让我们从一个简单例子开始,了解如何使用SimProcedure:

from angr import Project, SimProcedure

# 加载目标程序
project = Project('examples/fauxware/fauxware')

# 定义一个SimProcedure子类
class CustomMain(SimProcedure):
    def run(self, argc, argv):
        print(f'程序运行参数: argc={argc}, argv={argv}')
        return 0  # 返回0表示成功

# 将自定义过程挂钩到main函数
project.hook_symbol('main', CustomMain())

# 执行符号执行
simgr = project.factory.simulation_manager()
simgr.run()  # 执行直到没有活跃状态

这个例子中,我们创建了一个CustomMain类继承自SimProcedure,重写了run方法。当程序执行到main函数时,会执行我们的自定义逻辑而不是原始代码。

SimProcedure的工作原理

参数传递机制

SimProcedure最强大的特性之一是自动参数提取。当定义run方法时:

  1. 方法参数(argc, argv等)会自动从程序状态中提取
  2. 提取过程遵循当前架构的调用约定
  3. 返回值也会按照调用约定写回程序状态

实现上下文

在angr内部,SimProcedure通过以下方式管理:

  • project._sim_procedures字典维护地址到SimProcedure实例的映射
  • 当执行流到达挂钩地址时,会调用对应SimProcedure的execute方法
  • 每次执行都会创建新的SimProcedure实例以保证线程安全

高级特性

控制流操作

SimProcedure提供了多种控制流操作方法:

  • self.ret(value):从函数返回
  • self.jump(addr):跳转到指定地址
  • self.exit(code):终止程序
  • self.call(addr, args, continue_at):调用函数并指定返回后继续执行的方法
  • self.inline_call(procedure, *args):内联调用其他SimProcedure

条件分支

要实现条件分支,可以直接操作SimSuccessors对象:

# 创建状态副本
new_state = state.copy()

# 添加后继状态
self.successors.add_successor(
    new_state,        # 新状态
    target_addr,      # 目标地址
    condition,        # 条件表达式
    jumpkind          # 跳转类型
)

过程延续(Continuation)

SimProcedure延续允许在调用函数后恢复执行:

class ExampleProc(SimProcedure):
    IS_FUNCTION = True
    local_vars = ('counter',)
    
    def run(self):
        self.counter = 0
        self.call(target_func, (arg1, arg2), 'after_call')
    
    def after_call(self, result):
        self.counter += 1
        if self.counter < 10:
            self.call(target_func, (arg1, arg2), 'after_call')

关键点:

  1. 设置IS_FUNCTION = True
  2. 定义local_vars元组指定需要持久化的变量
  3. 使用self.call()指定返回后继续执行的方法

数据类型处理

在SimProcedure中处理数据时需要注意:

  • 参数会被包装为SimActionObject类型,这是对普通位向量的轻量级封装
  • 可以直接返回Python原生类型(如整数),它们会自动转换为适当大小的位向量
  • 处理浮点数时需要显式指定调用约定

静态分析支持

通过设置类变量可以帮助静态分析:

  • NO_RET:表示函数不会返回
  • ADDS_EXITS:表示函数会产生额外退出路径
  • IS_SYSCALL:标记为系统调用

如果设置了ADDS_EXITS,还需要实现static_exits()方法。

用户Hook简化接口

对于不需要完整SimProcedure功能的场景,可以使用更简单的用户Hook:

@project.hook(0x1234, length=5)
def simple_hook(state):
    state.regs.rax = 1  # 设置rax寄存器值
    # 自动跳过5字节继续执行

特点:

  • 不需要处理参数提取
  • 通过length参数控制执行流
  • 可以返回多个后继状态实现复杂控制流

符号挂钩实战

最常见的应用场景是替换库函数:

class DeterministicRand(SimProcedure):
    def run(self, sequence=None):
        idx = self.state.globals.get('rand_idx', 0) % len(sequence)
        result = sequence[idx]
        self.state.globals['rand_idx'] = idx + 1
        return result

# 挂钩rand函数,使其返回固定序列
project.hook_symbol('rand', DeterministicRand(sequence=[1,2,3,4,5]))

这个例子将rand()函数替换为返回预定义序列的版本,对于需要确定性执行的分析非常有用。

总结

angr的Hook和SimProcedure机制提供了强大的程序行为修改能力。通过本文介绍的技术,开发者可以:

  1. 轻松替换任意函数实现
  2. 精确控制程序执行流
  3. 构建复杂的分析逻辑
  4. 实现库函数模拟

无论是进行程序分析、程序验证还是符号执行,这些技术都是angr工具箱中不可或缺的部分。

【免费下载链接】angr A powerful and user-friendly binary analysis platform! 【免费下载链接】angr 项目地址: https://gitcode.com/gh_mirrors/an/angr

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值