def get_all_condition_addr(asm, magic="csel"):
condition_pc = []
for i in range(len(asm)):
ins = asm[i]
if ins.mnemonic == "br":
# 开始向上寻找
for j in range(i, 0, -1):
magic_ins = asm[j]
if magic_ins.mnemonic == magic.lower():
condition_pc.append(magic_ins.address)
break
if i - j > 10:
raise Exception("check this br" + str(ins))
return condition_pc
然后我们hook该条件位置,强行进行符号设置即可
def eval_updt_irblock(self, irb, step=False):
"""
Symbolic execution of the @irb on the current state
@irb: irbloc instance
@step: display intermediate steps
"""
for assignblk in irb:
self.pc = assignblk.instr.offset
self.instr = assignblk.instr
if step:
print(hex(assignblk.instr.offset) + ":", assignblk.instr)
print('Assignblk:')
print(assignblk)
print('_' * 80)
if assignblk.instr.offset in self.condition_pc:
# handle cesl
assigns_key = next(iter(assignblk._assigns.keys()))
assigns_value = assignblk._assigns[assigns_key]
assignblk._assigns[assigns_key] = replace_exprcond2(assigns_value)
self.eval_updt_assignblk(assignblk)
if assignblk.instr.offset in self.jmp_dict.keys():
self.symbols.symbols_id[ExprId("PC", 64)] = self.eval_expr(self.jmp_dict[assignblk.instr.offset])
self.symbols.symbols_id[ExprId("IRDst", 64)] = self.eval_expr(self.jmp_dict[assignblk.instr.offset])
def replace_exprcond2(expr):
if isinstance(expr, ExprCond):
# 对条件表达式的每个分支进行递归替换
src1 = replace_exprcond2(expr.src1)
src2 = replace_exprcond2(expr.src2)
# 生成两个新的表达式,分别代表条件成立或不成立的情况
return ExprCond(ExprId("SuperMan", 64), src1, src2)
elif isinstance(expr, ExprOp):
# 对ExprOp的每个参数进行递归替换
parts = [replace_exprcond2(arg) for arg in expr.args]
ret = ExprOp(expr.op, *parts)
return ret
else:
# 对于其他类型的表达式(如ExprId, ExprInt等),直接返回
return expr
2.5 递归进行分支树的遍历
这个应该是最简单的一块了直接展示代码
def handle(blocks, condition, jmp_dict):
print("[*]*****************************************************************")
sb, ircfg = init_machine(blocks, condition, jmp_dict)
try:
symbolic_pc = sb.run_at(ircfg, start_addr, step=True)
except Exception as e:
print("--------Exception---------")
print(e)
return
if symbolic_pc is not None and str(symbolic_pc) != "LR":
if not symbolic_pc.is_cond():
pc = sb.pc
if type(symbolic_pc.arg) == int:
next_pc = symbolic_pc.arg
# fp.write(f"{hex(pc)},{hex(next_pc)}\n")
if next_pc not in blocks and next_pc < end_addr:
blocks.append(next_pc)
handle(blocks, condition, jmp_dict)
else:
expr_list = replace_exprcond(symbolic_pc)
next_pc_list = []
for expr in expr_list:
simp_expr = sb.eval_expr(sb.expr_simp(expr))
if simp_expr not in next_pc_list:
next_pc_list.append(simp_expr)
if len(next_pc_list) == 2:
src1 = next_pc_list[0].arg
src2 = next_pc_list[1].arg
if src1 not in blocks and src1 < end_addr:
blocks.append(src1)
jmp_dict[pc] = next_pc_list[0]
handle(blocks, condition, jmp_dict)
if src2 not in blocks and src2 < end_addr:
blocks.append(src2)
jmp_dict[pc] = next_pc_list[1]
handle(blocks, condition, jmp_dict)
elif len(next_pc_list) == 1:
next_pc = next_pc_list[0].arg
if next_pc not in blocks and next_pc < end_addr:
blocks.append(next_pc)
handle(blocks, condition, jmp_dict)
else:
raise Exception("you need check your code")
else:
pc = sb.pc
src1 = sb.eval_expr(symbolic_pc.src1).arg
src2 = sb.eval_expr(symbolic_pc.src2).arg
# fp.write(f"{hex(pc)},{hex(src1)},{hex(src2)}\n")
if src1 not in blocks and src1 < end_addr:
blocks.append(src1)
jmp_dict[pc] = symbolic_pc.src1
handle(blocks, condition, jmp_dict)
if src2 not in blocks and src2 < end_addr:
blocks.append(src2)
jmp_dict[pc] = symbolic_pc.src2
handle(blocks, condition, jmp_dict)