def _translate_mvn(self, tb, instruction): oprnd1 = self._reg_acc_translator.read(tb, instruction.operands[1]) self._reg_acc_translator.write(tb, instruction.operands[0], negate_reg(tb, oprnd1)) if instruction.update_flags: self._flag_translator.update_flags_data_proc_other( tb, instruction.operands[1], oprnd1, None, negate_reg(tb, oprnd1))
def _translate_cbnz(self, tb, instruction): oprnd0 = self._reg_acc_translator.read(tb, instruction.operands[0]) arm_operand = instruction.operands[1] if isinstance(arm_operand, ArmImmediateOperand): target = ReilImmediateOperand(arm_operand.immediate << 8, self._pc.size + 8) elif isinstance(arm_operand, ArmRegisterOperand): target = ReilRegisterOperand(arm_operand.name, arm_operand.size) target = and_regs(tb, target, ReilImmediateOperand(0xFFFFFFFE, target.size)) tmp0 = tb.temporal(target.size + 8) tmp1 = tb.temporal(target.size + 8) tb.add(self._builder.gen_str(target, tmp0)) tb.add( self._builder.gen_bsh(tmp0, ReilImmediateOperand(8, target.size + 8), tmp1)) target = tmp1 else: raise Exception() neg_oprnd = negate_reg(tb, oprnd0) jump_if_zero(tb, neg_oprnd, target)
def _translate_cmovcc(self, tb, instruction, condition_code): # Move if condition (condition_code) is met. # Flags Affected # None. oprnd0 = self._reg_acc_translator.read(tb, instruction.operands[0]) oprnd1 = self._reg_acc_translator.read(tb, instruction.operands[1]) # NOTE: CMOV pseudocode (not its description) specifies that in 32-bit # registers, even if the condition is not met, the upper 32 bits of the # destination are set to zero (DEST[63:32] <- 0). So oprnd0 (dst) is # assigned to itself, in 32 bits that doesn't change anything, in 64 it # sets the upper 32 bits to zero. Then, if the condition is met, the mov # is performed and the previous assignment has no effect (oprnd0 <- # oprnd0.) tmp = tb.temporal(oprnd0.size) tb.add(self._builder.gen_str(oprnd0, tmp)) self._reg_acc_translator.write(tb, instruction.operands[0], tmp) cond_not_met = ReilLabel('cond_not_met') neg_cond = negate_reg(tb, X86ConditionCodeHelper.evaluate_cc(self._flags, tb, condition_code)) tb.add(self._builder.gen_jcc(neg_cond, cond_not_met)) self._reg_acc_translator.write(tb, instruction.operands[0], oprnd1) tb.add(cond_not_met) tb.add(self._builder.gen_nop())
def _translate_cmovcc(self, tb, instruction, condition_code): # Move if condition (condition_code) is met. # Flags Affected # None. oprnd0 = self._reg_acc_translator.read(tb, instruction.operands[0]) oprnd1 = self._reg_acc_translator.read(tb, instruction.operands[1]) # NOTE: CMOV pseudocode (not its description) specifies that in 32-bit # registers, even if the condition is not met, the upper 32 bits of the # destination are set to zero (DEST[63:32] <- 0). So oprnd0 (dst) is # assigned to itself, in 32 bits that doesn't change anything, in 64 it # sets the upper 32 bits to zero. Then, if the condition is met, the mov # is performed and the previous assignment has no effect (oprnd0 <- # oprnd0.) tmp = tb.temporal(oprnd0.size) tb.add(self._builder.gen_str(oprnd0, tmp)) self._reg_acc_translator.write(tb, instruction.operands[0], tmp) cond_not_met = ReilLabel('cond_not_met') neg_cond = negate_reg( tb, X86ConditionCodeHelper.evaluate_cc(self._flags, tb, condition_code)) tb.add(self._builder.gen_jcc(neg_cond, cond_not_met)) self._reg_acc_translator.write(tb, instruction.operands[0], oprnd1) tb.add(cond_not_met) tb.add(self._builder.gen_nop())
def _translate_setcc(self, tb, instruction, condition_code): # Set if condition (condition_code) is met. # Flags Affected # None. self._reg_acc_translator.write(tb, instruction.operands[0], tb.immediate(0, 1)) cond_not_met = ReilLabel('cond_not_met') neg_cond = negate_reg(tb, X86ConditionCodeHelper.evaluate_cc(self._flags, tb, condition_code)) tb.add(self._builder.gen_jcc(neg_cond, cond_not_met)) self._reg_acc_translator.write(tb, instruction.operands[0], tb.immediate(1, instruction.operands[0].size)) tb.add(cond_not_met) tb.add(self._builder.gen_nop())
def _translate_setcc(self, tb, instruction, condition_code): # Set if condition (condition_code) is met. # Flags Affected # None. self._reg_acc_translator.write(tb, instruction.operands[0], tb.immediate(0, 1)) cond_not_met = ReilLabel('cond_not_met') neg_cond = negate_reg( tb, X86ConditionCodeHelper.evaluate_cc(self._flags, tb, condition_code)) tb.add(self._builder.gen_jcc(neg_cond, cond_not_met)) self._reg_acc_translator.write( tb, instruction.operands[0], tb.immediate(1, instruction.operands[0].size)) tb.add(cond_not_met) tb.add(self._builder.gen_nop())
def _translate_loopcc(self, tb, instruction, condition_code): # Flags Affected # None. oprnd0 = self._reg_acc_translator.read(tb, instruction.operands[0]) counter_x86 = __get_loopcc_implicit_operand(self._arch_mode) counter = self._reg_acc_translator.read(tb, counter_x86) addr_oprnd = _translate_address(self, tb, oprnd0) end_addr = ReilImmediateOperand((instruction.address + instruction.size) << 8, self._arch_info.address_size + 8) tmp0 = tb.temporal(counter.size) counter_zero = tb.temporal(1) counter_not_zero = tb.temporal(1) branch_cond = tb.temporal(1) imm0 = tb.immediate(1, counter.size) imm1 = tb.immediate(1, 1) keep_looping_lbl = tb.label('keep_looping') neg_cond = negate_reg(tb, X86ConditionCodeHelper.evaluate_cc(self._flags, tb, condition_code)) tb.add(self._builder.gen_str(counter, tmp0)) tb.add(self._builder.gen_sub(tmp0, imm0, counter)) tb.add(self._builder.gen_bisz(counter, counter_zero)) tb.add(self._builder.gen_xor(counter_zero, imm1, counter_not_zero)) tb.add(self._builder.gen_and(counter_not_zero, neg_cond, branch_cond)) tb.add(self._builder.gen_jcc(branch_cond, keep_looping_lbl)) tb.add(self._builder.gen_jcc(imm0, end_addr)) # exit loop tb.add(keep_looping_lbl) tb.add(self._builder.gen_jcc(imm0, addr_oprnd))
def evaluate_g(flags, tb): # greater (ZF=0 and SF=OF) return and_regs(tb, negate_reg(tb, flags.zf), equal_regs(tb, flags.sf, flags.of))
def evaluate_hi(flags, tb): # HI: C set and Z clear return and_regs(tb, flags.cf, negate_reg(tb, flags.zf))
def evaluate_lt(flags, tb): # LT: N != V return negate_reg(tb, ArmConditionCodeHelper.evaluate_ge(flags, tb))
def evaluate_ne(flags, tb): # NE: Z clear return negate_reg(tb, flags.zf)
def evaluate_pl(flags, tb): # PL: N clear return negate_reg(tb, flags.nf)
def evaluate_a(flags, tb): # above (CF=0 and ZF=0) return and_regs(tb, negate_reg(tb, flags.cf), negate_reg(tb, flags.zf))
def evaluate_g(flags, tb): # greater (ZF=0 and SF=OF) return and_regs(tb, negate_reg(tb, flags.zf), equal_regs(tb, flags.sf, flags.of))
def evaluate_nle(flags, tb): # not less or equal (ZF=0 and SF=OF) return and_regs(tb, negate_reg(tb, flags.zf), equal_regs(tb, flags.sf, flags.of))
def evaluate_nz(flags, tb): # not zero (ZF=0) return negate_reg(tb, flags.zf)
def evaluate_a(flags, tb): # above (CF=0 and ZF=0) return and_regs(tb, negate_reg(tb, flags.cf), negate_reg(tb, flags.zf))
def evaluate_ae(flags, tb): # above or equal (CF=0) return negate_reg(tb, flags.cf)
def evaluate_po(flags, tb): # parity odd (PF=0) return negate_reg(tb, flags.pf)
def evaluate_nz(flags, tb): # not zero (ZF=0) return negate_reg(tb, flags.zf)
def evaluate_ns(flags, tb): # not sign (SF=0) return negate_reg(tb, flags.sf)
def evaluate_np(flags, tb): # not parity (PF=0) return negate_reg(tb, flags.pf)
def evaluate_no(flags, tb): # not overflow (OF=0) return negate_reg(tb, flags.of)
def evaluate_ns(flags, tb): # not sign (SF=0) return negate_reg(tb, flags.sf)
def evaluate_nc(flags, tb): # not carry (CF=0) return negate_reg(tb, flags.cf)
def evaluate_po(flags, tb): # parity odd (PF=0) return negate_reg(tb, flags.pf)
def evaluate_nbe(flags, tb): # not below or equal (CF=0 and ZF=0) return and_regs(tb, negate_reg(tb, flags.cf), negate_reg(tb, flags.zf))
def evaluate_ae(flags, tb): # above or equal (CF=0) return negate_reg(tb, flags.cf)
def evaluate_nb(flags, tb): # not below (CF=0) return negate_reg(tb, flags.cf)
def evaluate_nbe(flags, tb): # not below or equal (CF=0 and ZF=0) return and_regs(tb, negate_reg(tb, flags.cf), negate_reg(tb, flags.zf))
def evaluate_nc(flags, tb): # not carry (CF=0) return negate_reg(tb, flags.cf)
def evaluate_cc(flags, tb): # CC: C clear return negate_reg(tb, flags.cf)
def evaluate_nb(flags, tb): # not below (CF=0) return negate_reg(tb, flags.cf)
def evaluate_vc(flags, tb): # VC: V clear return negate_reg(tb, flags.vf)
def evaluate_nle(flags, tb): # not less or equal (ZF=0 and SF=OF) return and_regs(tb, negate_reg(tb, flags.zf), equal_regs(tb, flags.sf, flags.of))
def evaluate_ls(flags, tb): # LS: C clear or Z set return or_regs(tb, negate_reg(tb, flags.cf), flags.zf)
def evaluate_no(flags, tb): # not overflow (OF=0) return negate_reg(tb, flags.of)
def evaluate_gt(flags, tb): # GT: (Z == 0) and (N == V) return and_regs(tb, negate_reg(tb, flags.zf), ArmConditionCodeHelper.evaluate_ge(flags, tb))
def evaluate_np(flags, tb): # not parity (PF=0) return negate_reg(tb, flags.pf)
def evaluate_ne(flags, tb): # not equal (ZF=0) return negate_reg(tb, flags.zf)
def evaluate_ne(flags, tb): # not equal (ZF=0) return negate_reg(tb, flags.zf)