如何在angr中执行指定函数、分析结构体及传递具体参数
2. 符号执行时获取结构体A的执行轨迹
通过将结构体成员设为符号变量,运行符号执行并记录路径与内存变化,可追踪结构体的执行轨迹:
import angr import claripy proj = angr.Project('test_fun', auto_load_libs=False) foo_addr = proj.loader.find_symbol('foo').rebased_addr # 创建空白状态,将程序计数器指向foo函数地址 state = proj.factory.blank_state(addr=foo_addr) # 为结构体分配栈内存 struct_addr = state.allocate_stack(8) # 定义结构体成员的符号变量 data1_sym = claripy.BVS('data1', 32) data2_sym = claripy.BVS('data2', 32) # 将符号变量写入内存 state.memory.store(struct_addr, data1_sym, endness=proj.arch.memory_endness) state.memory.store(struct_addr + 4, data2_sym, endness=proj.arch.memory_endness) # 设置foo函数的第一个参数(64位架构下为rdi寄存器)为结构体指针 state.regs.rdi = struct_addr # 创建模拟管理器并运行符号执行 simgr = proj.factory.simgr(state) simgr.run() # 遍历所有结束的路径 for path in simgr.deadended: # 打印执行的基本块地址轨迹 print("执行的基本块地址:") for bbl_addr in path.history.bbl_addrs: print(hex(bbl_addr)) # 获取执行后的结构体成员符号表达式 final_data1 = path.memory.load(struct_addr, 4, endness=proj.arch.memory_endness) final_data2 = path.memory.load(struct_addr + 4, 4, endness=proj.arch.memory_endness) print(f"执行后data1的符号表达式:{final_data1}") print(f"执行后data2的符号表达式:{final_data2}")
执行后会输出foo和bar函数的基本块地址,以及结构体成员的符号表达式data1_sym + 1和data2_sym + 1,清晰展示结构体的变化轨迹。
3. 将结构体a设置为独立内存段并获取执行结果
若希望将结构体放在独立内存段而非栈上,可使用map_region分配自定义内存区域:
import angr import claripy proj = angr.Project('test_fun', auto_load_libs=False) foo_addr = proj.loader.find_symbol('foo').rebased_addr state = proj.factory.entry_state() # 分配一个4KB的可读写内存段,起始地址设为0x10000000 seg_addr = 0x10000000 state.memory.map_region(seg_addr, 0x1000, permissions='rw-') # 结构体放在该内存段的起始位置 struct_addr = seg_addr # 初始化结构体成员 state.memory.store(struct_addr, state.solver.BVV(5, 32), endness=proj.arch.memory_endness) state.memory.store(struct_addr + 4, state.solver.BVV(10, 32), endness=proj.arch.memory_endness) # 调用foo函数 foo_callable = proj.factory.callable(foo_addr, base_state=state) foo_callable(struct_addr) # 读取执行后的结构体成员值 data1 = state.memory.load(struct_addr, 4, endness=proj.arch.memory_endness) data2 = state.memory.load(struct_addr + 4, 4, endness=proj.arch.memory_endness) print(f"内存段中结构体执行后:data1={state.solver.eval(data1)}, data2={state.solver.eval(data2)}")
执行后会输出内存段中结构体执行后:data1=6, data2=11,验证了自定义内存段中结构体的执行结果。
原代码问题说明
你之前的代码直接将BVS作为参数传递给foo,但foo需要的是指向结构体的指针,而非一个64位符号值。正确做法是先分配内存存储结构体(无论具体值还是符号值),再将该内存的地址作为参数传递。
内容的提问来源于stack exchange,提问作者damaoooo
相关产品推荐
相关产品推荐

