diff --git a/miasm/arch/arm/arch.py b/miasm/arch/arm/arch.py index 7668cf0a4..497d6d689 100644 --- a/miasm/arch/arm/arch.py +++ b/miasm/arch/arm/arch.py @@ -181,6 +181,7 @@ def op_shift2expr(tokens): all_unaryop_shifts_t = literal_list(['RRX']).setParseAction(op_shift2expr) ror_shifts_t = literal_list(['ROR']).setParseAction(op_shift2expr) +shl_shifts_t = literal_list(['SHL']).setParseAction(op_shift2expr) allshifts_t_armt = literal_list( @@ -215,6 +216,8 @@ def cb_shift(tokens): )).setParseAction(cb_shift) +rot5_expr = shift_off + OP_LSL = Suppress("LSL") def cb_deref_reg_reg(tokens): @@ -1748,6 +1751,68 @@ def encode(self): self.parent.rot2.value = value // 8 return True + + +class arm_rm_rot5_lsl(arm_arg): + parser = rot5_expr + index_op = 0 + def decode(self, v): + expr = gpregs.expr[v] + shift_value = self.parent.rot5.value + if shift_value: + expr = ExprOp(allshifts[self.index_op], expr, ExprInt(shift_value, 32)) + self.expr = expr + return True + def encode(self): + if self.expr in gpregs.expr: + self.value = gpregs.expr.index(self.expr) + self.parent.rot5.value = 0 + elif (isinstance(self.expr, ExprOp) and + self.expr.op == allshifts[self.index_op]): + reg, value = self.expr.args + if reg not in gpregs.expr: + return False + self.value = gpregs.expr.index(reg) + if not isinstance(value, ExprInt): + return False + value = int(value) + if not 0 <= value < 32: + return False + self.parent.rot5.value = value + return True + +class arm_rm_rot5_asr(arm_rm_rot5_lsl): + parser = rot5_expr + index_op = 2 + def decode(self, v): + expr = gpregs.expr[v] + shift_value = self.parent.rot5.value + if shift_value == 0: + expr = ExprOp(allshifts[self.index_op], expr, ExprInt(32, 32)) + else: + expr = ExprOp(allshifts[self.index_op], expr, ExprInt(shift_value, 32)) + self.expr = expr + return True + def encode(self): + if (isinstance(self.expr, ExprOp) and + self.expr.op == allshifts[self.index_op]): + reg, value = self.expr.args + if reg not in gpregs.expr: + return False + self.value = gpregs.expr.index(reg) + if not isinstance(value, ExprInt): + return False + value = int(value) + if not 0 < value <= 32: + return False + if value == 32: + value = 0 + self.parent.rot5.value = value + else: + return False + return True + + class arm_gpreg_nopc(reg_noarg): reg_info = gpregs_nopc parser = reg_info.parser @@ -1778,6 +1843,10 @@ def decode(self, v): rm_rot2 = bs(l=4, cls=(arm_rm_rot2,), fname="rm") rot2 = bs(l=2, fname="rot2") +rm_rot5_lsl = bs(l=4, cls=(arm_rm_rot5_lsl,), fname="rm") +rm_rot5_asr = bs(l=4, cls=(arm_rm_rot5_asr,), fname="rm") +rot5 = bs(l=5, fname="rot5") + widthm1 = bs(l=5, cls=(arm_widthm1, m_arg)) lsb = bs(l=5, cls=(arm_imm, m_arg)) @@ -1796,6 +1865,9 @@ def decode(self, v): armop("uxtab", [bs('01101110'), rn_nopc, rd, rot2, bs('000111'), rm_rot2], [rd, rn_nopc, rm_rot2]) +armop("pkhbt", [bs('01101000'), rn, rd, rot5, bs('001'), rm_rot5_lsl], [rd, rn, rm_rot5_lsl]) +armop("pkhtb", [bs('01101000'), rn, rd, rot5, bs('101'), rm_rot5_asr], [rd, rn, rm_rot5_asr]) + # diff --git a/miasm/arch/arm/sem.py b/miasm/arch/arm/sem.py index bbffc05b2..981a50605 100644 --- a/miasm/arch/arm/sem.py +++ b/miasm/arch/arm/sem.py @@ -1349,6 +1349,35 @@ def adr(ir, instr, arg1, arg2): e.append(ExprAssign(arg1, (PC & ExprInt(0xfffffffc, 32)) + arg2)) return e, [] + +def pkhbt(ir, instr, arg1, arg2, arg3): + e = [] + e.append( + ExprAssign( + arg1, + ExprCompose( + arg2[:16], + arg3[16:] + ) + ) + ) + return e, [] + + +def pkhtb(ir, instr, arg1, arg2, arg3): + e = [] + e.append( + ExprAssign( + arg1, + ExprCompose( + arg3[:16], + arg2[16:] + ) + ) + ) + return e, [] + + COND_EQ = 0 COND_NE = 1 COND_CS = 2 @@ -1526,6 +1555,10 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir): 'smultt': smul, 'smulwt': smulw, 'smulwb': smulw, + + 'pkhtb': pkhtb, + 'pkhbt': pkhbt, + } mnemo_condm1 = {'adds': add, diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py index c8f2d433b..5aa619ea4 100644 --- a/test/arch/arm/arch.py +++ b/test/arch/arm/arch.py @@ -224,6 +224,16 @@ def u16swap(i): '7854e2e6'), + ('XXXXXXXX PKHBT R1, R2, R3 LSL 0x8', + '131482e6'), + ('XXXXXXXX PKHBT R1, R2, R3', + '131082e6'), + ('XXXXXXXX PKHTB R1, R2, R3 ASR 0x8', + '531482e6'), + ('XXXXXXXX PKHTB R1, R2, R3 ASR 0x20', + '531082e6'), + + ] ts = time.time()