namespace X86Disassembler.X86.Handlers.String; /// /// Handler for string instructions (MOVS, STOS, LODS, SCAS) /// public class StringInstructionHandler : InstructionHandler { /// /// 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) { return IsStringInstruction(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 instruction.Mnemonic = OpcodeMap.GetMnemonic(opcode); // Set the operands instruction.Operands = GetStringOperands(opcode); return true; } /// /// Checks if the opcode is a string instruction /// /// The opcode to check /// True if the opcode is a string instruction private bool IsStringInstruction(byte opcode) { return opcode == 0xA4 || opcode == 0xA5 || // MOVS opcode == 0xAA || opcode == 0xAB || // STOS opcode == 0xAC || opcode == 0xAD || // LODS opcode == 0xAE || opcode == 0xAF; // SCAS } /// /// Gets the operands for a string instruction /// /// The string operation opcode /// The operands string private string GetStringOperands(byte stringOp) { switch (stringOp) { case 0xA4: // MOVSB return "byte ptr [edi], byte ptr [esi]"; case 0xA5: // MOVSD return "dword ptr [edi], dword ptr [esi]"; case 0xAA: // STOSB return "byte ptr [edi], al"; case 0xAB: // STOSD return "dword ptr [edi], eax"; case 0xAC: // LODSB return "al, byte ptr [esi]"; case 0xAD: // LODSD return "eax, dword ptr [esi]"; case 0xAE: // SCASB return "al, byte ptr [edi]"; case 0xAF: // SCASD return "eax, dword ptr [edi]"; default: return "??"; } } }