深入浅出angr(四)
字数 1064 2025-08-06 08:35:35

angr Hook技术深入解析

一、Hook基础概念

在二进制逆向工程中,Hook技术是一种非常重要的方法,它允许我们在程序执行过程中拦截和修改特定函数或指令的行为。angr框架提供了强大的Hook功能,可以将复杂的问题简单化处理。

二、基本Hook方法

1. 地址Hook

通过@proj.hook(address)装饰器可以直接Hook任意地址:

import angr
project = angr.Project("binary", auto_load_libs=False)

@project.hook(0x400844)
def print_flag(state):
    print("FLAG SHOULD BE:", state.posix.dumps(0))
    project.terminate_execution()

project.execute()

关键点:

  • project.execute()启动符号执行
  • project.terminate_execution()终止执行
  • 执行流程:初始化→Hook→execute→遇到terminate_execution结束

2. 符号表Hook

使用hook_symbol函数可以根据符号名Hook对应函数:

p.hook_symbol('ptrace', angr.SIM_PROCEDURES['stubs']['ReturnUnconstrained'](return_value=0))

关键点:

  • angr.SIM_PROCEDURES是angr实现的符号化函数字典
  • 格式:angr.SIM_PROCEDURES['模块名']['库函数名']()
  • 常用于绕过反调试等场景

三、Hook实际应用案例

案例1:绕过反调试(tumctf2016_zwiebel)

# 初始化支持自修改代码的项目
p = angr.Project("zwiebel", support_selfmodifying_code=True)

# Hook ptrace绕过反调试
p.hook_symbol('ptrace', angr.SIM_PROCEDURES['stubs']['ReturnUnconstrained'](return_value=0))

# 执行管理
state = p.factory.full_init_state(add_options=angr.options.unicorn)
sm = p.factory.simulation_manager(state)

# 分步执行
while sm.active:
    sm.run(n=20)
    # 内存优化处理
    if 'deadended' in sm.stashes and sm.deadended:
        sm.stashes['deadended'] = sm.deadended[-20:]
    if sm.errored:
        sm.errored = sm.errored[-20:]
    
flag = sm.deadended[-1].posix.dumps(0).split(b"\n")[0]

案例2:控制输入(defcon2016quals_baby-re)

import angr
import claripy

def main():
    proj = angr.Project('./baby-re', auto_load_libs=False)
    flag_chars = [claripy.BVS('flag_%d' % i, 32) for i in range(13)]
    
    # 自定义scanf函数
    class my_scanf(angr.SimProcedure):
        def run(self, fmt, ptr):
            self.state.mem[ptr].dword = flag_chars[self.state.globals['scanf_count']]
            self.state.globals['scanf_count'] += 1
    
    # Hook标准scanf函数
    proj.hook_symbol('__isoc99_scanf', my_scanf(), replace=True)
    
    sm = proj.factory.simulation_manager()
    sm.one_active.options.add(angr.options.LAZY_SOLVES)
    sm.one_active.globals['scanf_count'] = 0
    
    # 探索执行路径
    sm.explore(find=0x4028E9, avoid=0x402941)
    
    # 获取flag
    flag = ''.join(chr(sm.one_found.solver.eval(c)) for c in flag_chars)
    return flag

关键实现细节:

  1. 创建符号变量数组flag_chars
  2. 自定义my_scanf类继承SimProcedure
  3. 使用state.mem[ptr].dword存储符号变量
  4. 使用全局变量scanf_count跟踪输入位置
  5. replace=True确保完全替换原函数

四、高级Hook技巧

1. 自定义SimProcedure

可以创建自己的SimProcedure类来实现复杂Hook逻辑:

class MyHook(angr.SimProcedure):
    def run(self, arg1, arg2):
        # 自定义处理逻辑
        return self.state.solver.BVV(0, 32)

2. 内存操作Hook

通过Hook内存操作函数可以监控或修改内存访问:

def mem_write(state):
    addr = state.inspect.mem_write_address
    print(f"Writing to {addr}")

state.inspect.b('mem_write', when=angr.BP_BEFORE, action=mem_write)

3. 寄存器操作Hook

监控或修改寄存器值:

def reg_write(state):
    if state.inspect.reg_write_offset == state.arch.registers['rax'][0]:
        print("RAX is being written to")

state.inspect.b('reg_write', when=angr.BP_BEFORE, action=reg_write)

五、性能优化建议

  1. 限制状态数量:在处理大量状态时,只保留最近的状态
sm.stashes['deadended'] = sm.deadended[-20:]
  1. 使用LAZY_SOLVES:延迟求解约束以提高性能
state = proj.factory.entry_state(add_options={angr.options.LAZY_SOLVES})
  1. 选择性Hook:只Hook必要的函数,避免不必要的性能开销

六、常见问题解决方案

1. 处理自修改代码(SMC)

proj = angr.Project("binary", support_selfmodifying_code=True)

2. 绕过反调试

# 返回固定值绕过ptrace检测
p.hook_symbol('ptrace', angr.SIM_PROCEDURES['stubs']['ReturnUnconstrained'](return_value=0))

3. 处理复杂输入

通过Hook输入函数控制程序输入:

class my_scanf(angr.SimProcedure):
    def run(self, fmt, ptr):
        self.state.mem[ptr].dword = flag_chars[self.state.globals['count']]
        self.state.globals['count'] += 1

七、总结

angr的Hook技术为二进制分析提供了强大而灵活的工具,通过本文介绍的方法,您可以:

  1. 拦截和修改任意地址或函数的执行
  2. 自定义输入输出行为
  3. 绕过各种保护机制
  4. 监控程序运行时的内存和寄存器变化

掌握这些Hook技术将显著提高您在逆向工程和漏洞分析中的效率和能力。

angr Hook技术深入解析 一、Hook基础概念 在二进制逆向工程中,Hook技术是一种非常重要的方法,它允许我们在程序执行过程中拦截和修改特定函数或指令的行为。angr框架提供了强大的Hook功能,可以将复杂的问题简单化处理。 二、基本Hook方法 1. 地址Hook 通过 @proj.hook(address) 装饰器可以直接Hook任意地址: 关键点: project.execute() 启动符号执行 project.terminate_execution() 终止执行 执行流程:初始化→Hook→execute→遇到terminate_ execution结束 2. 符号表Hook 使用 hook_symbol 函数可以根据符号名Hook对应函数: 关键点: angr.SIM_PROCEDURES 是angr实现的符号化函数字典 格式: angr.SIM_PROCEDURES['模块名']['库函数名']() 常用于绕过反调试等场景 三、Hook实际应用案例 案例1:绕过反调试(tumctf2016_ zwiebel) 案例2:控制输入(defcon2016quals_ baby-re) 关键实现细节: 创建符号变量数组 flag_chars 自定义 my_scanf 类继承 SimProcedure 使用 state.mem[ptr].dword 存储符号变量 使用全局变量 scanf_count 跟踪输入位置 replace=True 确保完全替换原函数 四、高级Hook技巧 1. 自定义SimProcedure 可以创建自己的SimProcedure类来实现复杂Hook逻辑: 2. 内存操作Hook 通过Hook内存操作函数可以监控或修改内存访问: 3. 寄存器操作Hook 监控或修改寄存器值: 五、性能优化建议 限制状态数量 :在处理大量状态时,只保留最近的状态 使用LAZY_ SOLVES :延迟求解约束以提高性能 选择性Hook :只Hook必要的函数,避免不必要的性能开销 六、常见问题解决方案 1. 处理自修改代码(SMC) 2. 绕过反调试 3. 处理复杂输入 通过Hook输入函数控制程序输入: 七、总结 angr的Hook技术为二进制分析提供了强大而灵活的工具,通过本文介绍的方法,您可以: 拦截和修改任意地址或函数的执行 自定义输入输出行为 绕过各种保护机制 监控程序运行时的内存和寄存器变化 掌握这些Hook技术将显著提高您在逆向工程和漏洞分析中的效率和能力。