Exemplo n.º 1
0
        /// <summary>
        /// Returns a string representation of a memory address.
        /// </summary>
        /// <param name="memoryOperand">Memory address operand to be converted to a string.</param>
        /// <param name="prefixes">Current instruction prefixes in effect.</param>
        /// <returns>String representation of the memory address.</returns>
        public static string Format(CodeOperand memoryOperand, PrefixState prefixes)
        {
            string prefix = GetSizePrefix(memoryOperand.OperandSize);

            if (memoryOperand.EffectiveAddress == CodeMemoryBase.SIB)
            {
                return(prefix + FormatSib(memoryOperand));
            }

            string register;

            effectiveAddresses.TryGetValue(memoryOperand.EffectiveAddress, out register);

            string segmentOverride = FormatSegment(prefixes);

            if (register == null)
            {
                return($"{prefix} {segmentOverride}[{memoryOperand.ImmediateValue:X4}]");
            }
            else if (memoryOperand.ImmediateValue == 0)
            {
                return($"{prefix} {segmentOverride}[{register}]");
            }
            else
            {
                return($"{prefix} {segmentOverride}[{register}+{memoryOperand.ImmediateValue:X4}]");
            }
        }
        bool ISettingParser.TryGetSetting(string name, PrefixState state, out ISettingMetadata setting)
        {
            var success = TryGetSetting(name, state, out var temp);

            setting = temp;
            return(success);
        }
Exemplo n.º 3
0
        private static string FormatSegment(PrefixState prefixes)
        {
            switch (prefixes & SegmentOverrideMask)
            {
            case PrefixState.CS:
                return("cs:");

            case PrefixState.DS:
                return("ds:");

            case PrefixState.ES:
                return("es:");

            case PrefixState.FS:
                return("fs:");

            case PrefixState.GS:
                return("gs:");

            case PrefixState.SS:
                return("ss:");

            default:
                return(string.Empty);
            }
        }
Exemplo n.º 4
0
 /// <summary>
 /// Returns a string representation of a segment register.
 /// </summary>
 /// <param name="prefixes">Segment register prefix.</param>
 /// <returns>String representation of the segment register.</returns>
 private static string GetSegmentPrefix(PrefixState prefixes)
 {
     if ((prefixes & SegmentPrefixes) != 0)
     {
         return((prefixes & SegmentPrefixes).ToString().ToLower());
     }
     else
     {
         return(null);
     }
 }
Exemplo n.º 5
0
        /// <summary>
        /// Removes the prefix from the start of the string if it exists.
        /// </summary>
        /// <param name="prefix"></param>
        /// <param name="input"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public static string Deprefix(string prefix, string input, PrefixState state)
        {
            switch (state)
            {
            case PrefixState.Required:
                return(input.CaseInsStartsWith(prefix) ? input.Substring(prefix.Length) : null);

            case PrefixState.Optional:
                return(input.CaseInsStartsWith(prefix) ? input.Substring(prefix.Length) : input);

            case PrefixState.NotPrefixed:
                return(input);

            default:
                throw new InvalidOperationException("Invalid prefix state provided.");
            }
        }
        /// <summary>
        /// Attempts to get the setting with the specified name.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="state"></param>
        /// <param name="setting"></param>
        /// <returns></returns>
        public bool TryGetSetting(string name, PrefixState state, out T setting)
        {
            bool InternalTryGetSetting(string deprefixedName, out T returned)
            {
                var valid = NameMap.TryGetValue(deprefixedName, out var guid);

                returned = valid ? SettingMap[guid] : default;
                return(valid);
            }

            foreach (var prefix in Prefixes)
            {
                var deprefixed = ArgumentMappingUtils.Deprefix(prefix, name, state);
                if (deprefixed != null && InternalTryGetSetting(deprefixed, out setting))
                {
                    return(true);
                }
            }
            setting = default;
            return(false);
        }
Exemplo n.º 7
0
            static void Postfix(ref ZoneSystem __instance, ref bool __result, PrefixState __state)
            {
                if (__result)
                {
                    return;
                }
                if (__state.isDungeon)
                {
                    var locationInstances = AccessTools.FieldRefAccess <ZoneSystem, Dictionary <Vector2i, ZoneSystem.LocationInstance> >(__instance, "m_locationInstances");

                    foreach (ZoneSystem.LocationInstance locationInstance in locationInstances.Values)
                    {
                        var prefabName = locationInstance.m_location.m_prefabName;
                        if ((IsDungeon(prefabName) || IsTrollCave(prefabName)) &&
                            Vector3.Distance(locationInstance.m_position, __state.point) < __state.radius)
                        {
                            __result = true;
                            return;
                        }
                    }
                }
                return;
            }
Exemplo n.º 8
0
 static void Prefix(string __0, ref string __1, Vector3 __2, ref float __3, out PrefixState __state)
 {
     __state           = new PrefixState(__2, __3);
     __state.isDungeon = IsDungeon(__0);
 }
 ISettingMetadata ISettingParser.GetSetting(string name, PrefixState state)
 => GetSetting(name, state);
 /// <summary>
 /// Gets the setting with the specified name and throws if it's not found.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="state"></param>
 /// <returns></returns>
 public T GetSetting(string name, PrefixState state)
 => TryGetSetting(name, state, out var temp) ? temp : throw new KeyNotFoundException($"There is no setting with the registered name {name}.");
Exemplo n.º 11
0
 public static DecodedOperands?TryDecode(OpcodeInfo opcode, ReadOnlySpan <byte> rawData, PrefixState prefixes)
 {
     try
     {
         return(Decode(opcode, rawData, prefixes, out _));
     }
     catch
     {
         return(null);
     }
 }
Exemplo n.º 12
0
 public static DecodedOperands Decode(OpcodeInfo opcode, ReadOnlySpan <byte> rawData, PrefixState prefixes) => Decode(opcode, rawData, prefixes, out _);
Exemplo n.º 13
0
        private static DecodedOperands Decode(OpcodeInfo opcode, ReadOnlySpan <byte> rawData, PrefixState prefixes, out int length)
        {
            var reader   = new OperandReader(rawData);
            var operands = new DecodedOperands();

            length = 0;

            if (opcode.Operands.Count == 0)
            {
                return(operands);
            }

            if (opcode.ModRmInfo != ModRmInfo.None)
            {
                byte modRmByte = reader.ReadByte();
                int  mod       = (modRmByte & 0xC0) >> 6;
                int  rm        = modRmByte & 0x07;

                for (int i = 0; i < opcode.Operands.Count; i++)
                {
                    var type = opcode.Operands[i];
                    if (type == OperandType.RegisterOrMemoryByte)
                    {
                        operands.SetOperand(i, DecodeRmbw(mod, rm, true, prefixes, ref reader));
                    }
                    else if (IsPointerOperand(type))
                    {
                        var operand = DecodeRmbw(mod, rm, false, prefixes, ref reader);
                        if (type == OperandType.EffectiveAddress)
                        {
                            operand.Type = CodeOperandType.EffectiveAddress;
                        }
                        else if (type == OperandType.FullLinearAddress)
                        {
                            operand.Type = CodeOperandType.FullLinearAddress;
                        }
                        else if (type == OperandType.RegisterOrMemoryWordNearPointer)
                        {
                            operand.Type = CodeOperandType.AbsoluteJumpAddress;
                        }
                        else if (type == OperandType.IndirectFarPointer)
                        {
                            operand.Type = CodeOperandType.IndirectFarMemoryAddress;
                        }
                        else if (type == OperandType.MemoryInt16 || type == OperandType.RegisterOrMemory16)
                        {
                            operand.OperandSize = CodeOperandSize.Word;
                        }
                        else if (type == OperandType.MemoryInt32 || type == OperandType.RegisterOrMemory32)
                        {
                            operand.OperandSize = CodeOperandSize.DoubleWord;
                        }
                        else if (type == OperandType.MemoryInt64)
                        {
                            operand.OperandSize = CodeOperandSize.QuadWord;
                        }
                        else if (type == OperandType.MemoryFloat32)
                        {
                            operand.OperandSize = CodeOperandSize.Single;
                        }
                        else if (type == OperandType.MemoryFloat64)
                        {
                            operand.OperandSize = CodeOperandSize.Double;
                        }
                        else if (type == OperandType.MemoryFloat80)
                        {
                            operand.OperandSize = CodeOperandSize.LongDouble;
                        }

                        operands.SetOperand(i, operand);
                    }
                }

                if (opcode.ModRmInfo == ModRmInfo.All)
                {
                    int reg = (modRmByte & 0x38) >> 3;
                    for (int i = 0; i < opcode.Operands.Count; i++)
                    {
                        var type = opcode.Operands[i];
                        if (type == OperandType.RegisterByte)
                        {
                            operands.SetOperand(i, DecodeRb(reg));
                        }
                        else if (type == OperandType.RegisterWord)
                        {
                            operands.SetOperand(i, DecodeRw(reg, prefixes));
                        }
                        else if (type == OperandType.SegmentRegister)
                        {
                            operands.SetOperand(i, DecodeSreg(reg));
                        }
                    }
                }
            }

            for (int i = 0; i < opcode.Operands.Count; i++)
            {
                var type = opcode.Operands[i];
                if (IsKnownRegister(type))
                {
                    operands.SetOperand(i, new CodeOperand(DecodeKnownRegister(type, (prefixes & PrefixState.OperandSize) != 0)));
                }
                else if (type == OperandType.ImmediateByte)
                {
                    operands.SetOperand(i, new CodeOperand(CodeOperandType.Immediate, reader.ReadByte(), CodeOperandSize.Byte));
                }
                else if (type == OperandType.ImmediateByteExtend || type == OperandType.ImmediateRelativeByte)
                {
                    var operand = new CodeOperand(CodeOperandType.Immediate, (uint)(int)reader.ReadSByte(), GetOperandSize(false, prefixes));
                    if (type == OperandType.ImmediateRelativeByte)
                    {
                        operand.Type = CodeOperandType.RelativeJumpAddress;
                    }

                    operands.SetOperand(i, operand);
                }
                else if (type == OperandType.ImmediateInt16)
                {
                    operands.SetOperand(i, new CodeOperand(CodeOperandType.Immediate, reader.ReadUInt16(), CodeOperandSize.Word));
                }
                else if (type == OperandType.ImmediateInt32)
                {
                    operands.SetOperand(i, new CodeOperand(CodeOperandType.Immediate, reader.ReadUInt32(), CodeOperandSize.DoubleWord));
                }
                else if (type == OperandType.ImmediateWord)
                {
                    uint value;
                    if ((prefixes & PrefixState.OperandSize) == 0)
                    {
                        value = reader.ReadUInt16();
                    }
                    else
                    {
                        value = reader.ReadUInt32();
                    }

                    operands.SetOperand(i, new CodeOperand(CodeOperandType.Immediate, value, GetOperandSize(false, prefixes)));
                }
                else if (type == OperandType.ImmediateRelativeWord)
                {
                    uint value;
                    if ((prefixes & PrefixState.OperandSize) == 0)
                    {
                        value = (uint)(int)reader.ReadInt16();
                    }
                    else
                    {
                        value = reader.ReadUInt32();
                    }

                    operands.SetOperand(i, new CodeOperand(CodeOperandType.RelativeJumpAddress, value, GetOperandSize(false, prefixes)));
                }
                else if (type == OperandType.MemoryOffsetByte || type == OperandType.MemoryOffsetWord)
                {
                    uint value;
                    if ((prefixes & PrefixState.AddressSize) == 0)
                    {
                        value = (uint)(int)reader.ReadInt16();
                    }
                    else
                    {
                        value = reader.ReadUInt32();
                    }

                    operands.SetOperand(i, new CodeOperand(CodeMemoryBase.DisplacementOnly, value, GetOperandSize(type == OperandType.MemoryOffsetByte, prefixes)));
                }
                else if (type == OperandType.ImmediateFarPointer)
                {
                    uint value;
                    if ((prefixes & PrefixState.AddressSize) == 0)
                    {
                        value = reader.ReadUInt16();
                    }
                    else
                    {
                        value = reader.ReadUInt32();
                    }

                    ushort segment = reader.ReadUInt16();
                    operands.SetOperand(i, CodeOperand.FarPointer(segment, value));
                }
            }

            length = reader.Position;
            return(operands);
        }
Exemplo n.º 14
0
 public static int CalculateOperandLength(OpcodeInfo opcode, ReadOnlySpan <byte> rawData, PrefixState prefixes)
 {
     Decode(opcode, rawData, prefixes, out int length);
     return(length);
 }