diff options
Diffstat (limited to 'miasm2/arch')
| -rw-r--r-- | miasm2/arch/aarch64/arch.py | 13 | ||||
| -rw-r--r-- | miasm2/arch/aarch64/sem.py | 123 |
2 files changed, 111 insertions, 25 deletions
diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py index b991fe81..a57b35bf 100644 --- a/miasm2/arch/aarch64/arch.py +++ b/miasm2/arch/aarch64/arch.py @@ -421,7 +421,7 @@ class instruction_aarch64(instruction): off = e.arg - self.offset if int(off % 4): raise ValueError('strange offset! %r' % off) - self.args[index] = m2_expr.ExprInt32(off) + self.args[index] = m2_expr.ExprInt64(off) @@ -929,17 +929,14 @@ class aarch64_gpreg_ext2(reg_noarg, m_arg): return self.parent.size.value def encode(self): - print "DECODE", self.expr if not isinstance(self.expr, m2_expr.ExprOp): return False arg0, arg1 = self.expr.args if not (isinstance(self.expr, m2_expr.ExprOp) and self.expr.op == 'segm'): return False - print 'OKI' if not arg0 in self.parent.rn.reg_info.expr: return False self.parent.rn.value = self.parent.rn.reg_info.expr.index(arg0) - print 'tt', arg0 is_reg = False self.parent.shift.value = 0 if isinstance(arg1, m2_expr.ExprId): @@ -950,14 +947,12 @@ class aarch64_gpreg_ext2(reg_noarg, m_arg): reg = arg1.args[0] else: return False - print 'ISR', is_reg if not (reg.size in gpregs_info and reg in gpregs_info[reg.size].expr): return False self.value = gpregs_info[reg.size].expr.index(reg) if is_reg: return True - print 'test int', arg1.args if not (isinstance(arg1.args[1], m2_expr.ExprInt)): return False if arg1.op not in EXT2_OP_INV: @@ -969,7 +964,6 @@ class aarch64_gpreg_ext2(reg_noarg, m_arg): if arg1.args[1].arg != self.get_size(): return False - print "RR", arg1.args[1].arg self.parent.shift.value = 1 @@ -1432,7 +1426,6 @@ class aarch64_b40(m_arg): size = self.parent.args[0].expr.size value = int(self.expr.arg) self.value = value & self.lmask - print 'TT', hex(value) if self.parent.sf.value is None: self.parent.sf.value = value >> self.l return True @@ -1626,7 +1619,7 @@ aarch64op("mvn", [sf, bs('01'), bs('01010'), shift, bs('1'), rm_sft, imm6, bs(' aarch64op("eor", [sf, bs('10'), bs('01010'), shift, bs('0'), rm_sft, imm6, rn, rd], [rd, rn, rm_sft]) aarch64op("eon", [sf, bs('10'), bs('01010'), shift, bs('1'), rm_sft, imm6, rn, rd], [rd, rn, rm_sft]) aarch64op("ands", [sf, bs('11'), bs('01010'), shift, bs('0'), rm_sft, imm6, rn, rd], [rd, rn, rm_sft]) -aarch64op("tst", [sf, bs('11'), bs('01010'), shift, bs('0'), rm_sft, imm6, rn, bs('11111')], [rn, rm_sft]) +aarch64op("tst", [sf, bs('11'), bs('01010'), shift, bs('0'), rm_sft, imm6, rn, bs('11111')], [rn, rm_sft], alias=True) aarch64op("bics", [sf, bs('11'), bs('01010'), shift, bs('1'), rm_sft, imm6, rn, rd], [rd, rn, rm_sft]) # move reg @@ -1776,7 +1769,7 @@ aarch64op("movk", [sf, bs('11'), bs('100101'), hw, imm16_hw_sc, rd], [rd, imm16_ ldstp_name = {'STP': 0b0, 'LDP': 0b1} bs_ldstp_name = bs_name(l=1, name=ldstp_name) aarch64op("ldstp", [sf, bs('0'), bs('101'), bs('0'), bs('0'), post_pre, bs('1'), bs_ldstp_name, simm7, rt2, rn64_deref_sf, rt], [rt, rt2, rn64_deref_sf]) -#aarch64op("ldstp", [sf, bs('0'), bs('101'), bs('0'), bs('0'), bs('1'), bs('0'), bs_ldstp_name, simm7, rt2, rn64_deref_sf, rt], [rt, rt2, rn64_deref_sf]) +aarch64op("ldstp", [sf, bs('0'), bs('101'), bs('0'), bs('0'), bs('1'), bs('0'), bs_ldstp_name, simm7, rt2, rn64_deref_sf, rt], [rt, rt2, rn64_deref_sf]) aarch64op("ldstp", [sdsize, bs('101'), bs('1'), bs('0'), post_pre, bs('1'), bs_ldstp_name, uimm7, sd2, rn64_deref_sd, sd1], [sd1, sd2, rn64_deref_sd]) aarch64op("ldstp", [sdsize, bs('101'), bs('1'), bs('0'), bs('1'), bs('0'), bs_ldstp_name, uimm7, sd2, rn64_deref_sd, sd1], [sd1, sd2, rn64_deref_sd]) 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): |