private void WriteOperandValue(X86OperandType method, X86OperandSize size, X86Operand operand) { switch (method) { case X86OperandType.MemoryAddress: case X86OperandType.DirectAddress: case X86OperandType.ImmediateData: { WriteNumber(operand.Value, size); break; } case X86OperandType.RegisterOrMemoryAddress: { if ((operand.ScaledIndex != null) || (operand.OperandUsage != X86OperandUsage.Normal && operand.Value is X86Register && (X86Register)operand.Value == X86Register.Esp)) { _writer.WriteByte(ComputeRegOrMemSibToken(operand)); } else if (!(operand.Value is X86Register)) { WriteNumber(operand.Value, X86OperandSize.Dword); } break; } case X86OperandType.RelativeOffset: { WriteNumber(Convert.ToUInt32(operand.Value) - (_writer.Position + sizeof(sbyte)), size); break; } } }
private static byte ComputeRegisterTokenPart(X86OperandType method, X86OperandSize size, X86Operand operand) { switch (method) { case X86OperandType.Register: { return (byte)(ComputeRegisterToken((X86Register)operand.Value) << 3); } case X86OperandType.RegisterOrMemoryAddress: { return ComputeRegOrMemToken(operand); } } return 0; }
private static byte ComputeRegisterTokenPart(X86OperandType method, X86OperandSize size, X86Operand operand) { switch (method) { case X86OperandType.Register: { return((byte)(ComputeRegisterToken((X86Register)operand.Value) << 3)); } case X86OperandType.RegisterOrMemoryAddress: { return(ComputeRegOrMemToken(operand)); } } return(0); }
private static int GetTotalOperandSize(X86OperandType operandType, X86OperandSize operandSize, X86Operand operand) { int size = (int)operand.OffsetType; switch (operandType) { case X86OperandType.None: case X86OperandType.ControlRegister: case X86OperandType.DebugRegister: case X86OperandType.StackRegister: case X86OperandType.Register: case X86OperandType.RegisterCl: case X86OperandType.RegisterDx: case X86OperandType.RegisterEax: case X86OperandType.RegisterAl: case X86OperandType.ImmediateOne: case X86OperandType.SegmentRegister: case X86OperandType.OpCodeRegister: break; case X86OperandType.DirectAddress: case X86OperandType.MemoryAddress: size += 4; break; case X86OperandType.RelativeOffset: case X86OperandType.ImmediateData: size += GetSize(operandSize); break; case X86OperandType.RegisterOrMemoryAddress: case X86OperandType.StackRegisterOrMemoryAddress: if ((operand.ScaledIndex != null) || (operand.OperandUsage != X86OperandUsage.Normal && operand.Value is X86Register && (X86Register)operand.Value == X86Register.Esp)) { size += 1; } if (!(operand.Value is X86Register)) { size += 4; } break; } return(size); }
private X86Operand ReadOperand(X86OperandType method, X86OperandSize size, byte opcode, byte registerToken) { switch (method) { case X86OperandType.OpCodeRegister: return(new X86Operand(GetRegisterFromToken((byte)(opcode & 7), GetRegisterSize(size)))); case X86OperandType.Register: return(new X86Operand(GetRegisterFromToken((byte)((registerToken >> 3) & 7), GetRegisterSize(size)))); case X86OperandType.RegisterOrMemoryAddress: return(GetRegOrMemOperand32(registerToken, size)); case X86OperandType.ImmediateData: return(new X86Operand(ReadImmediateData(size))); case X86OperandType.MemoryAddress: return(new X86Operand(GetOperandType(size), _reader.ReadUInt32())); case X86OperandType.RegisterAl: return(new X86Operand(X86Register.Al)); case X86OperandType.RegisterCl: return(new X86Operand(X86Register.Cl)); case X86OperandType.RegisterDx: return(new X86Operand(X86Register.Dx)); case X86OperandType.RegisterEax: return(new X86Operand(X86Register.Eax)); case X86OperandType.ImmediateOne: return(new X86Operand(1)); case X86OperandType.RelativeOffset: return(new X86Operand((ulong)(Convert.ToInt64(ReadSignedImmediateData(size)) + BaseAddress + _reader.Position))); case X86OperandType.None: return(null); } throw new NotSupportedException("Unrecognized or unsupported addressing method."); }
private void WriteOperand(X86OperandType method, X86OperandSize size, X86Operand operand) { WriteOperandValue(method, size, operand); WriteOperandOffset(operand.OffsetType, operand.Offset); }
/// <summary> /// Gets the strings used for the operand. /// </summary> /// <param name="spec">The opcode spec.</param> /// <param name="variant">The opcode variant.</param> /// <param name="operand">The operand.</param> /// <returns>A tuple with the C# code for the operand, followed by the YASM assembler code.</returns> Tuple<string, string> GetOperandStrings(X86OperandType operandType, DataSize operandSize, Register fixedRegister, Random rand) { switch (operandType) { case X86OperandType.Immediate: if (operandSize == DataSize.Bit8) { byte value = (byte)rand.Next(0, 0x100); return new Tuple<string, string>( string.Format("(byte)0x{0:X2}", value), string.Format("BYTE 0x{0:X2}", value)); } else if (operandSize == DataSize.Bit16) { ushort value = (ushort)rand.Next(0x100, 0x10000); return new Tuple<string, string>( string.Format("(ushort)0x{0:X}", value), string.Format("WORD 0x{0:X}", value)); } else if (operandSize == DataSize.Bit32) { uint value = (uint)rand.Next(0x10000); return new Tuple<string, string>( string.Format("(uint)0x{0:X}", value), string.Format("DWORD 0x{0:X}", value)); } else if (operandSize == DataSize.Bit64) { var x = (ulong)rand.Next(0x10000); var y = (ulong)rand.Next(0x10000); ulong value = x | (y << 32); return new Tuple<string, string>( string.Format("(ulong)0x{0:X}", value), string.Format("QWORD 0x{0:X}", value)); } else throw new NotSupportedException("The operand size is not supported."); case X86OperandType.FixedRegister: { string name = Enum.GetName(typeof(Register), fixedRegister); return new Tuple<string, string>( string.Format("Register.{0}", name), name.ToLowerInvariant()); } case X86OperandType.MemoryOffset: // TODO: return new Tuple<string, string>("new MemoryOffset()", "0"); case X86OperandType.FarPointer: { if (operandSize == DataSize.Bit16) { ushort selector = (ushort)rand.Next(0x100, 0x10000); ushort offset = (ushort)rand.Next(0x100, 0x10000); return new Tuple<string, string>( string.Format("new FarPointer(c => 0x{0:X}, c => 0x{1:X}, DataSize.Bit16)", selector, offset), string.Format("WORD 0x{0:X}:0x{1:X}", selector, offset)); } else if (operandSize == DataSize.Bit32) { uint selector = (uint)rand.Next(0x10000); uint offset = (uint)rand.Next(0x10000); return new Tuple<string, string>( string.Format("new FarPointer(c => 0x{0:X}, c => 0x{1:X}, DataSize.Bit32)", selector, offset), string.Format("DWORD 0x{0:X}:0x{1:X}", selector, offset)); } else throw new NotImplementedException(); } case X86OperandType.MemoryOperand: case X86OperandType.RegisterOrMemoryOperand: { ushort value = (ushort)rand.Next(0x100, 0x10000); return new Tuple<string, string>( string.Format("new EffectiveAddress(DataSize.Bit{1}, DataSize.None, c => new ReferenceOffset(0x{0:X}))", value, operandSize.GetBitCount()), string.Format("{0} [0x{1:X}]", GetNasmSizeSpecifier(operandSize), value)); } case X86OperandType.RelativeOffset: if (operandSize == DataSize.Bit8) { byte value = (byte)rand.Next(0, 0x100); return new Tuple<string, string>( string.Format("new RelativeOffset(c => 0x{0:X}, DataSize.Bit8)", value), string.Format("BYTE 0x{0:X}", value)); } else if (operandSize == DataSize.Bit16) { ushort value = (ushort)rand.Next(0x100, 0x10000); return new Tuple<string, string>( string.Format("new RelativeOffset(c => 0x{0:X}, DataSize.Bit16)", value), string.Format("WORD 0x{0:X}", value)); } else if (operandSize == DataSize.Bit32) { uint value = (uint)rand.Next(0x10000); return new Tuple<string, string>( string.Format("new RelativeOffset(c => 0x{0:X}, DataSize.Bit32)", value), string.Format("DWORD 0x{0:X}", value)); } else if (operandSize == DataSize.Bit64) { var x = (ulong)rand.Next(0x10000); var y = (ulong)rand.Next(0x10000); ulong value = x | (y << 32); return new Tuple<string, string>( string.Format("new RelativeOffset(c => 0x{0:X}, DataSize.Bit64)", value), string.Format("QWORD 0x{0:X}", value)); } else throw new NotSupportedException("The operand size is not supported."); case X86OperandType.RegisterOperand: return RandomGPRegister(operandSize, rand); default: throw new NotSupportedException("The operand type is not supported."); } }
private X86Operand ReadOperand(X86OperandType method, X86OperandSize size, byte opcode, byte registerToken) { switch (method) { case X86OperandType.OpCodeRegister: return new X86Operand(GetRegisterFromToken((byte)(opcode & 7), GetRegisterSize(size))); case X86OperandType.Register: return new X86Operand(GetRegisterFromToken((byte)((registerToken >> 3) & 7), GetRegisterSize(size))); case X86OperandType.RegisterOrMemoryAddress: return GetRegOrMemOperand32(registerToken, size); case X86OperandType.ImmediateData: return new X86Operand(ReadImmediateData(size)); case X86OperandType.MemoryAddress: return new X86Operand(GetOperandType(size), _reader.ReadUInt32()); case X86OperandType.RegisterAl: return new X86Operand(X86Register.Al); case X86OperandType.RegisterCl: return new X86Operand(X86Register.Cl); case X86OperandType.RegisterDx: return new X86Operand(X86Register.Dx); case X86OperandType.RegisterEax: return new X86Operand(X86Register.Eax); case X86OperandType.ImmediateOne: return new X86Operand(1); case X86OperandType.RelativeOffset: return new X86Operand((ulong)(Convert.ToInt64(ReadSignedImmediateData(size)) + BaseAddress + _reader.Position)); case X86OperandType.None: return null; } throw new NotSupportedException("Unrecognized or unsupported addressing method."); }
private void WriteOperandValue(X86OperandType method, X86OperandSize size, X86Operand operand) { switch (method) { case X86OperandType.MemoryAddress: case X86OperandType.DirectAddress: case X86OperandType.ImmediateData: { WriteNumber(operand.Value, size); break; } case X86OperandType.RegisterOrMemoryAddress: { if ((operand.ScaledIndex != null) || (operand.OperandUsage != X86OperandUsage.Normal && operand.Value is X86Register && (X86Register)operand.Value == X86Register.Esp)) _writer.WriteByte(ComputeRegOrMemSibToken(operand)); else if (!(operand.Value is X86Register)) WriteNumber(operand.Value, X86OperandSize.Dword); break; } case X86OperandType.RelativeOffset: { WriteNumber(Convert.ToUInt32(operand.Value) - (_writer.Position + sizeof (sbyte)), size); break; } } }
private static int GetTotalOperandSize(X86OperandType operandType, X86OperandSize operandSize, X86Operand operand) { int size = (int)operand.OffsetType; switch (operandType) { case X86OperandType.None: case X86OperandType.ControlRegister: case X86OperandType.DebugRegister: case X86OperandType.StackRegister: case X86OperandType.Register: case X86OperandType.RegisterCl: case X86OperandType.RegisterDx: case X86OperandType.RegisterEax: case X86OperandType.RegisterAl: case X86OperandType.ImmediateOne: case X86OperandType.SegmentRegister: case X86OperandType.OpCodeRegister: break; case X86OperandType.DirectAddress: case X86OperandType.MemoryAddress: size += 4; break; case X86OperandType.RelativeOffset: case X86OperandType.ImmediateData: size += GetSize(operandSize); break; case X86OperandType.RegisterOrMemoryAddress: case X86OperandType.StackRegisterOrMemoryAddress: if ((operand.ScaledIndex != null) || (operand.OperandUsage != X86OperandUsage.Normal && operand.Value is X86Register && (X86Register)operand.Value == X86Register.Esp)) size += 1; if (!(operand.Value is X86Register)) size += 4; break; } return size; }
/// <summary> /// Gets the strings used for the operand. /// </summary> /// <param name="spec">The opcode spec.</param> /// <param name="variant">The opcode variant.</param> /// <param name="operand">The operand.</param> /// <returns>A tuple with the C# code for the operand, followed by the YASM assembler code.</returns> Tuple <string, string> GetOperandStrings(X86OperandType operandType, DataSize operandSize, Register fixedRegister, Random rand) { switch (operandType) { case X86OperandType.Immediate: if (operandSize == DataSize.Bit8) { byte value = (byte)rand.Next(0, 0x100); return(new Tuple <string, string>( string.Format("(byte)0x{0:X2}", value), string.Format("BYTE 0x{0:X2}", value))); } else if (operandSize == DataSize.Bit16) { ushort value = (ushort)rand.Next(0x100, 0x10000); return(new Tuple <string, string>( string.Format("(ushort)0x{0:X}", value), string.Format("WORD 0x{0:X}", value))); } else if (operandSize == DataSize.Bit32) { uint value = (uint)rand.Next(0x10000); return(new Tuple <string, string>( string.Format("(uint)0x{0:X}", value), string.Format("DWORD 0x{0:X}", value))); } else if (operandSize == DataSize.Bit64) { var x = (ulong)rand.Next(0x10000); var y = (ulong)rand.Next(0x10000); ulong value = x | (y << 32); return(new Tuple <string, string>( string.Format("(ulong)0x{0:X}", value), string.Format("QWORD 0x{0:X}", value))); } else { throw new NotSupportedException("The operand size is not supported."); } case X86OperandType.FixedRegister: { string name = Enum.GetName(typeof(Register), fixedRegister); return(new Tuple <string, string>( string.Format("Register.{0}", name), name.ToLowerInvariant())); } case X86OperandType.MemoryOffset: // TODO: return(new Tuple <string, string>("new MemoryOffset()", "0")); case X86OperandType.FarPointer: { if (operandSize == DataSize.Bit16) { ushort selector = (ushort)rand.Next(0x100, 0x10000); ushort offset = (ushort)rand.Next(0x100, 0x10000); return(new Tuple <string, string>( string.Format("new FarPointer(c => 0x{0:X}, c => 0x{1:X}, DataSize.Bit16)", selector, offset), string.Format("WORD 0x{0:X}:0x{1:X}", selector, offset))); } else if (operandSize == DataSize.Bit32) { uint selector = (uint)rand.Next(0x10000); uint offset = (uint)rand.Next(0x10000); return(new Tuple <string, string>( string.Format("new FarPointer(c => 0x{0:X}, c => 0x{1:X}, DataSize.Bit32)", selector, offset), string.Format("DWORD 0x{0:X}:0x{1:X}", selector, offset))); } else { throw new NotImplementedException(); } } case X86OperandType.MemoryOperand: case X86OperandType.RegisterOrMemoryOperand: { ushort value = (ushort)rand.Next(0x100, 0x10000); return(new Tuple <string, string>( string.Format("new EffectiveAddress(DataSize.Bit{1}, DataSize.None, c => new ReferenceOffset(0x{0:X}))", value, operandSize.GetBitCount()), string.Format("{0} [0x{1:X}]", GetNasmSizeSpecifier(operandSize), value))); } case X86OperandType.RelativeOffset: if (operandSize == DataSize.Bit8) { byte value = (byte)rand.Next(0, 0x100); return(new Tuple <string, string>( string.Format("new RelativeOffset(c => 0x{0:X}, DataSize.Bit8)", value), string.Format("BYTE 0x{0:X}", value))); } else if (operandSize == DataSize.Bit16) { ushort value = (ushort)rand.Next(0x100, 0x10000); return(new Tuple <string, string>( string.Format("new RelativeOffset(c => 0x{0:X}, DataSize.Bit16)", value), string.Format("WORD 0x{0:X}", value))); } else if (operandSize == DataSize.Bit32) { uint value = (uint)rand.Next(0x10000); return(new Tuple <string, string>( string.Format("new RelativeOffset(c => 0x{0:X}, DataSize.Bit32)", value), string.Format("DWORD 0x{0:X}", value))); } else if (operandSize == DataSize.Bit64) { var x = (ulong)rand.Next(0x10000); var y = (ulong)rand.Next(0x10000); ulong value = x | (y << 32); return(new Tuple <string, string>( string.Format("new RelativeOffset(c => 0x{0:X}, DataSize.Bit64)", value), string.Format("QWORD 0x{0:X}", value))); } else { throw new NotSupportedException("The operand size is not supported."); } case X86OperandType.RegisterOperand: return(RandomGPRegister(operandSize, rand)); default: throw new NotSupportedException("The operand type is not supported."); } }