Exemplo n.º 1
0
	def _decode_hardcode(self, value, info):
		'''
		   Returns a new Immediate, Register, or EffectiveAddress
		   operand.
		'''
		string_regs = { 'X':(IA32.REG_ESI_INDEX, IA32.REG_SI_INDEX),
				'Y':(IA32.REG_EDI_INDEX, IA32.REG_DI_INDEX) }
		string_segs = { 'X':'ds',
				'Y':'es'}

		addr_meth = info['addr_meth']
		size = info['size']
		info['hardcoded'] = True
		if addr_meth == 'II':
			# 'Immediate' value is implicit in opcode definition
			imm = ISA.ImmediateValue(1,value,value, info['signed'])
			op = Operand.Immediate(imm, info)

		elif addr_meth == 'F':
			reg = IA32.register_factory(IA32.REG_FLAGS_INDEX)
			op = Operand.Register(reg, info)

		elif addr_meth in string_regs:
			# String destination is hard-coded in opcode definition
			# Note that the intel instruction syntax specifies
			# this as a segment:register address pair -- either
			# DS:ESI or ES:EDI -- when really what it represents
			# is an effective address, e.g. [DS:ESI].
			if self.state.addr_size == 2:
				reg_id = string_regs[addr_meth][1]
			else:
				reg_id = string_regs[addr_meth][0]

			info['string'] = True
			info['segment'] = string_segs[addr_meth]
			# NOTE: this operand applies to opcodes like MOVS.
			# Even though this is an explicit operand in the
			# opcode definition, it is not displayed during
			# disassembly ... so we make it implicit.
			info['implicit'] = True

			# base reg:
			reg = IA32.register_factory(reg_id)
			op = Operand.EffectiveAddress(None, reg, None, 1, info)

		else:
			# Register set is hard-coded in opcode definition
			reg_set = self._register_set(addr_meth, size)
			reg = IA32.register_factory(reg_set + value)
			op = Operand.Register(reg, info)

		return op
Exemplo n.º 2
0
		def decode(self, buf):
			if self.base == self.EBP_BASE and not self.disp_exists:
				# if ModR/M did not create a displacement 
				# (! mod) get 4-byte unsigned disp
				self.disp = unpack_immediate(buf, 4, False)
				self.disp_size = 4
			else:
				self.base_reg = \
				     IA32.register_factory(self.base + 1)

			self.scale_val = 1 << self.scale
			if self.index != self.NO_INDEX:
				self.index_reg = \
				     IA32.register_factory(self.index + 1)
Exemplo n.º 3
0
	def _decode_modrm_reg(self, info):
		'''
		   Returns a new Register operand object
		'''
		addr_meth = info['addr_meth']
		size = info['size']

		reg_set = self._register_set(addr_meth, size)
		reg = IA32.register_factory(reg_set + self.state.modrm.reg)

		return Operand.Register(reg, info)
Exemplo n.º 4
0
	def _decode_16(self, buf):
		# format: base, index, seg
		rm_regs = (
			( IA32.REG_BX_INDEX, IA32.REG_SI_INDEX, None ),
			( IA32.REG_BX_INDEX, IA32.REG_DI_INDEX, None ),
			( IA32.REG_BP_INDEX, IA32.REG_SI_INDEX, "ss" ),
			( IA32.REG_BP_INDEX, IA32.REG_DI_INDEX, "ss" ),
			( IA32.REG_SI_INDEX, None, None ),
			( IA32.REG_DI_INDEX, None, None ),
			( IA32.REG_BX_INDEX, None, None ),
			( IA32.REG_BP_INDEX, None, "ss" ) )

		self.base = IA32.register_factory(rm_regs[self.rm][0])

		idx = rm_regs[self.rm][1]
		if idx:
			self.index = IA32.register_factory(idx)

		if self.mod == ModRM.MOD.DISP8:
			# get 1-byte signed displacement
			self.disp = unpack_immediate(buf, 1, True)
			self.disp_size = 1

		elif self.mod == ModRM.MOD.DISP16:
			# get 2-byte unsigned displacement
			self.disp = unpack_immediate(buf, 2, False)
			self.disp_size = 2

		elif self.mod == ModRM.MOD.NO_DISP and \
		     self.rm == ModRM.RM16.BP:
		     # special case: there is no [BP] case, instead it
		     # decodes to disp16 with no register
			self.base = None
			# get 2-byte unsigned displacement
			self.disp = unpack_immediate(buf, 2, False)
			self.disp_size = 2

		seg = rm_regs[self.rm][2]
		if seg:
			self.segment = seg
Exemplo n.º 5
0
	def _segment(self, seg=None):
		seg_regs = { 	'es': IA32.REG_ES_INDEX, 
				'cs': IA32.REG_CS_INDEX,
				'ss': IA32.REG_SS_INDEX,
				'ds': IA32.REG_DS_INDEX,
				'fs': IA32.REG_FS_INDEX,
				'gs': IA32.REG_GS_INDEX }
		if not seg:
			seg = self.state.prefix_groups[2]
			if not seg or "taken" in seg:
				return None
		reg = seg_regs[seg]
		return IA32.register_factory(reg)
Exemplo n.º 6
0
    def _implicit_operands(self, index, insn ):
        # append to operands
        # TODO: Generate datatypes for implicit operands
        info = { 'segment':None, 'pointer':False, 'string':False, 
             'hardcoded':True, 'implicit':True, 'name':'',
             'addr_meth':None, 'op_type':None, 'datatype':None,
             'size':None }

        op_list = IA32.implicit_operands[index]
        for o in op_list:
            inf = info.copy()
            inf['access'] = o['access']
            reg = IA32.register_factory(o['register'])
            op = Operand.Register(reg, inf)
            insn._operands.append(op)
        return
Exemplo n.º 7
0
	def _decode_base(self, buf):
		if self.rm == ModRM.RM.SIB:
			# RM = 100
			self.sib = True
			sib = ModRM.SIB(buf.read(), self.mod)
			sib.decode(buf)
			self.base = sib.base_reg
			self.index = sib.index_reg
			self.scale = sib.scale_val
			self.disp = sib.disp
			self.disp_size = sib.disp_size
			if sib.segment:
				self.segment = sib.segment

		else:
			# RM encodes a general register
			self.base = IA32.register_factory(IA32.REG_DWORD_INDEX + self.rm )
Exemplo n.º 8
0
	def decode(self, buf, reg_set, addr_size):
		'''
		    Decode ModR/M byte, using mod and r/m fields.
		    Reg/opcode extension field is handled elsewhere.
		    Does not consume the ModR/M byte from buf, but
		    DOES consume SIB and displacement bytes.
		'''
		if self.mod == ModRM.MOD.REG_ONLY:
			# MOD = 11
			self.register = IA32.register_factory(reg_set + self.rm)
			return

		if addr_size == 2:
			return self._decode_16(buf)

		if self.mod == ModRM.MOD.NO_DISP:
			# MOD = 00
			if self.rm == ModRM.RM.NO_REG:
				# RM = 101
				# read a unsigned dword from buffer
				self.disp = unpack_immediate(buf, 4, False)
				self.disp_size = 4
			else:
				self._decode_base(buf)
		else:
			self._decode_base(buf)

			# NOTE: since mod > 0 in these cases, SIB.decode()
			#       never creates a displacement.
			if self.mod == ModRM.MOD.DISP8:
				# get signed byted into displacement
				self.disp = unpack_immediate(buf, 1, True)
				self.disp_size = 1
			else:
				# get unsigned dword into displacement
				self.disp = unpack_immediate(buf, 4, False)
				self.disp_size = 4