about summary refs log tree commit diff stats
path: root/miasm2/arch
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/arch')
-rw-r--r--miasm2/arch/aarch64/arch.py13
-rw-r--r--miasm2/arch/aarch64/sem.py123
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):