深入浅出angr(三)
字数 736 2025-08-06 08:35:35

深入浅出angr(三):内存与寄存器操作详解

1. 内存直接存取基础

angr提供了对内存和寄存器进行直接操作的能力,主要通过SimMemory类实现。

1.1 固定地址变量初始化

对于.bss段等固定地址的变量,可以使用claripy直接进行初始化:

# 示例:初始化.bss段的变量u
u = claripy.BVS('u', 8)  # 8bit的符号变量
state.memory.store(0x804a021, u)  # 存储到固定地址

关键点

  • 需要声明add_options={"SYMBOLIC_WRITE_ADDRESSES"}选项
  • 使用state.memory.store(address, value)进行存储

2. 内存操作方法

angr提供了两种主要的内存操作方法:

2.1 直接存储方法

state.memory.store(address, value)

2.2 内存切片方法

# 设置DWORD值
state.mem[address].dword = value

# 设置WORD值
state.mem[address].word = value

支持的数据类型

  • dwordwordlongint
  • uint8_tuint32_t

3. 寄存器操作

3.1 直接寄存器访问

state.regs.esp = value  # 设置ESP寄存器

3.2 通过内存间接访问寄存器

# 示例:设置栈上传入的参数
state.mem[state.regs.esp:].dword = 0x401064  # 第一个参数
state.mem[state.regs.esp+4:].dword = 0x4010e4  # 第二个参数

4. 实战案例解析

4.1 案例1:flareon2015_2

Windows程序参数传递设置:

s = b.factory.blank_state(addr=0x401084)  # 跳过API调用
s.memory.store(s.regs.esp+12, s.solver.BVV(40, s.arch.bits))  # 参数3
s.mem[s.regs.esp+8:].dword = 0x402159  # 参数2
s.mem[s.regs.esp+4:].dword = 0x4010e4  # 参数1
s.mem[s.regs.esp:].dword = 0x401064  # 返回地址

4.2 案例2:angrbird (反调试绕过)

# 设置初始状态绕过反调试
state.regs.rbp = state.regs.rsp
state.mem[state.regs.rbp - 0x74].uint32_t = 0x40
state.mem[state.regs.rbp - 0x70].uint64_t = 0x1000
state.mem[state.regs.rbp - 0x68].uint64_t = 0x1008

4.3 案例3:google2016_unbreakable_1 (两种解法)

方法一:命令行输入约束

argv = claripy.BVS("argv", 0x43*8)
state = p.factory.entry_state(args=["./unbreakable", argv])
state.libc.buf_symbolic_bytes = 0x43 + 1  # 扩展符号缓冲区大小

# 添加可打印字符约束
for byt in argv.chop(8):
    state.add_constraints(state.solver.And(byt >= ord(' '), byt <= ord('~')))

方法二:直接内存注入

flag_chars = [state.solver.BVS('flag_%d' % i, 8) for i in range(0x43)]
for flag_chr in flag_chars:
    state.add_constraints(state.solver.And(flag_chr >= ord(' '), flag_chr <= ord('~')))
    
for i in range(0x43):
    state.memory.store(INPUT_ADDR+i, flag_chars[i])

5. 高级技巧

5.1 符号缓冲区大小调整

state.libc.buf_symbolic_bytes = 0x43 + 1  # 默认只有60字节

5.2 内存内容提取

found_state.solver.eval(found_state.memory.load(0x402159, 40), cast_to=bytes)

5.3 状态初始化选项

add_options={angr.options.LAZY_SOLVES}  # 避免探索不可满足路径

6. 总结

  • 使用state.memory.storestate.mem[]进行内存操作
  • 直接通过state.regs访问寄存器
  • 对于Windows程序,需要正确设置栈布局
  • 可通过调整起始地址绕过反调试
  • 对符号变量添加约束可提高求解效率
  • 必要时扩展符号缓冲区大小

掌握这些内存和寄存器操作技巧,可以更灵活地使用angr进行二进制分析。

深入浅出angr(三):内存与寄存器操作详解 1. 内存直接存取基础 angr提供了对内存和寄存器进行直接操作的能力,主要通过 SimMemory 类实现。 1.1 固定地址变量初始化 对于 .bss 段等固定地址的变量,可以使用 claripy 直接进行初始化: 关键点 : 需要声明 add_options={"SYMBOLIC_WRITE_ADDRESSES"} 选项 使用 state.memory.store(address, value) 进行存储 2. 内存操作方法 angr提供了两种主要的内存操作方法: 2.1 直接存储方法 2.2 内存切片方法 支持的数据类型 : dword 、 word 、 long 、 int uint8_t 、 uint32_t 等 3. 寄存器操作 3.1 直接寄存器访问 3.2 通过内存间接访问寄存器 4. 实战案例解析 4.1 案例1:flareon2015_ 2 Windows程序参数传递设置: 4.2 案例2:angrbird (反调试绕过) 4.3 案例3:google2016_ unbreakable_ 1 (两种解法) 方法一:命令行输入约束 方法二:直接内存注入 5. 高级技巧 5.1 符号缓冲区大小调整 5.2 内存内容提取 5.3 状态初始化选项 6. 总结 使用 state.memory.store 和 state.mem[] 进行内存操作 直接通过 state.regs 访问寄存器 对于Windows程序,需要正确设置栈布局 可通过调整起始地址绕过反调试 对符号变量添加约束可提高求解效率 必要时扩展符号缓冲区大小 掌握这些内存和寄存器操作技巧,可以更灵活地使用angr进行二进制分析。