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; }
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; }
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; }
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; }
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; }