Esempio 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}]");
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Rebuilds the displayed content.
        /// </summary>
        /// <param name="operand">Operand to display.</param>
        /// <param name="format">Formatting information.</param>
        /// <returns>FrameworkElement to display as content.</returns>
        private FrameworkElement BuildContent(CodeOperand operand, IDebuggerTextSettings format)
        {
            switch (operand.Type)
            {
            case CodeOperandType.Immediate:
                return(BuildImmediateContent(operand.ImmediateValue));

            case CodeOperandType.Register:
                return(BuildRegisterContent(operand.RegisterValue));

            case CodeOperandType.MemoryAddress:
                return(BuildAddress16Content(operand));

            case CodeOperandType.RelativeJumpAddress:
                return(BuildJumpTargetContent((uint)(this.Instruction.EIP + this.Instruction.Length + (int)operand.ImmediateValue)));
            }

            return(null);
        }
Esempio n. 3
0
        private static string FormatSib(CodeOperand sibOperand)
        {
            sibRegisters.TryGetValue(sibOperand.Base, out var baseRegister);
            var scaleIndex = FormatScaleIndex(sibOperand.Scale, sibOperand.Index);

            if (baseRegister == null)
            {
                return($"[{sibOperand.ImmediateValue:X8}]{scaleIndex}");
            }
            else
            {
                if (sibOperand.ImmediateValue == 0)
                {
                    return($"[{baseRegister}]{scaleIndex}");
                }
                else
                {
                    return($"[{baseRegister}+{sibOperand.ImmediateValue:X8}]{scaleIndex}");
                }
            }
        }
Esempio n. 4
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);
        }
Esempio n. 5
0
        private FrameworkElement BuildAddress16Content(CodeOperand operand)
        {
            bool includeDisplacement = true;
            var  textBlock           = new TextBlock();

            var prefixes = this.Instruction.Prefixes;

            if (operand.OperandSize == CodeOperandSize.Byte)
            {
                textBlock.Inlines.Add("byte ptr ");
            }
            else if (operand.OperandSize == CodeOperandSize.Word && (prefixes & PrefixState.OperandSize) == 0)
            {
                textBlock.Inlines.Add("word ptr ");
            }
            else
            {
                textBlock.Inlines.Add("dword ptr ");
            }

            var segmentOverride = GetSegmentPrefix(prefixes);

            if (segmentOverride != null)
            {
                textBlock.Inlines.Add(NewRegisterRun(segmentOverride));
                textBlock.Inlines.Add(":");
            }

            textBlock.Inlines.Add("[");

            switch (operand.EffectiveAddress)
            {
            case CodeMemoryBase.DisplacementOnly:
                textBlock.Inlines.Add(NewImmediateRun(operand.ImmediateValue.ToString("X4")));
                includeDisplacement = false;
                break;

            case CodeMemoryBase.BX_plus_SI:
                textBlock.Inlines.Add(NewRegisterRun("bx"));
                textBlock.Inlines.Add("+");
                textBlock.Inlines.Add(NewRegisterRun("si"));
                break;

            case CodeMemoryBase.BX_plus_DI:
                textBlock.Inlines.Add(NewRegisterRun("bx"));
                textBlock.Inlines.Add("+");
                textBlock.Inlines.Add(NewRegisterRun("di"));
                break;

            case CodeMemoryBase.BP_plus_SI:
                textBlock.Inlines.Add(NewRegisterRun("bp"));
                textBlock.Inlines.Add("+");
                textBlock.Inlines.Add(NewRegisterRun("si"));
                break;

            case CodeMemoryBase.BP_plus_DI:
                textBlock.Inlines.Add(NewRegisterRun("bp"));
                textBlock.Inlines.Add("+");
                textBlock.Inlines.Add(NewRegisterRun("di"));
                break;

            case CodeMemoryBase.SI:
                textBlock.Inlines.Add(NewRegisterRun("si"));
                break;

            case CodeMemoryBase.DI:
                textBlock.Inlines.Add(NewRegisterRun("di"));
                break;

            case CodeMemoryBase.BX:
                textBlock.Inlines.Add(NewRegisterRun("bx"));
                break;

            case CodeMemoryBase.BP:
                textBlock.Inlines.Add(NewRegisterRun("bp"));
                break;
            }

            if (includeDisplacement && operand.ImmediateValue != 0)
            {
                int offset = (short)(ushort)operand.ImmediateValue;
                textBlock.Inlines.Add(offset >= 0 ? "+" : "-");
                textBlock.Inlines.Add(NewDisplacementRun(Math.Abs(offset).ToString()));
            }

            textBlock.Inlines.Add("]");

            return(textBlock);
        }