Esempio n. 1
0
 def __add__(self, addend):
     from peachpy.x86_64.registers import GeneralPurposeRegister64, GeneralPurposeRegister32
     from peachpy.util import is_int, is_sint32
     if is_int(addend):
         if not is_sint32(addend):
             raise ValueError("The addend value (%d) is not representable as a signed 32-bit integer" % addend)
         return MemoryAddress(self.base, self.index, self.scale, self.displacement + addend)
     elif isinstance(addend, (GeneralPurposeRegister64, GeneralPurposeRegister32)):
         if self.base is not None:
             raise TypeError("Can not add a general-purpose register to a memory operand with existing base")
         if self.index.size != addend.size:
             raise TypeError("Index (%s) and addend (%s) registers have different size" %
                             (str(self.index), str(addend)))
         return MemoryAddress(addend, self.index, self.scale, self.displacement)
     elif isinstance(addend, MemoryAddress):
         if self.base is not None and addend.base is not None:
             raise ValueError("Can not add memory address: both address expressions use base registers")
         if self.index is not None and addend.index is not None:
             raise ValueError("Can not add memory address: both address expressions use index registers")
         sum_base = self.base if self.base is not None else addend.base
         (sum_index, sum_scale) = (self.index, self.scale) \
             if self.index is not None else (addend.index, addend.scale)
         return MemoryAddress(sum_base, sum_index, sum_scale, self.displacement + addend.displacement)
     else:
         raise TypeError("Can not add %s: unsupported addend type" % str(addend))
Esempio n. 2
0
 def _encode_label_branch(self,
                          address,
                          label_address=None,
                          long_encoding=False):
     if label_address is None:
         encodings = [encode(0) for (_, encode) in self.encodings]
     else:
         encodings = []
         from peachpy.x86_64.encoding import Flags
         from peachpy.util import is_sint8, is_sint32
         for (flags, encode) in self.encodings:
             offset = label_address - (address + len(encode(0)))
             if flags & Flags.Rel8Label != 0 and is_sint8(offset) or \
                     flags & Flags.Rel32Label != 0 and is_sint32(offset):
                 encodings.append(encode(offset))
         if not encodings:
             raise ValueError("Can not encode offset to label %s" %
                              self.label_name)
     assert len(
         encodings
     ) <= 2, "At most 2 encodings expected for branch instructions with immediate code offset"
     if len(encodings) == 1:
         return True, encodings[0]
     else:
         if long_encoding:
             return True, max(encodings, key=len)
         else:
             return False, min(encodings, key=len)
Esempio n. 3
0
    def __init__(self, base=None, index=None, scale=None, displacement=0):
        from peachpy.x86_64.registers import GeneralPurposeRegister64, GeneralPurposeRegister32
        from peachpy.util import is_int, is_sint32

        # Check individual arguments
        if base is not None and not isinstance(base, (GeneralPurposeRegister32, GeneralPurposeRegister64)):
            raise TypeError("Base register must be a 32- or 64-bit general-purpose register")
        if index is not None and not isinstance(index, (GeneralPurposeRegister32, GeneralPurposeRegister64)):
            raise TypeError("Index register must be a 32- or 64-bit general-purpose register")
        if scale is not None and not is_int(scale):
            raise TypeError("Scale must be an integer")
        if scale is not None and int(scale) not in {1, 2, 4, 8}:
            raise TypeError("Scale must be 1, 2, 4, or 8")
        if not is_sint32(displacement):
            raise ValueError("Displacement value (%s) is not representable as a signed 32-bit integer" % str(displacement))

        # Check relations of arguments
        if scale is not None and index is None or scale is None and index is not None:
            raise ValueError("Either both of neither of scale and index must be defined")
        if base is not None and index is not None and base.size != index.size:
            raise TypeError("Base (%s) and index (%s) registers have different size" % (str(base), str(index)))
        if index is None and base is None:
            raise ValueError("Either base or index * scale must be specified")

        self.base = base
        self.index = index
        self.scale = None if scale is None else int(scale)
        self.displacement = int(displacement)
Esempio n. 4
0
    def __init__(self, base=None, index=None, scale=None, displacement=0):
        from peachpy.x86_64.registers import GeneralPurposeRegister64, \
            XMMRegister, YMMRegister, ZMMRegister, MaskedRegister
        from peachpy.util import is_int, is_sint32

        # Check individual arguments
        if base is not None and not isinstance(base, GeneralPurposeRegister64):
            raise TypeError("Base register must be a 64-bit general-purpose register")
        if index is not None and \
            not isinstance(index, (GeneralPurposeRegister64, XMMRegister, YMMRegister, ZMMRegister)) and not \
            (isinstance(index, MaskedRegister) and
                isinstance(index.register, (XMMRegister, YMMRegister, ZMMRegister)) and
                not index.mask.is_zeroing):
            raise TypeError("Index register must be a 64-bit general-purpose register or an XMM/YMM/ZMM register")
        if scale is not None and not is_int(scale):
            raise TypeError("Scale must be an integer")
        if scale is not None and int(scale) not in {1, 2, 4, 8}:
            raise TypeError("Scale must be 1, 2, 4, or 8")
        if not is_sint32(displacement):
            raise ValueError("Displacement value (%s) is not representable as a signed 32-bit integer" %
                             str(displacement))

        # Check relations of arguments
        if scale is not None and index is None or scale is None and index is not None:
            raise ValueError("Either both of neither of scale and index must be defined")
        if index is None and base is None:
            raise ValueError("Either base or index * scale must be specified")

        self.base = base
        self.index = index
        self.scale = None if scale is None else int(scale)
        self.displacement = int(displacement)
Esempio n. 5
0
    def _encode_label_branch(self, address, label_address=None, long_encoding=False):
        if label_address is None:
            encodings = [encode(0) for (_, encode) in self.encodings]
        else:
            encodings = []
            from peachpy.x86_64.encoding import Flags
            from peachpy.util import is_sint8, is_sint32

            for (flags, encode) in self.encodings:
                offset = label_address - (address + len(encode(0)))
                if (
                    flags & Flags.Rel8Label != 0
                    and is_sint8(offset)
                    or flags & Flags.Rel32Label != 0
                    and is_sint32(offset)
                ):
                    encodings.append(encode(offset))
            if not encodings:
                raise ValueError("Can not encode offset to label %s" % self.label_name)
        assert len(encodings) <= 2, "At most 2 encodings expected for branch instructions with immediate code offset"
        if len(encodings) == 1:
            return True, encodings[0]
        else:
            if long_encoding:
                return True, max(encodings, key=len)
            else:
                return False, min(encodings, key=len)
Esempio n. 6
0
    def __init__(self, base=None, index=None, scale=None, displacement=0):
        from peachpy.x86_64.registers import GeneralPurposeRegister64, \
            XMMRegister, YMMRegister, ZMMRegister, MaskedRegister
        from peachpy.util import is_int, is_sint32

        # Check individual arguments
        if base is not None and not isinstance(base, GeneralPurposeRegister64):
            raise TypeError("Base register must be a 64-bit general-purpose register")
        if index is not None and \
            not isinstance(index, (GeneralPurposeRegister64, XMMRegister, YMMRegister, ZMMRegister)) and not \
            (isinstance(index, MaskedRegister) and
                isinstance(index.register, (XMMRegister, YMMRegister, ZMMRegister)) and
                not index.mask.is_zeroing):
            raise TypeError("Index register must be a 64-bit general-purpose register or an XMM/YMM/ZMM register")
        if scale is not None and not is_int(scale):
            raise TypeError("Scale must be an integer")
        if scale is not None and int(scale) not in {1, 2, 4, 8}:
            raise TypeError("Scale must be 1, 2, 4, or 8")
        if not is_sint32(displacement):
            raise ValueError("Displacement value (%s) is not representable as a signed 32-bit integer" %
                             str(displacement))

        # Check relations of arguments
        if scale is not None and index is None or scale is None and index is not None:
            raise ValueError("Either both of neither of scale and index must be defined")
        if index is None and base is None:
            raise ValueError("Either base or index * scale must be specified")

        self.base = base
        self.index = index
        self.scale = None if scale is None else int(scale)
        self.displacement = int(displacement)
Esempio n. 7
0
 def __sub__(self, minuend):
     from peachpy.util import is_int, is_sint32
     if is_int(minuend):
         if not is_sint32(-minuend):
             raise ValueError("The addend value (%d) is not representable as a signed 32-bit integer" % minuend)
         return MemoryAddress(self.base, self.index, self.scale, self.displacement - minuend)
     else:
         raise TypeError("Can not add %s: unsupported addend type" % str(minuend))
Esempio n. 8
0
    def __init__(self, type, offset, size, symbol, is_pc_relative=False):
        from peachpy.util import is_sint32
        assert is_sint32(offset)
        assert offset >= 0
        assert size in [1, 2, 4, 8]
        from peachpy.formats.macho.section import Section
        assert symbol is None or isinstance(symbol, (Section, Symbol))

        self.type = type
        self.offset = offset
        self.size = size
        self.symbol = symbol
        self.is_pc_relative = is_pc_relative
Esempio n. 9
0
def is_rel32(operand):
    from peachpy.util import is_sint32
    return isinstance(operand, RIPRelativeOffset) and is_sint32(operand.offset)
Esempio n. 10
0
def is_rel32(operand):
    from peachpy.util import is_sint32
    return isinstance(operand, RIPRelativeOffset) and is_sint32(operand.offset)