Esempio n. 1
0
	def _decode_nomodrm(self, buf, info):
		'''
		   Returns a new Immediate, RelativeNear, RelativeFar,
		   Offset, or SegmentOffset operand object.
		'''
		addr_meth = info['addr_meth']
		size = info['size']
		addr_size = self.state.addr_size

		if addr_meth == 'A':
			# segment:offset (far calls). Either 16:16 or 16:32.
			seg = unpack_immediate(buf, 2, False)
			off = unpack_immediate(buf, addr_size, False)
			info['pointer'] = True
			op = Operand.SegmentOffset(seg, off, info)

			# mark this operand as variant
			self._mark_bytes(1, 2 + addr_size)

		elif addr_meth == 'I':
			sign = info['signed']
			val = unpack_immediate(buf, size, sign)
			if (val.signed() > 4096 or val.signed < -4096):
			   	# use sensible defaults for signedness
				sign = False
			else:
				sign = True
			op = Operand.Immediate(val, info, sign)

			# if Optype is v, assume this is variant
			if info['op_type'] == 'v':
				self._mark_bytes(1, size)
			else:
				self._mark_bytes(0, size)
				

		elif addr_meth == 'J':
			val = unpack_immediate(buf, size, True)
			if size == addr_size:
				op = Operand.RelativeFar(val, self.state.insn, 
					info)
			else:
				op = Operand.RelativeNear(val, self.state.insn,
					info)

			# mark this operand as invariant
			self._mark_bytes(0, size)

		elif addr_meth == 'O':
			val = unpack_immediate(buf, addr_size, False)
			info['segment'] = self._segment()
			info['pointer'] = True

			op = Operand.Offset(val, info)

			# mark this operand as variant
			self._mark_bytes(1, addr_size)

		return op
Esempio n. 2
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
Esempio n. 3
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)
Esempio n. 4
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