Beispiel #1
0
        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;
            }
            }
        }
Beispiel #2
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;
 }
Beispiel #3
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);
        }
Beispiel #5
0
        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.");
        }
Beispiel #6
0
 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.");
     }
 }
Beispiel #8
0
        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.");
        }
Beispiel #9
0
 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;
         }
     }
 }
Beispiel #10
0
 private void WriteOperand(X86OperandType method, X86OperandSize size, X86Operand operand)
 {
     WriteOperandValue(method, size, operand);
     WriteOperandOffset(operand.OffsetType, operand.Offset);
 }
Beispiel #11
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;
        }
Beispiel #12
0
        /// <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.");
            }
        }