namespace X86Disassembler.X86.Handlers.String; /// /// Handler for string instructions (MOVS, STOS, LODS, SCAS) /// public class StringInstructionHandler : InstructionHandler { // Dictionary mapping opcodes to their mnemonics private static readonly Dictionary _mnemonics = new Dictionary { { 0xA4, "movs" }, // MOVSB { 0xA5, "movs" }, // MOVSD { 0xAA, "stos" }, // STOSB { 0xAB, "stos" }, // STOSD { 0xAC, "lods" }, // LODSB { 0xAD, "lods" }, // LODSD { 0xAE, "scas" }, // SCASB { 0xAF, "scas" } // SCASD }; /// /// Initializes a new instance of the StringInstructionHandler class /// /// The buffer containing the code to decode /// The instruction decoder that owns this handler /// The length of the buffer public StringInstructionHandler(byte[] codeBuffer, InstructionDecoder decoder, int length) : base(codeBuffer, decoder, length) { } /// /// Checks if this handler can handle the given opcode /// /// The opcode to check /// True if this handler can handle the opcode public override bool CanHandle(byte opcode) { // Check if the opcode is a string instruction return _mnemonics.ContainsKey(opcode); } /// /// Decodes a string instruction /// /// The opcode to decode /// The instruction to populate /// True if the instruction was successfully decoded public override bool Decode(byte opcode, Instruction instruction) { // Set the mnemonic if (_mnemonics.TryGetValue(opcode, out string? mnemonic)) { instruction.Mnemonic = mnemonic; } else { // This shouldn't happen if CanHandle is called first return false; } // Set the operands based on the string operation switch (opcode) { case 0xA4: // MOVSB instruction.Operands = "byte ptr [edi], byte ptr [esi]"; break; case 0xA5: // MOVSD instruction.Operands = "dword ptr [edi], dword ptr [esi]"; break; case 0xAA: // STOSB instruction.Operands = "byte ptr [edi], al"; break; case 0xAB: // STOSD instruction.Operands = "dword ptr [edi], eax"; break; case 0xAC: // LODSB instruction.Operands = "al, byte ptr [esi]"; break; case 0xAD: // LODSD instruction.Operands = "eax, dword ptr [esi]"; break; case 0xAE: // SCASB instruction.Operands = "al, byte ptr [edi]"; break; case 0xAF: // SCASD instruction.Operands = "eax, dword ptr [edi]"; break; default: instruction.Operands = "??"; break; } return true; } }