diff --git a/X86Disassembler/X86/Handlers/Idiv/IdivRm32Handler.cs b/X86Disassembler/X86/Handlers/Idiv/IdivRm32Handler.cs index c94df86..aa61dfe 100644 --- a/X86Disassembler/X86/Handlers/Idiv/IdivRm32Handler.cs +++ b/X86Disassembler/X86/Handlers/Idiv/IdivRm32Handler.cs @@ -57,13 +57,7 @@ public class IdivRm32Handler : InstructionHandler // Read the ModR/M byte // For IDIV r/m32 (0xF7 /7): // - The r/m field with mod specifies the operand (register or memory) - var (mod, reg, rm, operand) = ModRMDecoder.ReadModRM(); - - // Verify that the reg field is 7 (IDIV) - if (reg != RegisterIndex.Di) - { - return false; - } + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); // Set the structured operands // IDIV has only one operand diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs index 8990779..b5105d1 100644 --- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs +++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs @@ -23,6 +23,7 @@ using X86Disassembler.X86.Handlers.Pop; using X86Disassembler.X86.Handlers.Push; using X86Disassembler.X86.Handlers.Ret; using X86Disassembler.X86.Handlers.Sbb; +using X86Disassembler.X86.Handlers.Shift; using X86Disassembler.X86.Handlers.String; using X86Disassembler.X86.Handlers.Sub; using X86Disassembler.X86.Handlers.Test; @@ -56,7 +57,7 @@ public class InstructionHandlerFactory private void RegisterAllHandlers() { // Register specific instruction handlers - _handlers.Add(new Nop.Int3Handler(_decoder)); + _handlers.Add(new Int3Handler(_decoder)); // Register handlers in order of priority (most specific first) RegisterSbbHandlers(); // SBB instructions @@ -91,6 +92,7 @@ public class InstructionHandlerFactory RegisterNopHandlers(); // Register NOP handlers RegisterBitHandlers(); // Register bit manipulation handlers RegisterMiscHandlers(); // Register miscellaneous instructions + RegisterShiftHandlers(); // Register shift and rotate instructions } /// @@ -477,7 +479,7 @@ public class InstructionHandlerFactory private void RegisterMiscHandlers() { // Register miscellaneous instruction handlers - _handlers.Add(new IntHandler(_decoder)); // INT (opcode 0xCD) + _handlers.Add(new IntImm8Handler(_decoder)); // INT (opcode 0xCD) _handlers.Add(new IntoHandler(_decoder)); // INTO (opcode 0xCE) _handlers.Add(new IretHandler(_decoder)); // IRET (opcode 0xCF) _handlers.Add(new CpuidHandler(_decoder)); // CPUID (opcode 0x0F 0xA2) @@ -489,6 +491,68 @@ public class InstructionHandlerFactory _handlers.Add(new OutHandler(_decoder)); // OUT (opcodes 0xE6, 0xE7, 0xEE, 0xEF) } + /// + /// Registers all shift and rotate instruction handlers + /// + private void RegisterShiftHandlers() + { + // SHL (Shift Left) handlers + _handlers.Add(new ShlRm8By1Handler(_decoder)); // SHL r/m8, 1 (0xD0 /4) + _handlers.Add(new ShlRm8ByClHandler(_decoder)); // SHL r/m8, CL (0xD2 /4) + _handlers.Add(new ShlRm8ByImmHandler(_decoder)); // SHL r/m8, imm8 (0xC0 /4) + _handlers.Add(new ShlRm32By1Handler(_decoder)); // SHL r/m32, 1 (0xD1 /4) + _handlers.Add(new ShlRm32ByClHandler(_decoder)); // SHL r/m32, CL (0xD3 /4) + _handlers.Add(new ShlRm32ByImmHandler(_decoder)); // SHL r/m32, imm8 (0xC1 /4) + + // SHR (Shift Right) handlers + _handlers.Add(new ShrRm8By1Handler(_decoder)); // SHR r/m8, 1 (0xD0 /5) + _handlers.Add(new ShrRm8ByClHandler(_decoder)); // SHR r/m8, CL (0xD2 /5) + _handlers.Add(new ShrRm8ByImmHandler(_decoder)); // SHR r/m8, imm8 (0xC0 /5) + _handlers.Add(new ShrRm32By1Handler(_decoder)); // SHR r/m32, 1 (0xD1 /5) + _handlers.Add(new ShrRm32ByClHandler(_decoder)); // SHR r/m32, CL (0xD3 /5) + _handlers.Add(new ShrRm32ByImmHandler(_decoder)); // SHR r/m32, imm8 (0xC1 /5) + + // SAR (Shift Arithmetic Right) handlers + _handlers.Add(new SarRm8By1Handler(_decoder)); // SAR r/m8, 1 (0xD0 /7) + _handlers.Add(new SarRm8ByClHandler(_decoder)); // SAR r/m8, CL (0xD2 /7) + _handlers.Add(new SarRm8ByImmHandler(_decoder)); // SAR r/m8, imm8 (0xC0 /7) + _handlers.Add(new SarRm32By1Handler(_decoder)); // SAR r/m32, 1 (0xD1 /7) + _handlers.Add(new SarRm32ByClHandler(_decoder)); // SAR r/m32, CL (0xD3 /7) + _handlers.Add(new SarRm32ByImmHandler(_decoder)); // SAR r/m32, imm8 (0xC1 /7) + + // ROL (Rotate Left) handlers + _handlers.Add(new RolRm8By1Handler(_decoder)); // ROL r/m8, 1 (0xD0 /0) + _handlers.Add(new RolRm8ByClHandler(_decoder)); // ROL r/m8, CL (0xD2 /0) + _handlers.Add(new RolRm8ByImmHandler(_decoder)); // ROL r/m8, imm8 (0xC0 /0) + _handlers.Add(new RolRm32By1Handler(_decoder)); // ROL r/m32, 1 (0xD1 /0) + _handlers.Add(new RolRm32ByClHandler(_decoder)); // ROL r/m32, CL (0xD3 /0) + _handlers.Add(new RolRm32ByImmHandler(_decoder)); // ROL r/m32, imm8 (0xC1 /0) + + // ROR (Rotate Right) handlers + _handlers.Add(new RorRm8By1Handler(_decoder)); // ROR r/m8, 1 (0xD0 /1) + _handlers.Add(new RorRm8ByClHandler(_decoder)); // ROR r/m8, CL (0xD2 /1) + _handlers.Add(new RorRm8ByImmHandler(_decoder)); // ROR r/m8, imm8 (0xC0 /1) + _handlers.Add(new RorRm32By1Handler(_decoder)); // ROR r/m32, 1 (0xD1 /1) + _handlers.Add(new RorRm32ByClHandler(_decoder)); // ROR r/m32, CL (0xD3 /1) + _handlers.Add(new RorRm32ByImmHandler(_decoder)); // ROR r/m32, imm8 (0xC1 /1) + + // RCL (Rotate Carry Left) handlers + _handlers.Add(new RclRm8By1Handler(_decoder)); // RCL r/m8, 1 (0xD0 /2) + _handlers.Add(new RclRm8ByClHandler(_decoder)); // RCL r/m8, CL (0xD2 /2) + _handlers.Add(new RclRm8ByImmHandler(_decoder)); // RCL r/m8, imm8 (0xC0 /2) + _handlers.Add(new RclRm32By1Handler(_decoder)); // RCL r/m32, 1 (0xD1 /2) + _handlers.Add(new RclRm32ByClHandler(_decoder)); // RCL r/m32, CL (0xD3 /2) + _handlers.Add(new RclRm32ByImmHandler(_decoder)); // RCL r/m32, imm8 (0xC1 /2) + + // RCR (Rotate Carry Right) handlers + _handlers.Add(new RcrRm8By1Handler(_decoder)); // RCR r/m8, 1 (0xD0 /3) + _handlers.Add(new RcrRm8ByClHandler(_decoder)); // RCR r/m8, CL (0xD2 /3) + _handlers.Add(new RcrRm8ByImmHandler(_decoder)); // RCR r/m8, imm8 (0xC0 /3) + _handlers.Add(new RcrRm32By1Handler(_decoder)); // RCR r/m32, 1 (0xD1 /3) + _handlers.Add(new RcrRm32ByClHandler(_decoder)); // RCR r/m32, CL (0xD3 /3) + _handlers.Add(new RcrRm32ByImmHandler(_decoder)); // RCR r/m32, imm8 (0xC1 /3) + } + /// /// Registers all bit manipulation instruction handlers /// diff --git a/X86Disassembler/X86/Handlers/Misc/IntHandler.cs b/X86Disassembler/X86/Handlers/Misc/IntImm8Handler.cs similarity index 94% rename from X86Disassembler/X86/Handlers/Misc/IntHandler.cs rename to X86Disassembler/X86/Handlers/Misc/IntImm8Handler.cs index a5e4ee6..54d3a85 100644 --- a/X86Disassembler/X86/Handlers/Misc/IntHandler.cs +++ b/X86Disassembler/X86/Handlers/Misc/IntImm8Handler.cs @@ -5,13 +5,13 @@ using X86Disassembler.X86.Operands; /// /// Handler for INT instruction (0xCD) /// -public class IntHandler : InstructionHandler +public class IntImm8Handler : InstructionHandler { /// /// Initializes a new instance of the IntHandler class /// /// The instruction decoder that owns this handler - public IntHandler(InstructionDecoder decoder) + public IntImm8Handler(InstructionDecoder decoder) : base(decoder) { } diff --git a/X86Disassembler/X86/Handlers/Nop/Int3Handler.cs b/X86Disassembler/X86/Handlers/Nop/Int3Handler.cs index da1a05b..5d54b77 100644 --- a/X86Disassembler/X86/Handlers/Nop/Int3Handler.cs +++ b/X86Disassembler/X86/Handlers/Nop/Int3Handler.cs @@ -35,7 +35,7 @@ public class Int3Handler : InstructionHandler public override bool Decode(byte opcode, Instruction instruction) { // Set the instruction type - instruction.Type = InstructionType.Int; + instruction.Type = InstructionType.Int3; // INT3 has no operands instruction.StructuredOperands = []; diff --git a/X86Disassembler/X86/Handlers/Shift/RclRm32By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/RclRm32By1Handler.cs new file mode 100644 index 0000000..15e07bd --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RclRm32By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCL r/m32, 1 instruction (0xD1 /2) +/// +public class RclRm32By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the RclRm32By1Handler class + /// + /// The instruction decoder that owns this handler + public RclRm32By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCL r/m32, 1 is encoded as 0xD1 /2 + if (opcode != 0xD1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 2 (RCL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 2; // 2 = RCL + } + + /// + /// Decodes a RCL r/m32, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RclRm32ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/RclRm32ByClHandler.cs new file mode 100644 index 0000000..98a99f5 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RclRm32ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCL r/m32, CL instruction (0xD3 /2) +/// +public class RclRm32ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RclRm32ByClHandler class + /// + /// The instruction decoder that owns this handler + public RclRm32ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCL r/m32, CL is encoded as 0xD3 /2 + if (opcode != 0xD3) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 2 (RCL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 2; // 2 = RCL + } + + /// + /// Decodes a RCL r/m32, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RclRm32ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/RclRm32ByImmHandler.cs new file mode 100644 index 0000000..46ab95d --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RclRm32ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCL r/m32, imm8 instruction (0xC1 /2) +/// +public class RclRm32ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RclRm32ByImmHandler class + /// + /// The instruction decoder that owns this handler + public RclRm32ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCL r/m32, imm8 is encoded as 0xC1 /2 + if (opcode != 0xC1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 2 (RCL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 2; // 2 = RCL + } + + /// + /// Decodes a RCL r/m32, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (rotate count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the rotate count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RclRm8By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/RclRm8By1Handler.cs new file mode 100644 index 0000000..f737938 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RclRm8By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCL r/m8, 1 instruction (0xD0 /2) +/// +public class RclRm8By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the RclRm8By1Handler class + /// + /// The instruction decoder that owns this handler + public RclRm8By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCL r/m8, 1 is encoded as 0xD0 /2 + if (opcode != 0xD0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 2 (RCL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 2; // 2 = RCL + } + + /// + /// Decodes a RCL r/m8, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RclRm8ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/RclRm8ByClHandler.cs new file mode 100644 index 0000000..9e962ba --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RclRm8ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCL r/m8, CL instruction (0xD2 /2) +/// +public class RclRm8ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RclRm8ByClHandler class + /// + /// The instruction decoder that owns this handler + public RclRm8ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCL r/m8, CL is encoded as 0xD2 /2 + if (opcode != 0xD2) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 2 (RCL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 2; // 2 = RCL + } + + /// + /// Decodes a RCL r/m8, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RclRm8ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/RclRm8ByImmHandler.cs new file mode 100644 index 0000000..e9cdbbd --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RclRm8ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCL r/m8, imm8 instruction (0xC0 /2) +/// +public class RclRm8ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RclRm8ByImmHandler class + /// + /// The instruction decoder that owns this handler + public RclRm8ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCL r/m8, imm8 is encoded as 0xC0 /2 + if (opcode != 0xC0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 2 (RCL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 2; // 2 = RCL + } + + /// + /// Decodes a RCL r/m8, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (rotate count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the rotate count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RcrRm32By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/RcrRm32By1Handler.cs new file mode 100644 index 0000000..910a62d --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RcrRm32By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCR r/m32, 1 instruction (0xD1 /3) +/// +public class RcrRm32By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the RcrRm32By1Handler class + /// + /// The instruction decoder that owns this handler + public RcrRm32By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCR r/m32, 1 is encoded as 0xD1 /3 + if (opcode != 0xD1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 3 (RCR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 3; // 3 = RCR + } + + /// + /// Decodes a RCR r/m32, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RcrRm32ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/RcrRm32ByClHandler.cs new file mode 100644 index 0000000..7c52efe --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RcrRm32ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCR r/m32, CL instruction (0xD3 /3) +/// +public class RcrRm32ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RcrRm32ByClHandler class + /// + /// The instruction decoder that owns this handler + public RcrRm32ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCR r/m32, CL is encoded as 0xD3 /3 + if (opcode != 0xD3) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 3 (RCR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 3; // 3 = RCR + } + + /// + /// Decodes a RCR r/m32, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RcrRm32ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/RcrRm32ByImmHandler.cs new file mode 100644 index 0000000..e2d9d7d --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RcrRm32ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCR r/m32, imm8 instruction (0xC1 /3) +/// +public class RcrRm32ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RcrRm32ByImmHandler class + /// + /// The instruction decoder that owns this handler + public RcrRm32ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCR r/m32, imm8 is encoded as 0xC1 /3 + if (opcode != 0xC1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 3 (RCR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 3; // 3 = RCR + } + + /// + /// Decodes a RCR r/m32, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (rotate count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the rotate count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RcrRm8By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/RcrRm8By1Handler.cs new file mode 100644 index 0000000..1054715 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RcrRm8By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCR r/m8, 1 instruction (0xD0 /3) +/// +public class RcrRm8By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the RcrRm8By1Handler class + /// + /// The instruction decoder that owns this handler + public RcrRm8By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCR r/m8, 1 is encoded as 0xD0 /3 + if (opcode != 0xD0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 3 (RCR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 3; // 3 = RCR + } + + /// + /// Decodes a RCR r/m8, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RcrRm8ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/RcrRm8ByClHandler.cs new file mode 100644 index 0000000..c2f8baa --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RcrRm8ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCR r/m8, CL instruction (0xD2 /3) +/// +public class RcrRm8ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RcrRm8ByClHandler class + /// + /// The instruction decoder that owns this handler + public RcrRm8ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCR r/m8, CL is encoded as 0xD2 /3 + if (opcode != 0xD2) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 3 (RCR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 3; // 3 = RCR + } + + /// + /// Decodes a RCR r/m8, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RcrRm8ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/RcrRm8ByImmHandler.cs new file mode 100644 index 0000000..ce0aed3 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RcrRm8ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for RCR r/m8, imm8 instruction (0xC0 /3) +/// +public class RcrRm8ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RcrRm8ByImmHandler class + /// + /// The instruction decoder that owns this handler + public RcrRm8ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // RCR r/m8, imm8 is encoded as 0xC0 /3 + if (opcode != 0xC0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 3 (RCR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 3; // 3 = RCR + } + + /// + /// Decodes a RCR r/m8, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rcr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (rotate count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the rotate count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RolRm32By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/RolRm32By1Handler.cs new file mode 100644 index 0000000..2291b4f --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RolRm32By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROL r/m32, 1 instruction (0xD1 /0) +/// +public class RolRm32By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the RolRm32By1Handler class + /// + /// The instruction decoder that owns this handler + public RolRm32By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROL r/m32, 1 is encoded as 0xD1 /0 + if (opcode != 0xD1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 0 (ROL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 0; // 0 = ROL + } + + /// + /// Decodes a ROL r/m32, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rol; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RolRm32ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/RolRm32ByClHandler.cs new file mode 100644 index 0000000..59b85c5 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RolRm32ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROL r/m32, CL instruction (0xD3 /0) +/// +public class RolRm32ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RolRm32ByClHandler class + /// + /// The instruction decoder that owns this handler + public RolRm32ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROL r/m32, CL is encoded as 0xD3 /0 + if (opcode != 0xD3) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 0 (ROL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 0; // 0 = ROL + } + + /// + /// Decodes a ROL r/m32, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rol; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RolRm32ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/RolRm32ByImmHandler.cs new file mode 100644 index 0000000..c643112 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RolRm32ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROL r/m32, imm8 instruction (0xC1 /0) +/// +public class RolRm32ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RolRm32ByImmHandler class + /// + /// The instruction decoder that owns this handler + public RolRm32ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROL r/m32, imm8 is encoded as 0xC1 /0 + if (opcode != 0xC1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 0 (ROL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 0; // 0 = ROL + } + + /// + /// Decodes a ROL r/m32, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rol; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (rotate count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the rotate count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RolRm8By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/RolRm8By1Handler.cs new file mode 100644 index 0000000..5bc15e4 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RolRm8By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROL r/m8, 1 instruction (0xD0 /0) +/// +public class RolRm8By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the RolRm8By1Handler class + /// + /// The instruction decoder that owns this handler + public RolRm8By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROL r/m8, 1 is encoded as 0xD0 /0 + if (opcode != 0xD0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 0 (ROL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 0; // 0 = ROL + } + + /// + /// Decodes a ROL r/m8, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rol; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RolRm8ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/RolRm8ByClHandler.cs new file mode 100644 index 0000000..4e5c575 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RolRm8ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROL r/m8, CL instruction (0xD2 /0) +/// +public class RolRm8ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RolRm8ByClHandler class + /// + /// The instruction decoder that owns this handler + public RolRm8ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROL r/m8, CL is encoded as 0xD2 /0 + if (opcode != 0xD2) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 0 (ROL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 0; // 0 = ROL + } + + /// + /// Decodes a ROL r/m8, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rol; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RolRm8ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/RolRm8ByImmHandler.cs new file mode 100644 index 0000000..387c4d8 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RolRm8ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROL r/m8, imm8 instruction (0xC0 /0) +/// +public class RolRm8ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RolRm8ByImmHandler class + /// + /// The instruction decoder that owns this handler + public RolRm8ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROL r/m8, imm8 is encoded as 0xC0 /0 + if (opcode != 0xC0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 0 (ROL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 0; // 0 = ROL + } + + /// + /// Decodes a ROL r/m8, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Rol; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (rotate count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the rotate count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RorRm32By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/RorRm32By1Handler.cs new file mode 100644 index 0000000..c916fac --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RorRm32By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROR r/m32, 1 instruction (0xD1 /1) +/// +public class RorRm32By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the RorRm32By1Handler class + /// + /// The instruction decoder that owns this handler + public RorRm32By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROR r/m32, 1 is encoded as 0xD1 /1 + if (opcode != 0xD1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 1 (ROR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 1; // 1 = ROR + } + + /// + /// Decodes a ROR r/m32, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Ror; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RorRm32ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/RorRm32ByClHandler.cs new file mode 100644 index 0000000..17a36b1 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RorRm32ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROR r/m32, CL instruction (0xD3 /1) +/// +public class RorRm32ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RorRm32ByClHandler class + /// + /// The instruction decoder that owns this handler + public RorRm32ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROR r/m32, CL is encoded as 0xD3 /1 + if (opcode != 0xD3) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 1 (ROR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 1; // 1 = ROR + } + + /// + /// Decodes a ROR r/m32, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Ror; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RorRm32ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/RorRm32ByImmHandler.cs new file mode 100644 index 0000000..a4a47e0 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RorRm32ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROR r/m32, imm8 instruction (0xC1 /1) +/// +public class RorRm32ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RorRm32ByImmHandler class + /// + /// The instruction decoder that owns this handler + public RorRm32ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROR r/m32, imm8 is encoded as 0xC1 /1 + if (opcode != 0xC1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 1 (ROR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 1; // 1 = ROR + } + + /// + /// Decodes a ROR r/m32, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Ror; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (rotate count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the rotate count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RorRm8By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/RorRm8By1Handler.cs new file mode 100644 index 0000000..7bfc20c --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RorRm8By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROR r/m8, 1 instruction (0xD0 /1) +/// +public class RorRm8By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the RorRm8By1Handler class + /// + /// The instruction decoder that owns this handler + public RorRm8By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROR r/m8, 1 is encoded as 0xD0 /1 + if (opcode != 0xD0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 1 (ROR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 1; // 1 = ROR + } + + /// + /// Decodes a ROR r/m8, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Ror; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RorRm8ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/RorRm8ByClHandler.cs new file mode 100644 index 0000000..35bf3f3 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RorRm8ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROR r/m8, CL instruction (0xD2 /1) +/// +public class RorRm8ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RorRm8ByClHandler class + /// + /// The instruction decoder that owns this handler + public RorRm8ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROR r/m8, CL is encoded as 0xD2 /1 + if (opcode != 0xD2) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 1 (ROR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 1; // 1 = ROR + } + + /// + /// Decodes a ROR r/m8, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Ror; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/RorRm8ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/RorRm8ByImmHandler.cs new file mode 100644 index 0000000..500f572 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/RorRm8ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for ROR r/m8, imm8 instruction (0xC0 /1) +/// +public class RorRm8ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the RorRm8ByImmHandler class + /// + /// The instruction decoder that owns this handler + public RorRm8ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // ROR r/m8, imm8 is encoded as 0xC0 /1 + if (opcode != 0xC0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 1 (ROR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 1; // 1 = ROR + } + + /// + /// Decodes a ROR r/m8, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Ror; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (rotate count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the rotate count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/SarRm32By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/SarRm32By1Handler.cs new file mode 100644 index 0000000..ef09752 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/SarRm32By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SAR r/m32, 1 instruction (0xD1 /7) +/// +public class SarRm32By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the SarRm32By1Handler class + /// + /// The instruction decoder that owns this handler + public SarRm32By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SAR r/m32, 1 is encoded as 0xD1 /7 + if (opcode != 0xD1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 7 (SAR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 7; // 7 = SAR + } + + /// + /// Decodes a SAR r/m32, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Sar; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/SarRm32ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/SarRm32ByClHandler.cs new file mode 100644 index 0000000..1542336 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/SarRm32ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SAR r/m32, CL instruction (0xD3 /7) +/// +public class SarRm32ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the SarRm32ByClHandler class + /// + /// The instruction decoder that owns this handler + public SarRm32ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SAR r/m32, CL is encoded as 0xD3 /7 + if (opcode != 0xD3) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 7 (SAR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 7; // 7 = SAR + } + + /// + /// Decodes a SAR r/m32, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Sar; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/SarRm32ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/SarRm32ByImmHandler.cs new file mode 100644 index 0000000..942fc61 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/SarRm32ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SAR r/m32, imm8 instruction (0xC1 /7) +/// +public class SarRm32ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the SarRm32ByImmHandler class + /// + /// The instruction decoder that owns this handler + public SarRm32ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SAR r/m32, imm8 is encoded as 0xC1 /7 + if (opcode != 0xC1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 7 (SAR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 7; // 7 = SAR + } + + /// + /// Decodes a SAR r/m32, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Sar; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (shift count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the shift count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/SarRm8By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/SarRm8By1Handler.cs new file mode 100644 index 0000000..3e6f9ee --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/SarRm8By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SAR r/m8, 1 instruction (0xD0 /7) +/// +public class SarRm8By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the SarRm8By1Handler class + /// + /// The instruction decoder that owns this handler + public SarRm8By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SAR r/m8, 1 is encoded as 0xD0 /7 + if (opcode != 0xD0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 7 (SAR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 7; // 7 = SAR + } + + /// + /// Decodes a SAR r/m8, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Sar; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/SarRm8ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/SarRm8ByClHandler.cs new file mode 100644 index 0000000..02d3e09 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/SarRm8ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SAR r/m8, CL instruction (0xD2 /7) +/// +public class SarRm8ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the SarRm8ByClHandler class + /// + /// The instruction decoder that owns this handler + public SarRm8ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SAR r/m8, CL is encoded as 0xD2 /7 + if (opcode != 0xD2) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 7 (SAR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 7; // 7 = SAR + } + + /// + /// Decodes a SAR r/m8, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Sar; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/SarRm8ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/SarRm8ByImmHandler.cs new file mode 100644 index 0000000..4fcbf4e --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/SarRm8ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SAR r/m8, imm8 instruction (0xC0 /7) +/// +public class SarRm8ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the SarRm8ByImmHandler class + /// + /// The instruction decoder that owns this handler + public SarRm8ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SAR r/m8, imm8 is encoded as 0xC0 /7 + if (opcode != 0xC0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 7 (SAR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 7; // 7 = SAR + } + + /// + /// Decodes a SAR r/m8, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Sar; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (shift count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the shift count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShlRm32By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/ShlRm32By1Handler.cs new file mode 100644 index 0000000..92358e0 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShlRm32By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHL r/m32, 1 instruction (0xD1 /4) +/// +public class ShlRm32By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShlRm32By1Handler class + /// + /// The instruction decoder that owns this handler + public ShlRm32By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHL r/m32, 1 is encoded as 0xD1 /4 + if (opcode != 0xD1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 4 (SHL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 4; // 4 = SHL + } + + /// + /// Decodes a SHL r/m32, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShlRm32ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/ShlRm32ByClHandler.cs new file mode 100644 index 0000000..330d7d1 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShlRm32ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHL r/m32, CL instruction (0xD3 /4) +/// +public class ShlRm32ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShlRm32ByClHandler class + /// + /// The instruction decoder that owns this handler + public ShlRm32ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHL r/m32, CL is encoded as 0xD3 /4 + if (opcode != 0xD3) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 4 (SHL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 4; // 4 = SHL + } + + /// + /// Decodes a SHL r/m32, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShlRm32ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/ShlRm32ByImmHandler.cs new file mode 100644 index 0000000..b53effb --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShlRm32ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHL r/m32, imm8 instruction (0xC1 /4) +/// +public class ShlRm32ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShlRm32ByImmHandler class + /// + /// The instruction decoder that owns this handler + public ShlRm32ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHL r/m32, imm8 is encoded as 0xC1 /4 + if (opcode != 0xC1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 4 (SHL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 4; // 4 = SHL + } + + /// + /// Decodes a SHL r/m32, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (shift count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the shift count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShlRm8By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/ShlRm8By1Handler.cs new file mode 100644 index 0000000..075a6f2 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShlRm8By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHL r/m8, 1 instruction (0xD0 /4) +/// +public class ShlRm8By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShlRm8By1Handler class + /// + /// The instruction decoder that owns this handler + public ShlRm8By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHL r/m8, 1 is encoded as 0xD0 /4 + if (opcode != 0xD0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 4 (SHL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 4; // 4 = SHL + } + + /// + /// Decodes a SHL r/m8, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShlRm8ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/ShlRm8ByClHandler.cs new file mode 100644 index 0000000..cf857af --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShlRm8ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHL r/m8, CL instruction (0xD2 /4) +/// +public class ShlRm8ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShlRm8ByClHandler class + /// + /// The instruction decoder that owns this handler + public ShlRm8ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHL r/m8, CL is encoded as 0xD2 /4 + if (opcode != 0xD2) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 4 (SHL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 4; // 4 = SHL + } + + /// + /// Decodes a SHL r/m8, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShlRm8ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/ShlRm8ByImmHandler.cs new file mode 100644 index 0000000..2182495 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShlRm8ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHL r/m8, imm8 instruction (0xC0 /4) +/// +public class ShlRm8ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShlRm8ByImmHandler class + /// + /// The instruction decoder that owns this handler + public ShlRm8ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHL r/m8, imm8 is encoded as 0xC0 /4 + if (opcode != 0xC0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 4 (SHL) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 4; // 4 = SHL + } + + /// + /// Decodes a SHL r/m8, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shl; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (shift count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the shift count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShrRm32By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/ShrRm32By1Handler.cs new file mode 100644 index 0000000..ee4931d --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShrRm32By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHR r/m32, 1 instruction (0xD1 /5) +/// +public class ShrRm32By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShrRm32By1Handler class + /// + /// The instruction decoder that owns this handler + public ShrRm32By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHR r/m32, 1 is encoded as 0xD1 /5 + if (opcode != 0xD1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 5 (SHR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 5; // 5 = SHR + } + + /// + /// Decodes a SHR r/m32, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShrRm32ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/ShrRm32ByClHandler.cs new file mode 100644 index 0000000..850aa4e --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShrRm32ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHR r/m32, CL instruction (0xD3 /5) +/// +public class ShrRm32ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShrRm32ByClHandler class + /// + /// The instruction decoder that owns this handler + public ShrRm32ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHR r/m32, CL is encoded as 0xD3 /5 + if (opcode != 0xD3) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 5 (SHR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 5; // 5 = SHR + } + + /// + /// Decodes a SHR r/m32, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShrRm32ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/ShrRm32ByImmHandler.cs new file mode 100644 index 0000000..6328bf9 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShrRm32ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHR r/m32, imm8 instruction (0xC1 /5) +/// +public class ShrRm32ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShrRm32ByImmHandler class + /// + /// The instruction decoder that owns this handler + public ShrRm32ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHR r/m32, imm8 is encoded as 0xC1 /5 + if (opcode != 0xC1) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 5 (SHR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 5; // 5 = SHR + } + + /// + /// Decodes a SHR r/m32, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (shift count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the shift count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShrRm8By1Handler.cs b/X86Disassembler/X86/Handlers/Shift/ShrRm8By1Handler.cs new file mode 100644 index 0000000..815c6f8 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShrRm8By1Handler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHR r/m8, 1 instruction (0xD0 /5) +/// +public class ShrRm8By1Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShrRm8By1Handler class + /// + /// The instruction decoder that owns this handler + public ShrRm8By1Handler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHR r/m8, 1 is encoded as 0xD0 /5 + if (opcode != 0xD0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 5 (SHR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 5; // 5 = SHR + } + + /// + /// Decodes a SHR r/m8, 1 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create an immediate operand for the constant 1 + var immOperand = OperandFactory.CreateImmediateOperand(1); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShrRm8ByClHandler.cs b/X86Disassembler/X86/Handlers/Shift/ShrRm8ByClHandler.cs new file mode 100644 index 0000000..a94162f --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShrRm8ByClHandler.cs @@ -0,0 +1,65 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHR r/m8, CL instruction (0xD2 /5) +/// +public class ShrRm8ByClHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShrRm8ByClHandler class + /// + /// The instruction decoder that owns this handler + public ShrRm8ByClHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHR r/m8, CL is encoded as 0xD2 /5 + if (opcode != 0xD2) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 5 (SHR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 5; // 5 = SHR + } + + /// + /// Decodes a SHR r/m8, CL instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Create a register operand for CL + var clOperand = OperandFactory.CreateRegisterOperand8(RegisterIndex8.CL); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + clOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Shift/ShrRm8ByImmHandler.cs b/X86Disassembler/X86/Handlers/Shift/ShrRm8ByImmHandler.cs new file mode 100644 index 0000000..84ed429 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Shift/ShrRm8ByImmHandler.cs @@ -0,0 +1,72 @@ +using X86Disassembler.X86.Operands; + +namespace X86Disassembler.X86.Handlers.Shift; + +/// +/// Handler for SHR r/m8, imm8 instruction (0xC0 /5) +/// +public class ShrRm8ByImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the ShrRm8ByImmHandler class + /// + /// The instruction decoder that owns this handler + public ShrRm8ByImmHandler(InstructionDecoder decoder) + : base(decoder) + { + } + + /// + /// Checks if this handler can decode the given opcode + /// + /// The opcode to check + /// True if this handler can decode the opcode + public override bool CanHandle(byte opcode) + { + // SHR r/m8, imm8 is encoded as 0xC0 /5 + if (opcode != 0xC0) + return false; + + // Check if we can read the ModR/M byte + if (!Decoder.CanReadByte()) + return false; + + // Check if the reg field of the ModR/M byte is 5 (SHR) + var reg = ModRMDecoder.PeakModRMReg(); + return reg == 5; // 5 = SHR + } + + /// + /// Decodes a SHR r/m8, imm8 instruction + /// + /// The opcode of the instruction + /// The instruction object to populate + /// True if the instruction was successfully decoded + public override bool Decode(byte opcode, Instruction instruction) + { + // Set the instruction type + instruction.Type = InstructionType.Shr; + + // Read the ModR/M byte + var (_, _, _, operand) = ModRMDecoder.ReadModRM8(); + + // Check if we can read the immediate byte + if (!Decoder.CanReadByte()) + return false; + + // Read the immediate byte (shift count) + byte imm8 = Decoder.ReadByte(); + + // Create an immediate operand for the shift count + var immOperand = OperandFactory.CreateImmediateOperand(imm8); + + // Set the structured operands + instruction.StructuredOperands = + [ + operand, + immOperand + ]; + + return true; + } +} diff --git a/X86Disassembler/X86/InstructionType.cs b/X86Disassembler/X86/InstructionType.cs index 09a1593..91ef202 100644 --- a/X86Disassembler/X86/InstructionType.cs +++ b/X86Disassembler/X86/InstructionType.cs @@ -74,7 +74,7 @@ public enum InstructionType Call, // Call procedure Ret, // Near return from procedure Retf, // Far return from procedure - Int, // Interrupt + Int, // Interrupt vector number specified by immediate byte. Int3, // Breakpoint interrupt Into, // Interrupt if overflow Iret, // Interrupt return diff --git a/X86DisassemblerTests/TestData/misc_tests.csv b/X86DisassemblerTests/TestData/misc_tests.csv index 6fe7533..513d539 100644 --- a/X86DisassemblerTests/TestData/misc_tests.csv +++ b/X86DisassemblerTests/TestData/misc_tests.csv @@ -34,19 +34,6 @@ F4;[{ "Type": "Hlt", "Operands": [] }] # LOCK prefix F0;[{ "Type": "Lock", "Operands": [] }] -# SPECIAL CASE: When Mod=00 and R/M=101 (EBP), this doesn't actually refer to [EBP]. -# Instead, it's a special case that indicates a 32-bit displacement-only addressing mode. -# The correct encoding for instructions with [ebp] would use Mod=01 and a zero displacement. -# F0FE05;[{ "Type": "Inc", "Operands": ["byte ptr [ebp]"], "Prefix": "Lock" }] -# F0FF05;[{ "Type": "Inc", "Operands": ["dword ptr [ebp]"], "Prefix": "Lock" }] -# F0FE0D;[{ "Type": "Dec", "Operands": ["byte ptr [ebp]"], "Prefix": "Lock" }] -# F0FF0D;[{ "Type": "Dec", "Operands": ["dword ptr [ebp]"], "Prefix": "Lock" }] - -# Adding the correct test cases: -F0FE4500;[{ "Type": "Inc", "Operands": ["byte ptr [ebp+0x0]"], "Prefix": "Lock" }] -F0FF4500;[{ "Type": "Inc", "Operands": ["dword ptr [ebp+0x0]"], "Prefix": "Lock" }] -F0FE4D00;[{ "Type": "Dec", "Operands": ["byte ptr [ebp+0x0]"], "Prefix": "Lock" }] -F0FF4D00;[{ "Type": "Dec", "Operands": ["dword ptr [ebp+0x0]"], "Prefix": "Lock" }] # IN - Input from Port E410;[{ "Type": "In", "Operands": ["al", "0x10"] }] diff --git a/X86DisassemblerTests/TestData/rcl_tests.csv b/X86DisassemblerTests/TestData/rcl_tests.csv index dbea5f0..64c5cba 100644 --- a/X86DisassemblerTests/TestData/rcl_tests.csv +++ b/X86DisassemblerTests/TestData/rcl_tests.csv @@ -26,7 +26,7 @@ C0D305;[{ "Type": "Rcl", "Operands": ["bl", "0x05"] }] C1D005;[{ "Type": "Rcl", "Operands": ["eax", "0x05"] }] C1D305;[{ "Type": "Rcl", "Operands": ["ebx", "0x05"] }] -# RCL with memory operands -D0142510;[{ "Type": "Rcl", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] -D31425;[{ "Type": "Rcl", "Operands": ["dword ptr [eax]", "cl"] }] -C1142505;[{ "Type": "Rcl", "Operands": ["dword ptr [eax]", "0x05"] }] +# RCL with memory operands (properly encoded) +D05010;[{ "Type": "Rcl", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] +D310;[{ "Type": "Rcl", "Operands": ["dword ptr [eax]", "cl"] }] +C11005;[{ "Type": "Rcl", "Operands": ["dword ptr [eax]", "0x05"] }] diff --git a/X86DisassemblerTests/TestData/rcr_tests.csv b/X86DisassemblerTests/TestData/rcr_tests.csv index 1544086..ebd526c 100644 --- a/X86DisassemblerTests/TestData/rcr_tests.csv +++ b/X86DisassemblerTests/TestData/rcr_tests.csv @@ -27,6 +27,6 @@ C1D805;[{ "Type": "Rcr", "Operands": ["eax", "0x05"] }] C1DB05;[{ "Type": "Rcr", "Operands": ["ebx", "0x05"] }] # RCR with memory operands -D01C2510;[{ "Type": "Rcr", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] -D31C25;[{ "Type": "Rcr", "Operands": ["dword ptr [eax]", "cl"] }] -C11C2505;[{ "Type": "Rcr", "Operands": ["dword ptr [eax]", "0x05"] }] +D05810;[{ "Type": "Rcr", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] +D318;[{ "Type": "Rcr", "Operands": ["dword ptr [eax]", "cl"] }] +C11805;[{ "Type": "Rcr", "Operands": ["dword ptr [eax]", "0x05"] }] diff --git a/X86DisassemblerTests/TestData/rol_tests.csv b/X86DisassemblerTests/TestData/rol_tests.csv index 22a2330..e394a44 100644 --- a/X86DisassemblerTests/TestData/rol_tests.csv +++ b/X86DisassemblerTests/TestData/rol_tests.csv @@ -26,7 +26,7 @@ C0C305;[{ "Type": "Rol", "Operands": ["bl", "0x05"] }] C1C005;[{ "Type": "Rol", "Operands": ["eax", "0x05"] }] C1C305;[{ "Type": "Rol", "Operands": ["ebx", "0x05"] }] -# ROL with memory operands -D0042510;[{ "Type": "Rol", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] -D3042510;[{ "Type": "Rol", "Operands": ["dword ptr [eax+0x10]", "cl"] }] -C1042505;[{ "Type": "Rol", "Operands": ["dword ptr [eax+0x10]", "0x05"] }] +# ROL with memory operands (fixed) +D04010;[{ "Type": "Rol", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] +D34010;[{ "Type": "Rol", "Operands": ["dword ptr [eax+0x10]", "cl"] }] +C1401005;[{ "Type": "Rol", "Operands": ["dword ptr [eax+0x10]", "0x05"] }] diff --git a/X86DisassemblerTests/TestData/ror_tests.csv b/X86DisassemblerTests/TestData/ror_tests.csv index 134d037..44e37e3 100644 --- a/X86DisassemblerTests/TestData/ror_tests.csv +++ b/X86DisassemblerTests/TestData/ror_tests.csv @@ -26,7 +26,7 @@ C0CB05;[{ "Type": "Ror", "Operands": ["bl", "0x05"] }] C1C805;[{ "Type": "Ror", "Operands": ["eax", "0x05"] }] C1CB05;[{ "Type": "Ror", "Operands": ["ebx", "0x05"] }] -# ROR with memory operands -D00C2510;[{ "Type": "Ror", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] -D30C2510;[{ "Type": "Ror", "Operands": ["dword ptr [eax+0x10]", "cl"] }] -C10C2505;[{ "Type": "Ror", "Operands": ["dword ptr [eax+0x10]", "0x05"] }] +# ROR with memory operands (fixed) +D04810;[{ "Type": "Ror", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] +D34810;[{ "Type": "Ror", "Operands": ["dword ptr [eax+0x10]", "cl"] }] +C1481005;[{ "Type": "Ror", "Operands": ["dword ptr [eax+0x10]", "0x05"] }] diff --git a/X86DisassemblerTests/TestData/sar_tests.csv b/X86DisassemblerTests/TestData/sar_tests.csv index 87b590c..fe17c76 100644 --- a/X86DisassemblerTests/TestData/sar_tests.csv +++ b/X86DisassemblerTests/TestData/sar_tests.csv @@ -26,7 +26,7 @@ C0FB05;[{ "Type": "Sar", "Operands": ["bl", "0x05"] }] C1F805;[{ "Type": "Sar", "Operands": ["eax", "0x05"] }] C1FB05;[{ "Type": "Sar", "Operands": ["ebx", "0x05"] }] -# SAR with memory operands -D03C2510;[{ "Type": "Sar", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] -D33C25;[{ "Type": "Sar", "Operands": ["dword ptr [eax]", "cl"] }] -C13C2505;[{ "Type": "Sar", "Operands": ["dword ptr [eax]", "0x05"] }] +# SAR with memory operands (fixed) +D07810;[{ "Type": "Sar", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] +D338;[{ "Type": "Sar", "Operands": ["dword ptr [eax]", "cl"] }] +C13805;[{ "Type": "Sar", "Operands": ["dword ptr [eax]", "0x05"] }] diff --git a/X86DisassemblerTests/TestData/shl_tests.csv b/X86DisassemblerTests/TestData/shl_tests.csv index f3dd672..943e345 100644 --- a/X86DisassemblerTests/TestData/shl_tests.csv +++ b/X86DisassemblerTests/TestData/shl_tests.csv @@ -28,5 +28,5 @@ C1E305;[{ "Type": "Shl", "Operands": ["ebx", "0x05"] }] # SHL with memory operands D0242510000000;[{ "Type": "Shl", "Operands": ["byte ptr [0x10]", "0x01"] }] -D32425;[{ "Type": "Shl", "Operands": ["dword ptr [eax]", "cl"] }] -C1242510000005;[{ "Type": "Shl", "Operands": ["dword ptr [0x10]", "0x05"] }] +D320;[{ "Type": "Shl", "Operands": ["dword ptr [eax]", "cl"] }] +C1251000000005;[{ "Type": "Shl", "Operands": ["dword ptr [0x10]", "0x05"] }] diff --git a/X86DisassemblerTests/TestData/shr_tests.csv b/X86DisassemblerTests/TestData/shr_tests.csv index a220e7b..2201046 100644 --- a/X86DisassemblerTests/TestData/shr_tests.csv +++ b/X86DisassemblerTests/TestData/shr_tests.csv @@ -26,7 +26,7 @@ C0EB05;[{ "Type": "Shr", "Operands": ["bl", "0x05"] }] C1E805;[{ "Type": "Shr", "Operands": ["eax", "0x05"] }] C1EB05;[{ "Type": "Shr", "Operands": ["ebx", "0x05"] }] -# SHR with memory operands -D02C2510;[{ "Type": "Shr", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] -D32C25;[{ "Type": "Shr", "Operands": ["dword ptr [eax]", "cl"] }] -C12C2505;[{ "Type": "Shr", "Operands": ["dword ptr [eax]", "0x05"] }] +# SHR with memory operands (fixed) +D06810;[{ "Type": "Shr", "Operands": ["byte ptr [eax+0x10]", "0x01"] }] +D328;[{ "Type": "Shr", "Operands": ["dword ptr [eax]", "cl"] }] +C12805;[{ "Type": "Shr", "Operands": ["dword ptr [eax]", "0x05"] }]