Beispiel #1
0
    def Interpret(self):
        """For a :class:`.ModRM16` object whose :attr:`.MOD` field is not ``3`` 
		(i.e., the :class:`.ModRM16` object specifies a memory location and not a 
		register), examine the fields of the object and return a 4-tuple describing
		the 16-bit memory expression.
		
		:rtype: (:class:`~.R16Elt`, :class:`~.R16Elt`, integer, integer)
		:returns: A 4-tuple containing a base register, index register, integer
			displacement, and displacement size in bytes.  The register components
			may be ``None``; the displacement may be ``0`` or ``None``.
		:raises: assertion failure if :attr:`MOD` is ``3``.
		"""

        # We're interpreting memory expressions here, not registers.
        assert (self.MOD != 3)

        # Return a 4-tuple:  (basereg,indexreg,disp,dispsize)
        # m.Disp and m.DispSize will be set identically for any case, so we pull
        # that logic out into this helper function.
        def ModRM16WithDisp(basereg, indexreg):
            return (basereg, indexreg, self.Disp, self.DispSize)

        # Handle the special case of an offset specified directly, i.e., with no
        # base or index register.
        if self.MOD == 0 and self.RM == 6:
            # Hint: call ModRM16WithDisp.  What should the parameters be?
            raise ExerciseError("ModRM16::Interpret: Offset-only special case")

        # Otherwise, the base and index registers are specified by m.RM.

        # Hint: ultimately, you will return the result of calling ModRM16WithDisp.
        # You will need to use the proper registers as specified by m.RM.
        # Take a look at the declaration of the data item named modrm_16.
        raise ExerciseError("ModRM16::Interpret: General case")
Beispiel #2
0
	def visit_Immediate_FarTarget(self,i):
		"""Create a :class:`AP16` or :class:`AP32` depending upon the address
		size prefix.
		
		:param `.ImmEnc` i:
		:rtype: :class:`.FarTarget`
		"""
		if self.addrpfx: 
			raise ExerciseError("X86Decoder::visit_Immediate_FarTarget:AP16")
		else:
			raise ExerciseError("X86Decoder::visit_Immediate_FarTarget:AP32")
Beispiel #3
0
	def visit_RegOrMem_Register(self,m): 
		"""For RegOrMem when a register is specified, create a new register of the
		type held in *m*'s reg field.
		
		:raises: :exc:`.InvalidInstruction` if *m*'s *reg* field is ``None``, i.e.
			register values are illegal for this abstract operand type.
		
		:param `.RegOrMem` m:
		:rtype: :class:`~.Register`
		"""
		if m.reg is None: 
			raise ExerciseError("X86Decoder::visit_RegOrMem_Register:None")
		raise ExerciseError("X86Decoder::visit_RegOrMem_Register:Default")
Beispiel #4
0
    def Interpret(self):
        """For a :class:`.ModRM32` object whose :attr:`.MOD` field is not 3 (i.e.,
		the :class:`.ModRM32` object specifies a memory location and not a 
		register), examine the fields of the object and return a 5-tuple describing
		the 32-bit memory expression.
		
		:rtype: (:class:`~.R32Elt`, :class:`~.R32Elt`,integer,integer,integer)
		:returns: A 5-tuple containing a base register, index register, scale 
			factor, integer displacement, and displacement size in bytes. The 
			register components may be ``None``; the displacement may be ``None``.
		:raises: assertion failure if :attr:`MOD` is ``3``.
		"""
        # We're interpreting memory expressions here, not registers.
        assert (self.MOD != 3)

        # Adjust a 32-bit register from a number [0,7] to a 32-bit register enum.
        def AdjustReg32(n):
            return R32Elt(n)

        # Return a 5-tuple:  (basereg,indexreg,scalefac,disp,dispsize)
        # self.Disp and self.DispSize will be set identically for any case, so
        # we pull that logic out into this helper function.
        def ModRM32WithDisp(basereg, indexreg, scalefac):
            return (basereg, indexreg, scalefac, self.Disp, self.DispSize)

        # Is it the case that the expression is just a DWORD?
        if self.MOD == 0 and self.RM == 5:
            raise ExerciseError("ModRM32::Interpret: Displacement only")

        # Check to see if a SIB is specified.  If not, no index register is used.
        if self.RM != 4:
            raise ExerciseError("ModRM32::Interpret: No SIB")

        # Set IndexReg and ScaleFac to empty at first.
        IndexReg, ScaleFac = None, 0

        # Is it the case that an index register is present (i.e., SIB.IDX is not
        # ESP)?  If so, set IndexReg with the adjusted register and set ScaleFac
        # to the SIB's SS field.
        if self.SIB.INDEX != 4:
            raise ExerciseError("ModRM32::Interpret: Index/Scale")

        # Is it the case where MOD == 0 and BASE == 5?  In this case, there is no
        # base register.  Call ModRM32WithDisp and return its value.
        if self.MOD == 0 and self.SIB.BASE == 5:
            raise ExerciseError("ModRM32::Interpret: No base register")

        # The full SIB case applies.  We had a base register (in SIB.SREG), an index
        # (in IndexReg) and scale factor (in ScaleFac).
        raise ExerciseError("ModRM32::Interpret: SIB general case")
Beispiel #5
0
    def EncodeFromParts(self, BaseReg, IndexReg, Disp):
        """Given base and index registers, and an integer displacement, set the
		internal state to the corresponding integer values.  We must interpret the
		arguments and determine which special cases apply, if any.
		
		:param `.R16Elt` BaseReg: base register (or ``None``)
		:param `.R16Elt` IndexReg: index register (or ``None``)
		:param integer Disp: displacement (may be ``0`` or ``None``)
		:raises Exception: if *BaseReg* and *IndexReg* are an illegal register pair
		"""

        # Helper function:  set the MOD and displacement information.
        def SetModDisp(mod, disp, dispsize):
            self.MOD, self.Disp, self.DispSize = mod, disp, dispsize

        # Is it the case where only an offset is specified?  If so, set MOD=0,RM=6,
        # and the displacement Disp with size 2.  Then, return.
        if BaseReg == None and IndexReg == None:
            raise ExerciseError("ModRM16::EncodeFromParts: Displacement only")

        had_Disp = False
        # A displacement was not specified.  Set MOD to 0.  We may change it later
        # for [Bp], whose encoding mandates a displacement.
        if Disp == None or Disp == 0:
            raise ExerciseError("ModRM16::EncodeFromParts: No displacement")

        # A displacement was specified, so set the displacement information.
        else:
            had_Disp = True
            # Check if the displacement can be encoded in 8 bits.  Set the MOD and
            # displacement information.
            raise ExerciseError("ModRM16::EncodeFromParts: Displacement")

        # A base register of Bp requires a displacement.  If no displacement has
        # already been specified, set the MOD and displacement information for a
        # 1-byte displacement 0.
        if BaseReg == Bp and not had_Disp:
            raise ExerciseError(
                "ModRM16::EncodeFromParts: Bp, no displacement")

        # Set self.RM to the position of the base/index register pair within the list
        # modrm_16.  This will throw an exception if the register combination is
        # invalid.
        try:
            raise ExerciseError("ModRM16::EncodeFromParts: Set RM")
        except e:
            print "Invalid ModRM/16 register pair"
            raise IndexError
Beispiel #6
0
    def visit_Exact(self, op, i):
        """Exact operands do not need to be encoded.

		:param `.Operand` op:
		:param `.Exact` i:		
		"""
        raise ExerciseError("X86Encoder::visit_Exact")
Beispiel #7
0
	def visit_Exact(self,i):      
		"""For Exact operand types, return *i*'s *value* field directly.
		
		:param `.Exact` i:
		:rtype: :class:`~.Operand`
		"""
		raise ExerciseError("X86Decoder::visit_Exact")
Beispiel #8
0
    def visit_Immediate_MemExpr(s, op, a):
        """For ImmEnc AOTDL elements whose *archetype* members are of type 
		:class:`.MemExpr`, ensure that the operand *op* is indeed a 
		:class:`.MemExpr` object that consists solely of a displacement 
		(:attr:`~.MemExpr.Disp` member) -- in particular, that :attr:`.BaseReg` and
		:attr:`.IndexReg` are ``None``.  As for all :class:`.MemExpr` operands,
		check for address-size and segment-override prefixes.
		
		:param `.Operand` op:  X86 operand
		:param `.ImmEnc` a: :class:`ImmEnc` with :class:`.MemExpr` *archetype*
		:rtype: TypeCheckInfo
		"""
        # Check for immediate only
        if isinstance(op,
                      MemExpr) and op.BaseReg == None and op.IndexReg == None:
            # Check that the sizes match
            if a.archetype.size == op.size:
                # Check the segment and address size prefix requirements, identically
                # to the RegOrMem memory case.
                s_tc = None
                a_tc = None
                raise ExerciseError("X86TypeChecker::visit_Immediate_MemExpr")

                return a_tc
        return None
Beispiel #9
0
	def visit_Immediate_Id(self,i):  
		"""Read a dword from the stream, and return it as an immediate.
		
		:param `.ImmEnc` i:
		:rtype: :class:`.Id`
		"""
		raise ExerciseError("X86Decoder::visit_Immediate_Id")
Beispiel #10
0
	def visit_SignExtImm_Id(self,i): 
		"""Read a byte from the steam and sign-extend it to a dword.
		
		:param `.SignedImm` i:
		:rtype: :class:`.Id`
		"""
		raise ExerciseError("X86Decoder::visit_SignExtImm_Id")
Beispiel #11
0
    def visit_GPart(self, op, g):
        """For GPart operands, store the :class:`~.Register` object *op* 
		:meth:`~.Register.IntValue` in the *ModRM* field :attr:`.GGG`.

		:param `.Register` op:
		:param `.GPart` g:		
		"""
        raise ExerciseError("X86Encoder::visit_GPart")
Beispiel #12
0
    def visit_ExactSeg(self, op, i):
        """For ExactSeg operands, we already know if a segment prefix is required
		due to type-checking.  Therefore, we do not need to do anything.

		:param `.Operand` op:
		:param `.ExactSeg` i:		
		"""
        raise ExerciseError("X86Encoder::visit_ExactSeg")
Beispiel #13
0
    def visit_AddrPrefix(s, op, a):
        """See comments for :meth:`visit_SizePrefix`.

		:param `.Operand` op1:  X86 operand
		:param `.AddrPrefix` a:
		:rtype: TypeCheckInfo
		"""
        raise ExerciseError("X86TypeChecker::visit_AddrPrefix")
Beispiel #14
0
	def visit_AddrPrefix(self,a):    
		"""Depending upon the address size prefix, call :meth:`visit` on either 
		*z*'s *yes* or *no* member.
		
		:param `.AddrPrefix` a:
		:rtype: :class:`.Operand`
		"""
		raise ExerciseError("X86Decoder::visit_AddrPrefix")
Beispiel #15
0
    def visit_AddrPrefix(self, op, a):
        """Visit the appropriate child depending upon whether an address prefix is
		present.
		
		:param `.Operand` op:
		:param `.AddrPrefix` a:		
		"""
        raise ExerciseError("X86Encoder::visit_AddrPrefix")
Beispiel #16
0
	def visit_SizePrefix(self,z):     
		"""Depending upon the operand size prefix, call :meth:`visit` on either 
		*z*'s *yes* or *no* member.
		
		:param `.SizePrefix` z:
		:rtype: :class:`.Operand`
		"""
		raise ExerciseError("X86Decoder::visit_SizePrefix")
Beispiel #17
0
	def visit_GPart(self,g):         
		"""For GPart operand types, return a register with the same type as *g*'s
		*archetype* field, whose register number is the ModRM :attr:`.GGG` field.
		
		:param `.GPart` g:
		:rtype: :class:`~.Register`
		"""
		raise ExerciseError("X86Decoder::visit_GPart")
Beispiel #18
0
    def visit_SizePrefix(self, op, z):
        """Visit the appropriate child depending upon whether a size prefix is 
		present.
		
		:param `.Operand` op:
		:param `.SizePrefix` z:		
		"""
        raise ExerciseError("X86Encoder::visit_SizePrefix")
Beispiel #19
0
    def visit_Immediate_Id(self, op, i):
        """For ImmEnc where the *op* is an :class:`~.Id`, write its *value* member
		as a 32-bit immediate.

		:param `.Id` op:
		:param `.ImmEnc` i:		
		"""
        raise ExerciseError("X86Encoder::visit_Immediate_Id")
Beispiel #20
0
    def visit_Immediate_MemExpr(self, op, i):
        """For ImmEnc where the *op* is a :class:`~.MemExpr`, write its *Disp*
		member as an immediate (``2`` bytes for :class:`~.Mem16`, ``4`` bytes for
		:class:`~.Mem32`.

		:param `.MemExpr` op:
		:param `.ImmEnc` i:		
		"""
        raise ExerciseError("X86Encoder::visit_Immediate_MemExpr")
Beispiel #21
0
	def visit_ExactSeg(self,i): 
		"""For ExactSeg operand types, return *i*'s *value* field directly if there
		was no segment override, or a copy of *value* with the overridden segment
		if there was.
		
		:param `.ExactSeg` i:
		:rtype: :class:`~.MemExpr`
		"""
		raise ExerciseError("X86Decoder::visit_ExactSeg")
Beispiel #22
0
    def visit_Immediate_FarTarget(self, op, i):
        """For ImmEnc where the *op* is a :class:`~.FarTarget`, write its 
		:attr:`Off` member (``2`` bytes for :class:`~.AP16`, ``4`` bytes for
		:class:`~.AP32`), followed by its ``2``-byte :attr:`Seg`.

		:param `.FarTarget` op:
		:param `.ImmEnc` i:		
		"""
        raise ExerciseError("X86Encoder::visit_Immediate_FarTarget")
Beispiel #23
0
    def visit_RegOrMem_Register(self, op, m):
        """For RegOrMem where the *op* a :class:`~.Register`, set the ModRM field
		:attr:`.MOD` to ``3``, and field :attr:`.RM` to the :class:`~.Register` 
		object *op*'s :meth:`~.Register.IntValue`.

		:param `.Register` op:
		:param `.RegOrMem` m:		
		"""
        raise ExerciseError("X86Encoder::visit_RegOrMem_Register")
Beispiel #24
0
    def visit_RegOrMem_Mem32(self, mem, m):
        """For RegOrMem where the *op* a :class:`~.Mem32`, invoke the 
		:meth:`~.ModRM32.EncodeFromParts` method using the parts of the memory
		expression *mem*.

		:param `.Mem32` mem:
		:param `.RegOrMem` m:		
		"""
        raise ExerciseError("X86Encoder::visit_RegOrMem_Mem32")
Beispiel #25
0
    def visit_Exact(s, op, a):
        """For Exact AOTDL elements, *op* must match *a*'s *value* member exactly.

		:param `.Operand` op:  X86 operand
		:param `.Exact` a:
		:rtype: TypeCheckInfo
		"""
        if op == a.value:
            raise ExerciseError("X86TypeChecker::visit_Exact")
        return None
Beispiel #26
0
    def visit_ExactSeg(s, op, a):
        """For ExactSeg AOTDL elements, *op* must match *a*'s *value* member 
		exactly, or it must match *value* when *value*'s :attr:`~.Seg` attribute
		is changed to that of *op*.  In the latter case, the return value must
		indicate that a segment override prefix is required.

		:param `.Operand` op:  X86 operand
		:param `.ExactSeg` a:
		:rtype: TypeCheckInfo
		"""
        if op == a.value:
            raise ExerciseError("X86TypeChecker::visit_ExactSeg: Exact match")

        if isinstance(op, MemExpr) and isinstance(a.value, MemExpr):
            # Make a copy of a.value with op's segment, and compare it to op.
            if a.value(op.Seg) == op:
                raise ExerciseError(
                    "X86TypeChecker::visit_ExactSeg: Segment differs")
        return None
Beispiel #27
0
    def visit_GPart(s, op, a):
        """For GPart AOTDL elements, ensure that the operand type specified in 
		*a*'s *archetype* member has the same type as the operand *op*.
		
		:param `.Operand` op:  X86 operand
		:param `.GPart` a:
		:rtype: TypeCheckInfo
		"""
        if type(op) == type(a.archetype):
            raise ExerciseError("X86TypeChecker::visit_GPart")
        return None
Beispiel #28
0
    def visit_Immediate_JccTarget(s, op, a):
        """For ImmEnc AOTDL elements whose *archetype* members are of type 
		:class:`.JccTarget`, ensure that the operand *op* also has type 
		:class:`.JccTarget`.
		
		:param `.Operand` op:  X86 operand
		:param `.ImmEnc` a: :class:`ImmEnc` with :class:`.JccTarget` *archetype*
		:rtype: TypeCheckInfo
		"""
        if isinstance(op, JccTarget):
            raise ExerciseError("X86TypeChecker::visit_Immediate_JccTarget")
        return None
Beispiel #29
0
    def visit_Immediate_Immediate(s, op, a):
        """For ImmEnc AOTDL elements whose *archetype* members are of type 
		:class:`.ImmEnc`, ensure that the operand *op* has the same type as 
		*archetype*.
		
		:param `.Operand` op:  X86 operand
		:param `.ImmEnc` a: :class:`ImmEnc` with :class:`.Immediate` *archetype*
		:rtype: TypeCheckInfo
		"""
        if type(op) == type(a.archetype):
            raise ExerciseError("X86TypeChecker::visit_Immediate_Immediate")
        return None
Beispiel #30
0
	def visit_RegOrMem_MemExpr(self,m):
		"""For RegOrMem when memory is specified, create a :class:`Mem16` or 
		:class:`Mem32` object depending upon address size, using the information
		from :attr:`X86Decoder.ModRM`.
		
		:raises: :exc:`.InvalidInstruction` if *m*'s *mem* field is ``None``, i.e.
			memory locations are illegal for this abstract operand type.
		
		:param `.RegOrMem` m:
		:rtype: :class:`~.MemExpr`
		"""
		if m.mem is None: 
			raise ExerciseError("X86Decoder::visit_RegOrMem_MemExpr:None")
		else:
			seg = self.GetSegment()
			
			# Decode a 16-bit ModRM
			if self.addrpfx: 
				raise ExerciseError("X86Decoder::visit_RegOrMem_MemExpr:Mem16")
			 
			# Decode a 32-bit ModRM
			raise ExerciseError("X86Decoder::visit_RegOrMem_MemExpr:Mem32")