using X86Disassembler.X86.Operands; namespace X86Disassembler.X86; using System.Text; using System.Collections.Generic; /// /// Core x86 instruction disassembler /// public class Disassembler { // The buffer containing the code to disassemble private readonly byte[] _codeBuffer; // The length of the buffer private readonly int _length; // The base address of the code private readonly ulong _baseAddress; // Segment override prefixes private static readonly byte[] SegmentOverridePrefixes = {0x26, 0x2E, 0x36, 0x3E, 0x64, 0x65}; /// /// Initializes a new instance of the Disassembler class /// /// The buffer containing the code to disassemble /// The base address of the code public Disassembler(byte[] codeBuffer, ulong baseAddress) { _codeBuffer = codeBuffer; _length = codeBuffer.Length; _baseAddress = baseAddress; } /// /// Checks if a byte is a segment override prefix /// /// The byte to check /// True if the byte is a segment override prefix private bool IsSegmentOverridePrefix(byte b) { return Array.IndexOf(SegmentOverridePrefixes, b) >= 0; } /// /// Gets the segment override name for a prefix byte /// /// The prefix byte /// The segment override name private string GetSegmentOverrideName(byte prefix) { return prefix switch { 0x26 => "es", 0x2E => "cs", 0x36 => "ss", 0x3E => "ds", 0x64 => "fs", 0x65 => "gs", _ => string.Empty }; } /// /// Disassembles the code buffer and returns the disassembled instructions /// /// A list of disassembled instructions public List Disassemble() { List instructions = new List(); // Create an instruction decoder InstructionDecoder decoder = new InstructionDecoder(_codeBuffer, _length); // Decode instructions until the end of the buffer is reached while (true) { int position = decoder.GetPosition(); // Check if we've reached the end of the buffer if (!decoder.CanReadByte()) { break; } // If no special case applies, decode normally Instruction? instruction = decoder.DecodeInstruction(); if (instruction != null) { // Adjust the instruction address to include the base address instruction.Address += _baseAddress; // Add the instruction to the list instructions.Add(instruction); } else { // If decoding failed, create a dummy instruction for the unknown byte byte unknownByte = decoder.ReadByte(); Instruction dummyInstruction = new Instruction { Address = _baseAddress + (uint) position, Type = InstructionType.Unknown, StructuredOperands = [OperandFactory.CreateImmediateOperand(unknownByte, 8),] }; instructions.Add(dummyInstruction); } } return instructions; } }