示例#1
0
        private void ProcessRegMemSegment(ref Operand operand, Argument argument, byte rmByte)
        {
            byte index = (byte)(rmByte & 0x7);

            operand.Type = OperandType.Register;
            operand.Register = registersSegment[index];
            if(buildString)
                InstructionText += operand.Register;
        }
示例#2
0
        private void ProcessRegMemRegister(ref Operand operand, Argument argument, byte rmByte)
        {
            byte index = (byte)(rmByte & 0x7);

            operand.Type = OperandType.Register;
            if (operand.Size == 8)
                operand.Register = registers8Bit[index];
            else if (operand.Size == 16)
                operand.Register = registers16Bit[index];
            else
                operand.Register = registers32Bit[index];

            if(buildString)
                InstructionText += operand.Register;
        }
示例#3
0
        private uint ProcessRegMemMemory(ref Operand operand, Argument argument, byte rmByte, uint offset)
        {
            byte mod, rm;

            operand.Type = OperandType.Memory;
            operand.Memory = regMemMemory16[rmByte & 0x7];

            mod = (byte)((rmByte >> 6) & 0x3);
            rm = (byte)(rmByte & 0x7);

            if (mod == 0 && rm == 6)
            {
                operand.Memory.Base = GeneralRegister.None;
                operand.Memory.Displacement = (short)ReadWord(offset);
                operand.Memory.Segment = SegmentRegister.DS;
                offset += 2;
            }
            else if (mod == 1)
                operand.Memory.Displacement = (sbyte)ReadByte(offset++);
            else if (mod == 2)
            {
                operand.Memory.Displacement = (short)ReadWord(offset);
                offset += 2;
            }

            if (OverrideSegment != SegmentRegister.Default)
                operand.Memory.Segment = OverrideSegment;

            if(buildString)
                InstructionText += operand.Memory;

            return offset;
        }
示例#4
0
        private uint ProcessRegMemMemory32(ref Operand operand, Argument argument, byte rmByte, uint offset)
        {
            byte mod, rm, reg;
            bool needDisp = false;

            operand.Type = OperandType.Memory;
            operand.Memory = regMemMemory32[rmByte & 0x7];

            mod = (byte)((rmByte >> 6) & 0x3);
            rm = (byte)(rmByte & 0x7);
            reg = (byte)((rmByte >> 3) & 0x7);

            if (rm == 4)
            {
                byte scale, baseIndex;
                MemoryOperand memory;

                if (!gotSIB)
                {
                    sibByte = ReadByte(offset++);
                    gotSIB = true;
                }

                baseIndex = (byte)(sibByte & 0x3f);
                scale = (byte)((sibByte >> 6) & 0x3);

                memory = regMemMemorySib[baseIndex];
                memory.Scale = scale;

                if ((baseIndex & 7) == 5)
                {
                    memory.Index = GeneralRegister.None;
                    needDisp = true;
                }

                operand.Memory.Base = memory.Base;
                operand.Memory.Index = memory.Index;
                operand.Memory.Segment = memory.Segment;
                operand.Memory.Scale = memory.Scale;
            }

            if (mod == 0 && rm == 5)
            {
                operand.Memory.Base = GeneralRegister.None;
                operand.Memory.Displacement = (int)ReadDWord(offset);
                operand.Memory.Segment = SegmentRegister.DS;
                offset += 4;
            }
            else if (rm == 4 && needDisp)
            {
                if (mod == 0)
                {
                    operand.Memory.Displacement = (int)ReadDWord(offset);
                    operand.Memory.Segment = SegmentRegister.DS;
                    offset += 4;
                }
                else if (mod == 1)
                {
                    operand.Memory.Displacement = (int)ReadByte(offset++);
                    operand.Memory.Segment = SegmentRegister.SS;
                    operand.Memory.Index = GeneralRegister.EBP;
                }
                else if (mod == 2)
                {
                    operand.Memory.Displacement = (int)ReadDWord(offset);
                    operand.Memory.Segment = SegmentRegister.SS;
                    operand.Memory.Index = GeneralRegister.EBP;
                    offset += 4;
                }
            }
            else if (mod == 1)
                operand.Memory.Displacement = (sbyte)ReadByte(offset++);
            else if (mod == 2)
            {
                operand.Memory.Displacement = (int)ReadDWord(offset);
                offset += 4;
            }

            if (OverrideSegment != SegmentRegister.Default)
                operand.Memory.Segment = OverrideSegment;

            if (buildString)
                InstructionText += operand.Memory;

            return offset;
        }
示例#5
0
        private uint ProcessArgument(Argument argument, int operandNumber, uint offset)
        {
            Operand operand = new Operand();

            if (argument.Size == 16 && !argument.IgnorePrefix)
                operand.Size = (uint)OperandSize;
            else
                operand.Size = argument.Size;

            switch (argument.Type)
            {
                case ArgumentType.Address:
                    operand.Type = OperandType.Address;
                    if (OperandSize == 32)
                    {
                        operand.Address = (uint)ReadDWord(offset);
                        offset += 4;
                        operand.Value = ReadWord(offset);
                    }
                    else
                    {
                        operand.Address = (uint)ReadWord(offset);
                        offset += 2;
                        operand.Value = ReadWord(offset);
                    }
                    offset += 2;
                    if(buildString)
                        InstructionText += operand.Value.ToString("X") + ":" + operand.Address.ToString("X");
                    break;
                case ArgumentType.Immediate:
                    operand.Type = OperandType.Immediate;
                    if (argument.SignExtend)
                    {
                        switch (operand.Size)
                        {
                            case 8:
                                operand.Size = 16;
                                operand.Value = (ushort)(short)(sbyte)ReadByte(offset);
                                break;
                            case 16:
                                operand.Size = 32;
                                operand.Value = (uint)(int)(short)ReadWord(offset);
                                break;
                        }
                        offset += argument.Size / 8;
                    }
                    else
                    {
                        operand.Value = readFunction(offset, (int)operand.Size);
                        offset += operand.Size / 8;
                    }
                    if(buildString)
                        InstructionText += operand;
                    break;
                case ArgumentType.ImmediateSuppressDefault:
                    operand.Value = readFunction(offset, (int)operand.Size);
                    offset += operand.Size / 8;
                    operand.Type = OperandType.Immediate;
                    if (operand.Value != 10)
                        InstructionText += operand;
                    break;
                case ArgumentType.Relative:
                    operand.Type = OperandType.Immediate;
                    operand.Value = readFunction(offset, (int)operand.Size);
                    offset += operand.Size / 8;
                    if (buildString)
                    {
                        if (operand.SignedValue < 0)
                            InstructionText += "-" + (-operand.SignedValue).ToString("X") + " (" + ((virtualAddr & 0xffff0000) + (ushort)((ushort)virtualAddr + operand.Value + offset)).ToString("X") + ")";
                        else
                            InstructionText += operand.Value.ToString("X") + " (" + ((virtualAddr & 0xffff0000) + (ushort)((ushort)virtualAddr + operand.Value + offset)).ToString("X") + ")";
                    }
                    break;
                case ArgumentType.RegMem:
                case ArgumentType.RegMemGeneral:
                case ArgumentType.RegMemMemory:
                case ArgumentType.RegMemSegment:
                case ArgumentType.RegMemControl:
                    if (!gotRM)
                    {
                        rmByte = ReadByte(offset++);
                        gotRM = true;
                    }
                    switch (argument.Type)
                    {
                        case ArgumentType.RegMem:
                            if (rmByte >= 0xc0)
                                ProcessRegMemRegister(ref operand, argument, rmByte);
                            else
                            {
                                if(CodeSize == 16)
                                    offset = ProcessRegMemMemory(ref operand, argument, rmByte, offset);
                                else
                                    offset = ProcessRegMemMemory32(ref operand, argument, rmByte, offset);
                            }
                            break;
                        case ArgumentType.RegMemGeneral:
                            ProcessRegMemRegister(ref operand, argument, (byte)(rmByte >> 3));
                            break;
                        case ArgumentType.RegMemMemory:
                            if (AddressSize == 16)
                                offset = ProcessRegMemMemory(ref operand, argument, rmByte, offset);
                            else
                                offset = ProcessRegMemMemory32(ref operand, argument, rmByte, offset);
                            break;
                        case ArgumentType.RegMemSegment:
                            ProcessRegMemSegment(ref operand, argument, (byte)(rmByte >> 3));
                            break;
                        case ArgumentType.RegMemControl:
                            ProcessRegMemControl(ref operand, argument, (byte)(rmByte >> 3));
                            break;
                        default:
                            System.Diagnostics.Debugger.Break();
                            break;
                    }
                    break;
                case ArgumentType.GeneralRegister:
                    operand.Type = OperandType.Register;
                    if (operand.Size == 8)
                        operand.Register = registers8Bit[argument.Value];
                    else if(operand.Size == 16)
                        operand.Register = registers16Bit[argument.Value];
                    else
                        operand.Register = registers32Bit[argument.Value];

                    if(buildString)
                        InstructionText += operand.Register;
                    break;
                case ArgumentType.SegmentRegister:
                    operand.Type = OperandType.Register;
                    operand.Register = registersSegment[argument.Value];
                    if(buildString)
                        InstructionText += operand.Register;
                    break;
                case ArgumentType.Memory:
                    operand.Type = OperandType.Memory;
                    if (argument.UsesES)
                    {
                        operand.Memory.Base = GeneralRegister.EDI;
                        operand.Memory.Segment = SegmentRegister.ES;
                    }
                    else
                    {
                        operand.Memory.Base = GeneralRegister.ESI;
                        if (OverrideSegment == SegmentRegister.Default)
                            operand.Memory.Segment = SegmentRegister.DS;
                        else
                            operand.Memory.Segment = OverrideSegment;
                    }
                    operand.Memory.Index = GeneralRegister.None;
                    operand.Memory.Size = CodeSize;

                    if(buildString)
                        InstructionText += operand.Memory;
                    break;
                case ArgumentType.Offset:
                    operand.Type = OperandType.Memory;

                    operand.Memory.Index = GeneralRegister.None;
                    operand.Memory.Base = GeneralRegister.None;
                    operand.Memory.Displacement = (int)readFunction(offset, AddressSize);
                    offset += (uint)(AddressSize / 8);
                    if (OverrideSegment == SegmentRegister.Default)
                        operand.Memory.Segment = SegmentRegister.DS;
                    else
                        operand.Memory.Segment = OverrideSegment;

                    if(buildString)
                        InstructionText += operand.Memory;
                    break;
                case ArgumentType.Constant:
                    operand.Type = OperandType.Immediate;
                    operand.Value = (uint)argument.Value;

                    if(buildString)
                        InstructionText += operand;
                    break;
                default:
                    System.Diagnostics.Debugger.Break();
                    break;
            }

            operands[operandNumber] = operand;

            return offset;
        }