Ejemplo n.º 1
0
    def _calc_displacement(self):
        """
        Calculate the displacement offset of the operand's text.

        e.g:
            word ptr [rdi+rbx]

        :return int: calculated value
        """
        size = 8 if idc.__EA64__ else 4
        insn = idaapi.insn_t()
        idaapi.decode_insn(insn, self.ip)
        op = insn.ops[self.idx]
        offset = utils.signed(op.addr, utils.get_bits())
        scale = utils.sib_scale(op)
        base_reg = utils.x86_base_reg(insn, op)
        indx_reg = utils.x86_index_reg(insn, op)
        base_val = self._cpu_context.registers[utils.reg2str(base_reg, size)]
        indx_val = self._cpu_context.registers[utils.reg2str(
            indx_reg, size)] if indx_reg != -1 else 0
        result = base_val + indx_val * scale + offset
        logger.debug("calc_displacement :: Displacement {} -> {}".format(
            self.text, result))

        # Before returning, record the frame_id and stack_offset for this address.
        # (This can become useful information for retrieving the original location of a variable)
        frame_id = idc.get_frame_id(self.ip)
        stack_var = ida_frame.get_stkvar(insn, op, offset)
        if stack_var:
            _, stack_offset = stack_var
            self._cpu_context.stack_variables[result] = (frame_id,
                                                         stack_offset)

        return result
Ejemplo n.º 2
0
 def base(self):
     """The value of the base register if operand is a displacement."""
     if not self.has_phrase:
         return None
     base_reg = utils.reg2str(utils.x86_base_reg(self._insn, self._op))
     value = self._cpu_context.registers[base_reg]
     return utils.signed(value, utils.get_bits())
    def offset(self) -> Optional[int]:
        """The offset value if the operand is a displacement/phrase."""
        # [R1, R2]
        if self.type == ida_ua.o_phrase:
            second_reg = ida_arm.secreg(self._op)  # pulling the R2
            offset = self._cpu_context.registers[utils.reg2str(second_reg)]
            # We could also have a shift applied in the offset.
            #   [R1, R2, LSL #3]
            offset = self._calc_shift(offset)
            return utils.signed(offset)

        # [R1, #1]
        elif self.type == ida_ua.o_displ:
            return utils.signed(self._op.addr)

        return None
Ejemplo n.º 4
0
    def offset(self) -> Optional[int]:
        """
        The offset value if the operand is a displacement.

        e.g.
            [ebp+ecx*2+var_8] -> var_8
        """
        if not self.has_phrase:
            return None
        return utils.signed(self._op.addr)
Ejemplo n.º 5
0
 def index(self):
     """The value of the index register if operand is a displacement."""
     if not self.has_phrase:
         return None
     index_reg = utils.x86_index_reg(self._insn, self._op)
     if index_reg == -1:
         return 0
     index_reg = utils.reg2str(index_reg)
     value = self._cpu_context.registers[index_reg]
     return utils.signed(value, utils.get_bits())
Ejemplo n.º 6
0
    def base(self) -> Optional[int]:
        """
        The value of the base register if operand is a displacement.

        e.g.
            [ebp+ecx*2+var_8] -> ebp
        """
        if not self.has_phrase:
            return None
        base_reg = ida_intel.x86_base_reg(self._insn, self._op)
        value = self._cpu_context.registers[utils.reg2str(base_reg)]
        return utils.signed(value)
Ejemplo n.º 7
0
    def index(self) -> Optional[int]:
        """
        The value of the index register if operand is a displacement.

        e.g.
            [ebp+ecx*2+var_8] -> ecx
        """
        if not self.has_phrase:
            return None
        index_reg = ida_intel.x86_index_reg(self._insn, self._op)
        if index_reg == -1:
            return 0
        index_reg = utils.reg2str(index_reg)
        value = self._cpu_context.registers[index_reg]
        return utils.signed(value)
    def value(self):
        # Barrel shifter
        if self.type == ida_arm.o_shreg:
            value = self._cpu_context.registers[utils.reg2str(self._op.reg)]
            value = self._calc_shift(value)
            return value

        # Register list
        if self.type == ida_arm.o_reglist:
            return [
                self._cpu_context.registers[reg] for reg in self.register_list
            ]

        value = super().value

        # If a memory reference, the final value may be signed.
        if self.is_memory_reference and self.is_signed:
            value = utils.signed(value)

        return value
Ejemplo n.º 9
0
 def offset(self):
     """The offset value if the operand is a displacement."""
     if not self.has_phrase:
         return None
     return utils.signed(self._op.addr, utils.get_bits())
Ejemplo n.º 10
0
 def base(self) -> Optional[int]:
     """The value of the base register if operand is a displacement."""
     if not self.has_phrase:
         return None
     value = self._cpu_context.registers[utils.reg2str(self._op.reg)]
     return utils.signed(value)