예제 #1
0
        ulong registerAddress;     // _ADR

        public GenericRegisterDescriptor(AddressSpace addressSpace, byte registerBitWidth, byte registerBitOffset,
                                         AddressSize addressSize, ulong registerAddress)
        {
            this.addressSpace      = addressSpace;
            this.registerBitWidth  = registerBitWidth;
            this.registerBitOffset = registerBitOffset;
            this.addressSize       = addressSize;
            this.registerAddress   = registerAddress;
        }
예제 #2
0
 protected EncoderOpCodeHandler(Code code, uint opCode, int groupIndex, Encodable encodable, OperandSize opSize, AddressSize addrSize, TryConvertToDisp8N tryConvertToDisp8N, Op[] operands)
 {
     TEST_Code          = code;
     OpCode             = opCode;
     GroupIndex         = groupIndex;
     Encodable          = encodable;
     OpSize             = opSize;
     AddrSize           = addrSize;
     TryConvertToDisp8N = tryConvertToDisp8N;
     Operands           = operands;
 }
예제 #3
0
 protected OpCodeHandler(uint opCode, int groupIndex, OpCodeHandlerFlags flags, Encodable encodable, OperandSize opSize, AddressSize addrSize, TryConvertToDisp8N?tryConvertToDisp8N, Op[] operands)
 {
     OpCode             = opCode;
     GroupIndex         = groupIndex;
     Flags              = flags;
     Encodable          = encodable;
     OpSize             = opSize;
     AddrSize           = addrSize;
     TryConvertToDisp8N = tryConvertToDisp8N;
     Operands           = operands;
 }
예제 #4
0
 public LegacyOpCodeInfo(EnumValue code, MandatoryPrefix mandatoryPrefix, OpCodeTableKind table, uint opCode, int groupIndex, OperandSize operandSize, AddressSize addressSize, OpCodeFlags flags, LegacyOpKind[] opKinds)
 {
     Code            = code;
     MandatoryPrefix = mandatoryPrefix;
     Table           = table;
     OpCode          = opCode;
     GroupIndex      = groupIndex;
     Flags           = flags;
     OperandSize     = operandSize;
     AddressSize     = addressSize;
     OpKinds         = opKinds;
 }
예제 #5
0
		public bool Match(
			AddressSize defaultAddressSize, ImmutableLegacyPrefixList legacyPrefixes, Xex xex, byte opcode,
			out bool hasModRM, out int immediateSize)
		{
			var partialInstruction = new Instruction.Builder
			{
				DefaultAddressSize = defaultAddressSize,
				LegacyPrefixes = legacyPrefixes,
				Xex = xex,
				OpcodeByte = opcode
			}.Build();

			return Match(partialInstruction, upToOpcode: true, hasModRM: out hasModRM, immediateSize: out immediateSize);
		}
예제 #6
0
		public static int InBytes(this ImmediateSize size, OperandSize operandSize, AddressSize addressSize)
		{
			Contract.Requires(operandSize >= OperandSize.Word && operandSize <= OperandSize.Qword);
			switch (size)
			{
				case ImmediateSize.Zero: return 0;
				case ImmediateSize.Fixed8: return 1;
				case ImmediateSize.Fixed16: return 2;
				case ImmediateSize.Fixed32: return 4;
				case ImmediateSize.Fixed64: return 8;
				case ImmediateSize.Operand16Or32: return operandSize == OperandSize.Word ? 2 : 4;
				case ImmediateSize.Operand16Or32Or64: return operandSize == OperandSize.Qword ? 8 : 4;
				case ImmediateSize.Address16Or32: return addressSize == AddressSize._16 ? 2 : 4;
				default: throw new ArgumentException(nameof(size));
			}
		}
예제 #7
0
파일: ModRM.cs 프로젝트: MrTrillian/Asmuth
		public static DisplacementSize GetDisplacementSize(this ModRM modRM, Sib sib, AddressSize addressSize)
		{
			switch (modRM & ModRM.Mod_Mask)
			{
				case ModRM.Mod_IndirectDisplacement8:
					return DisplacementSize._8;
				case ModRM.Mod_IndirectLongDisplacement:
					return addressSize == AddressSize._16 ? DisplacementSize._16 : DisplacementSize._32;
				case ModRM.Mod_Direct: return 0;
			}

			// Mod = 0
			if (addressSize == AddressSize._16)
				return GetRM(modRM) == 6 ? DisplacementSize._16 : DisplacementSize._0;

			if (GetRM(modRM) == 5) return DisplacementSize._32;

			// 32-bit mode, mod = 0, RM = 6 (sib byte)
			return (sib & Sib.Base_Mask) == Sib.Base_Special ? DisplacementSize._32 : DisplacementSize._0;
		}
예제 #8
0
		public static EffectiveAddress Indirect(
			AddressSize addressSize, SegmentRegister? segment,
			GprCode @base, int displacement = 0)
			=> Indirect(addressSize, segment, (AddressBaseRegister)@base, displacement);
예제 #9
0
		public static EffectiveAddress Indirect(
			AddressSize addressSize, SegmentRegister? segment,
			AddressBaseRegister @base, int displacement = 0)
			=> Indirect(addressSize, segment, @base, index: null, scale: 1, displacement: displacement);
예제 #10
0
		public static bool IsEncodable(this DisplacementSize size, AddressSize addressSize)
			=> (size == DisplacementSize._16) == (addressSize == AddressSize._16);
예제 #11
0
		public static int GetImmediatesSizeInBytes(this InstructionEncoding encoding,
			OperandSize operandSize, AddressSize addressSize)
		{
			Contract.Requires(operandSize >= OperandSize.Word && operandSize <= OperandSize.Qword);
			return GetFirstImmediateSize(encoding).InBytes(operandSize, addressSize)
				+ GetSecondImmediateSize(encoding).InBytes(operandSize, addressSize);
		}
예제 #12
0
		public bool IsEncodableWithDefaultAddressSize(AddressSize defaultAddressSize)
		{
			var effectiveAddressSize = AddressSize;
			if (defaultAddressSize == AddressSize._16 && effectiveAddressSize == AddressSize._64) return false;
			if (defaultAddressSize == AddressSize._64) return effectiveAddressSize != AddressSize._16;
			
			// default size = 16 or 32
			var baseFlags = flags & Flags.BaseReg_Mask;
			return (baseFlags < Flags.BaseReg_R8 || baseFlags == Flags.BaseReg_None)
				|| (flags & Flags.IndexReg_Mask) < Flags.IndexReg_R8;
		}
예제 #13
0
		public static CodeContext GetIA32e(AddressSize defaultAddressSize)
		{
			switch (defaultAddressSize)
			{
				case AddressSize._16: return CodeContext.Compatibility_Default16;
				case AddressSize._32: return CodeContext.Compatibility_Default32;
				case AddressSize._64: return CodeContext.SixtyFourBit;
				default: throw new ArgumentOutOfRangeException(nameof(defaultAddressSize));
			}
		}
예제 #14
0
파일: ModRM.cs 프로젝트: MrTrillian/Asmuth
		public static bool ImpliesSib(this ModRM modRM, AddressSize addressSize)
			=> addressSize >= AddressSize._32 && GetRM(modRM) == 4 && GetMod(modRM) != 3;
예제 #15
0
		public static EffectiveAddress RipRelative(
			AddressSize addressSize, SegmentRegister? segment, int displacement)
		{
			Contract.Requires(addressSize != AddressSize._16);
			return Indirect(addressSize, segment, AddressBaseRegister.Rip, displacement);
		}
예제 #16
0
		public static EffectiveAddress FromEncoding(AddressSize defaultAddressSize, Encoding encoding)
		{
			if ((encoding.ModRM & ModRM.Mod_Mask) == ModRM.Mod_Direct)
				throw new ArgumentException("ModRM does not encode a memory operand.");

			var addressSize = defaultAddressSize.GetEffective(encoding.AddressSizeOverride);

			// Mod in { 0, 1, 2 }
			if (addressSize == AddressSize._16)
			{
				Contract.Assert(unchecked((short)encoding.Displacement) == encoding.Displacement);
				if (encoding.ModRM.GetMod() == 0 && encoding.ModRM.GetRM() == 6)
					return Absolute(addressSize, encoding.Displacement);

				int displacementSize = encoding.ModRM.GetMod();
				Contract.Assert(displacementSize != 0 || encoding.Displacement == 0);
				Contract.Assert(displacementSize != 1 || unchecked((sbyte)encoding.Displacement) == encoding.Displacement);
				return FromIndirect16Encoding(encoding.Segment, encoding.ModRM.GetRM(), (short)encoding.Displacement);
			}
			else
			{
				if (encoding.ModRM.GetMod() == 0 && encoding.ModRM.GetRM() == 5)
				{
					return defaultAddressSize == AddressSize._64
						? RipRelative(addressSize, encoding.Segment, encoding.Displacement)
						: Absolute(addressSize, encoding.Displacement);
				}

				var displacementSize = encoding.ModRM.GetDisplacementSize(encoding.Sib.GetValueOrDefault(), addressSize);
				Contract.Assert(displacementSize.CanEncodeValue(encoding.Displacement));

				GprCode? baseReg = (GprCode)encoding.ModRM.GetRM();
				if (baseReg != GprCode.Esp)
					return Indirect(addressSize, encoding.Segment, baseReg.Value, encoding.Displacement);

				// Sib byte
				if (!encoding.Sib.HasValue) throw new ArgumentException();

				baseReg = encoding.Sib.Value.GetBaseReg(encoding.ModRM);
				var index = encoding.Sib.Value.GetIndexReg();
				int scale = encoding.Sib.Value.GetScale();
				return Indirect(addressSize, encoding.Segment, baseReg, index, (byte)scale, encoding.Displacement);
			}
		}
예제 #17
0
		private static Flags BaseFlags(AddressSize size)
		{
			switch (size)
			{
				case AddressSize._16: return Flags.AddressSize_16;
				case AddressSize._32: return Flags.AddressSize_32;
				case AddressSize._64: return Flags.AddressSize_64;
				default: throw new UnreachableException();
			}
		}
예제 #18
0
		public Encoding Encode(AddressSize defaultAddressSize, byte modReg, DisplacementSize displacementSize)
		{
			if ((defaultAddressSize == AddressSize._16 && AddressSize == AddressSize._64)
				|| (defaultAddressSize == AddressSize._64 && AddressSize == AddressSize._16))
				throw new ArgumentException(nameof(defaultAddressSize));

			if (modReg >= 8) throw new ArgumentException(nameof(modReg));
			if (!IsEncodableWithDisplacementSize(displacementSize))
				throw new ArgumentException(nameof(displacementSize));

			var encoding = new Encoding()
			{
				Segment = RequiresSegmentOverride ? Segment : (SegmentRegister?)null,
				AddressSizeOverride = AddressSize != defaultAddressSize,
				BaseRegExtension = BaseAsGprCode >= GprCode.R8,
				IndexRegExtension = IndexAsGprCode >= GprCode.R8,
				Displacement = displacement
			};

			if (AddressSize == AddressSize._16) throw new NotImplementedException();

			byte mod;
			switch (displacementSize)
			{
				case DisplacementSize._0: mod = 0; break;
				case DisplacementSize._8: mod = 1; break;
				default: mod = 2; break;
			}

			var @base = Base;
			bool needsSib = false;
			if (AddressSize == AddressSize._64)
			{
				// Same as 32-bit except that [disp32] encodes [rip + disp32]
				if ([email protected]) needsSib = true;
				if (@base == AddressBaseRegister.Rip) @base = null;
			}

			if (@base == AddressBaseRegister.SP || (mod == 0 && @base == AddressBaseRegister.BP))
				needsSib = true;

			if (needsSib)
			{
				if (@base == AddressBaseRegister.BP) throw new NotImplementedException();

				encoding.ModRM = ModRMEnum.FromComponents(mod, modReg, 0) | ModRM.RM_Sib;
				encoding.Sib = SibEnum.FromComponents(
					ss: (byte)((int)(flags & Flags.Scale_Mask) >> (int)Flags.Scale_Shift),
					index: (IndexAsGprCode ?? GprCode.SP).GetLow3Bits(),
					@base: (BaseAsGprCode ?? GprCode.BP).GetLow3Bits());
			}
			else
			{
				encoding.ModRM = ModRMEnum.FromComponents(mod, modReg, (byte)((byte)@base.Value & 0x7));
			}

			return encoding;
		}
예제 #19
0
		private static Flags BaseFlags(AddressSize size, SegmentRegister segment)
		{
			var flags = BaseFlags(size);
			switch (segment)
			{
				case SegmentRegister.CS: flags |= Flags.Segment_C; break;
				case SegmentRegister.DS: flags |= Flags.Segment_D; break;
				case SegmentRegister.ES: flags |= Flags.Segment_E; break;
				case SegmentRegister.FS: flags |= Flags.Segment_F; break;
				case SegmentRegister.GS: flags |= Flags.Segment_G; break;
				case SegmentRegister.SS: flags |= Flags.Segment_S; break;
				default: throw new UnreachableException();
			}

			return flags;
		}
예제 #20
0
		private static Instruction DecodeSingle_IA32e(AddressSize defaultAddressSize, params byte[] bytes)
			=> DecodeSingle(CodeContextEnum.GetIA32e(defaultAddressSize), bytes);
예제 #21
0
		public static EffectiveAddress Absolute(AddressSize size, SegmentRegister segment, int address)
		{
			Contract.Requires(size > AddressSize._16 || (short)address == address);
			return new EffectiveAddress(BaseFlags(size, segment) | Flags.BaseReg_None | Flags.IndexReg_None, address);
		}
예제 #22
0
		public static EffectiveAddress Indirect(
			AddressSize addressSize, SegmentRegister? segment, 
			AddressBaseRegister? @base, GprCode? index = null, byte scale = 1, int displacement = 0)
		{
			Contract.Requires(scale == 1 || scale == 2 || scale == 4 || scale == 8
				|| (scale == 0 && !index.HasValue));
			Contract.Requires(@base != AddressBaseRegister.Rip || (addressSize != AddressSize._16 && index.HasValue));
			if (addressSize == AddressSize._16)
			{
				Contract.Requires(!(@base >= AddressBaseRegister.R8));
				Contract.Requires(!(index >= GprCode.R8));
				Contract.Requires((short)displacement == displacement);
				if (@base.HasValue)
				{
					if (index.HasValue)
					{
						Contract.Requires(@base == AddressBaseRegister.B || @base == AddressBaseRegister.BP);
						Contract.Requires(index.Value == GprCode.SI || index.Value == GprCode.DI);
					}
					else
					{
						Contract.Requires(@base == AddressBaseRegister.SI || @base == AddressBaseRegister.DI
							|| @base == AddressBaseRegister.BP || @base == AddressBaseRegister.B);
					}
				}
				else
				{
					Contract.Requires(!index.HasValue);
				}
			}
			else
			{
				Contract.Requires(index != GprCode.Esp);
			}

			// Segment defaults to D, or S if we are using a stack-pointing register
			if (!segment.HasValue)
			{
				segment = (@base == AddressBaseRegister.SP || @base == AddressBaseRegister.BP)
					? SegmentRegister.SS : SegmentRegister.DS;
			}

			var flags = BaseFlags(addressSize, segment.Value);

			if (@base.HasValue) flags |= (Flags)(((int)@base + 1) << (int)Flags.BaseReg_Shift);
			if (index.HasValue)
			{
				// Swap eax and esp (esp meaning "none")
				if (index.Value == GprCode.Eax) flags |= Flags.IndexReg_Eax;
				else flags |= (Flags)((int)index.Value << (int)Flags.IndexReg_Shift);
			}

			if (scale == 2) flags |= Flags.Scale_2x;
			else if (scale == 4) flags |= Flags.Scale_4x;
			else if (scale == 8) flags |= Flags.Scale_8x;
			return new EffectiveAddress(flags, displacement);
		}
예제 #23
0
		public static EffectiveAddress Indirect(
			AddressSize addressSize, SegmentRegister? segment,
			GprCode? @base, GprCode? index = null, byte scale = 1, int displacement = 0)
			=> Indirect(addressSize, segment, (AddressBaseRegister?)@base, index, scale, displacement);
예제 #24
0
 public LegacyOpCodeInfo(EnumValue code, MandatoryPrefix mandatoryPrefix, OpCodeTableKind table, uint opCode, int groupIndex, OperandSize operandSize, AddressSize addressSize, OpCodeFlags flags, LegacyOpKind[] opKinds)
     : this(code, mandatoryPrefix, table, opCode, groupIndex, -1, operandSize, addressSize, flags, opKinds)
 {
 }
예제 #25
0
		public static DisplacementSize GetMaximum(AddressSize addressSize)
			=> addressSize == AddressSize._16 ? DisplacementSize._16 : DisplacementSize._32;