diff options
Diffstat (limited to 'miasm2/arch/aarch64/sem.py')
| -rw-r--r-- | miasm2/arch/aarch64/sem.py | 123 |
1 files changed, 108 insertions, 15 deletions
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py index 800cc677..f23574e6 100644 --- a/miasm2/arch/aarch64/sem.py +++ b/miasm2/arch/aarch64/sem.py @@ -240,6 +240,13 @@ def ands(ir, instr, arg1, arg2, arg3): e.append(m2_expr.ExprAff(arg1, res)) return e, [] +def tst(ir, instr, arg1, arg2): + e = [] + arg2 = extend_arg(arg1, arg2) + res = arg1 & arg2 + e += update_flag_logic(res) + return e, [] + @sbuild.parse def lsl(arg1, arg2, arg3): @@ -383,10 +390,11 @@ def get_mem_access(mem): return addr, updt -def strb(ir, instr, arg1, arg2): + +def ldr(ir, instr, arg1, arg2): e = [] addr, updt = get_mem_access(arg2) - e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, 8), arg1[:8])) + e.append(m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, arg1.size))) if updt: e.append(updt) return e, [] @@ -402,7 +410,17 @@ def ldrb(ir, instr, arg1, arg2): return e, [] -def str(ir, instr, arg1, arg2): +def ldrh(ir, instr, arg1, arg2): + e = [] + addr, updt = get_mem_access(arg2) + e.append( + m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 16).zeroExtend(arg1.size))) + if updt: + e.append(updt) + return e, [] + + +def l_str(ir, instr, arg1, arg2): e = [] addr, updt = get_mem_access(arg2) e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, arg1.size), arg1)) @@ -411,10 +429,19 @@ def str(ir, instr, arg1, arg2): return e, [] -def ldr(ir, instr, arg1, arg2): +def strb(ir, instr, arg1, arg2): e = [] addr, updt = get_mem_access(arg2) - e.append(m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, arg1.size))) + e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, 8), arg1[:8])) + if updt: + e.append(updt) + return e, [] + + +def strh(ir, instr, arg1, arg2): + e = [] + addr, updt = get_mem_access(arg2) + e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, 16), arg1[:16])) if updt: e.append(updt) return e, [] @@ -475,6 +502,19 @@ def ubfm(ir, instr, arg1, arg2, arg3, arg4): e.append(m2_expr.ExprAff(arg1, res)) return e, [] +def bfm(ir, instr, arg1, arg2, arg3, arg4): + e = [] + rim, sim = int(arg3.arg), int(arg4.arg) + 1 + if sim > rim: + res = arg2[rim:sim] + e.append(m2_expr.ExprAff(arg1[:sim-rim], res)) + else: + shift_i = arg2.size - rim + shift = m2_expr.ExprInt_from(arg2, shift_i) + res = arg2[:sim] + e.append(m2_expr.ExprAff(arg1[shift_i:shift_i+sim], res)) + return e, [] + @sbuild.parse def madd(arg1, arg2, arg3, arg4): @@ -482,6 +522,11 @@ def madd(arg1, arg2, arg3, arg4): @sbuild.parse +def msub(arg1, arg2, arg3, arg4): + arg1 = arg4 - (arg2 * arg3) + + +@sbuild.parse def udiv(arg1, arg2, arg3): arg1 = m2_expr.ExprOp('udiv', arg2, arg3) @@ -623,11 +668,20 @@ def br(arg1): def nop(): """Do nothing""" + + +@sbuild.parse +def extr(arg1, arg2, arg3, arg4): + compose = m2_expr.ExprCompose([(arg2, 0, arg2.size), + (arg3, arg2.size, arg2.size+arg3.size)]) + arg1 = compose[int(arg4.arg):int(arg4.arg)+arg1.size] + mnemo_func = sbuild.functions mnemo_func.update({ 'and': and_l, 'adds': adds, 'ands': ands, + 'tst': tst, 'subs': subs, 'cmp': cmp, 'cmn': cmn, @@ -653,19 +707,31 @@ mnemo_func.update({ 'stp': stp, 'ldp': ldp, - 'str': str, 'ldr': ldr, + 'ldrb': ldrb, + 'ldrh': ldrh, - 'ldur': ldr, # XXXX CHECK + 'ldur': ldr, + 'ldurb': ldrb, + 'ldurh': ldrh, + + 'str': l_str, + 'strb': strb, + 'strh': strh, + + 'stur': l_str, + 'sturb': strb, + 'sturh': strh, 'ldrsw': ldrsw, - 'strb': strb, - 'ldrb': ldrb, + 'bfm': bfm, 'sbfm': sbfm, 'ubfm': ubfm, + 'extr': extr, + }) @@ -698,12 +764,9 @@ class ir_aarch64l(ir): args[-1].args[0], args[-1].args[-1][:8].zeroExtend(32)) instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) - # for i, expr in enumerate(instr_ir): - # instr_ir[i] = self.expraff_fix_regs_for_mode(expr) - # for b in extra_ir: - # for irs in b.irs: - # for i, expr in enumerate(irs): - # irs[i] = self.expraff_fix_regs_for_mode(expr) + self.mod_pc(instr, instr_ir, extra_ir) + instr_ir, extra_ir = self.del_dst_zr(instr, instr_ir, extra_ir) + return instr_ir, extra_ir def expr_fix_regs_for_mode(self, e): @@ -730,6 +793,36 @@ class ir_aarch64l(ir): irs[i] = self.expr_fix_regs_for_mode(e) irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst) + def mod_pc(self, instr, instr_ir, extra_ir): + "Replace PC by the instruction's offset" + cur_offset = m2_expr.ExprInt64(instr.offset) + for i, expr in enumerate(instr_ir): + dst, src = expr.dst, expr.src + if dst != self.pc: + dst = dst.replace_expr({self.pc: cur_offset}) + src = src.replace_expr({self.pc: cur_offset}) + instr_ir[i] = m2_expr.ExprAff(dst, src) + for b in extra_ir: + for irs in b.irs: + for i, expr in enumerate(irs): + dst, src = expr.dst, expr.src + if dst != self.pc: + dst = dst.replace_expr({self.pc: cur_offset}) + src = src.replace_expr({self.pc: cur_offset}) + irs[i] = m2_expr.ExprAff(dst, src) + + + def del_dst_zr(self, instr, instr_ir, extra_ir): + "Writes to zero register are discarded" + regs_to_fix = [WZR, XZR] + instr_ir = [expr for expr in instr_ir if expr.dst not in regs_to_fix] + + for b in extra_ir: + for i, irs in eunmerate(b.irs): + b.irs[i] = [expr for expr in irs if expr.dst not in regs_to_fix] + + return instr_ir, extra_ir + class ir_aarch64b(ir_aarch64l): |