Z3中是否存在与C++ map等效、支持Z3表达式为键值的容器?
Z3实现键值均为符号表达式的内存映射方案
核心结论
Z3内置的数组理论本身就完全匹配你的需求,不需要额外构造自定义map结构。Z3数组没有固定长度限制,索引和值都可以是任意符号表达式,原生支持Select/Store操作,完全适配汇编内存读写的建模场景。
具体实现步骤
- 定义内存类型
根据你的目标架构位宽构造对应的数组排序,以32位ARM架构为例,地址和存储值均为32位位向量,Python API实现如下:
- 定义内存类型
from z3 import * ctx = Context() # 定义地址、值的排序 addr_sort = BitVecSort(32, ctx) value_sort = BitVecSort(32, ctx) # 构造数组类型:地址作为索引,存储值作为映射结果 mem_sort = ArraySort(addr_sort, value_sort) # 初始化初始内存状态 mem = Const('mem_initial', mem_sort, ctx)
- 实现内存读写操作
- 读内存(对应ldr指令):直接调用
Select方法,索引可以是任意Z3符号表达式,完全符合你要求的调用形式
对应你的示例代码:
# 初始r2寄存器符号 r2_old = BitVec('r2_old', 32, ctx) # 计算ldr的地址:r2_old + 13 load_addr = r2_old + BitVecVal(13, 32, ctx) # 读内存得到r2的新值 r2_new = Select(mem, load_addr) # 执行后续add r1, r2, 3 r1 = r2_new + BitVecVal(3, 32, ctx)- 写内存(对应str指令):调用
Store方法得到更新后的内存状态,遵循SSA形式更新,和寄存器的建模逻辑一致
示例:
# 执行str r1, [sp, #8] store_addr = sp + BitVecVal(8, 32, ctx) # 得到更新后的新内存对象,后续操作均使用该新对象 mem_new = Store(mem, store_addr, r1)- 自定义映射的替代方案:未解释函数
如果你需要更高的灵活性(比如自定义对齐规则、内存区域约束),可以用未解释函数模拟映射:
- 自定义映射的替代方案:未解释函数
# 定义输入为地址、输出为存储值的未解释函数 mem_uf = Function('mem_uf', addr_sort, value_sort, ctx) # 读内存直接调用函数 r2_new = mem_uf(r2_old + 13) # 可以自定义添加约束,比如指定某段地址的值为固定常量 a = Const('a', addr_sort) s = Solver(ctx=ctx) s.add(ForAll([a], If(And(a >= 0x80000000, a < 0x80010000), mem_uf(a) == BitVecVal(0, 32), True)))
内容的提问来源于stack exchange,提问作者hany erfan
相关产品推荐
相关产品推荐

