一
开篇
二
正文
call_func_ret(0x1AE20, SP + 0xFFFFFFFFFFFFFF30)[0:32]?(@64[0x545B0] + 0xFFFFFFFFF775B348,@64[0x54558] + 0xFFFFFFFFF775B348)
src1 = sb.eval_expr(symbolic_pc.src1).arg
src2 = sb.eval_expr(symbolic_pc.src2).arg
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)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 add_block(asmcfg, offset):
block, next1 = mdis._dis_block(offset)
asmcfg.add_block(block)
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
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 retelse:
# 对于其他类型的表达式(如ExprId, ExprInt等),直接返回
return expr
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)
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])if step:
self.dump(mems=False)
'''
内存打印太多了
'''
# if assignblk.instr.offset == 0xca768:
# self.dump(ids=False)
print('_' * 80)if assignblk.instr.name == "BR":
symbolic_pc = self.symbols.symbols_id[assignblk.instr.args[0]]
if not symbolic_pc.is_cond():
pc = self.pc
if type(symbolic_pc.arg) == int:
next_pc = symbolic_pc.arg
self.write(f"{hex(pc)},{hex(next_pc)}\n")
else:
expr_list = replace_exprcond(symbolic_pc)
next_pc_list = []
for expr in expr_list:
simp_expr = self.eval_expr(self.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
self.write(f"{hex(pc)},{hex(src1)},{hex(src2)}\n")
elif len(next_pc_list) == 1:
next_pc = next_pc_list[0].arg
self.write(f"{hex(pc)},{hex(next_pc)}\n")
else:
raise Exception("you need check your code")
else:
pc = self.pc
src1 = int(str(self.eval_expr(symbolic_pc.src1)), 16)
src2 = int(str(self.eval_expr(symbolic_pc.src2)), 16)
self.write(f"{hex(pc)},{hex(src1)},{hex(src2)}\n")dst = self.eval_expr(self.lifter.IRDst)
return dst
import keystone
import capstone
import ida_bytes
import idc
from module.utils import MAGICKS = keystone.Ks(keystone.KS_ARCH_ARM64, keystone.KS_MODE_LITTLE_ENDIAN)
CS = capstone.Cs(capstone.CS_ARCH_ARM, capstone.CS_MODE_THUMB)NOP_BYTES = b'\x1f\x20\x03\xd5'
def handle_txt(path):
addr_dict = {}
f = open(path)
line = f.readline().replace("\n", "")
while line:
info = line.split(",")
if len(info) == 2:
patch_addr = info[0]
b_addr = info[1]
if patch_addr not in addr_dict.keys():
addr_dict[patch_addr] = [b_addr]
else:
addr_list = addr_dict[patch_addr]
if b_addr not in addr_list:
addr_dict[patch_addr].append(b_addr)
elif len(info) == 3:
patch_addr = info[0]
b_addr1 = info[1]
b_addr2 = info[2]
if patch_addr not in addr_dict.keys():
addr_dict[patch_addr] = [b_addr1, b_addr2]
else:
addr_list = addr_dict[patch_addr]
if b_addr1 not in addr_list:
addr_dict[patch_addr].append(b_addr1)
if b_addr2 not in addr_list:
addr_dict[patch_addr].append(b_addr1)
else:
raise Exception("check your code")
line = f.readline().replace("\n", "")
f.close()
return addr_dictdef get_b_const_bytes(ea, const):
'''
返回例如 ea: b 0x12334的指令
:param ea:
:param const:
:return:
'''
ea = int(ea, 16)
CODE = f"b {const[0]}"
encoding, count = KS.asm(CODE, ea)
return ea, bytes(encoding)def find_magic(ea):
for i in range(10):
asm = idc.GetDisasm(ea)
if asm.startswith(MAGIC):
info = asm.split(",")
cond = info[-1].replace(" ","").lower()
return ea, cond
ea = idc.prev_head(ea)
raise Exception("check your code:" + hex(ea))def get_bxx_const_bytes(ea, const_list):
ea = int(ea, 16)
patch_ea, cond = find_magic(ea)
code = f"b{cond} {const_list[0]}"
encoding, count = KS.asm(code, patch_ea)
ret = bytes(encoding)
code = f"b {const_list[1]}"
encoding, count = KS.asm(code, patch_ea + 4)
ret += bytes(encoding)
return patch_ea, retaddr_dict = handle_txt("./addr.txt")
for key in addr_dict.keys():
value = addr_dict[key]
if len(value) == 1:
ea, patch_bytes = get_b_const_bytes(key, value)
ida_bytes.patch_bytes(ea, patch_bytes)
else:
ea, patch_bytes = get_bxx_const_bytes(key, value)
ida_bytes.patch_bytes(ea, patch_bytes)
三
总结
看雪ID:大帅锅
https://bbs.kanxue.com/user-home-759174.htm
# 往期推荐
4、Chrome v8漏洞 CVE-2021-30632浅析
球分享
球点赞
球在看
点击阅读原文查看更多