diff --git a/X86Disassembler/X86/Handlers/Group5/CallRm32Handler.cs b/X86Disassembler/X86/Handlers/Call/CallRm32Handler.cs similarity index 100% rename from X86Disassembler/X86/Handlers/Group5/CallRm32Handler.cs rename to X86Disassembler/X86/Handlers/Call/CallRm32Handler.cs diff --git a/X86Disassembler/X86/Handlers/Inc/IncRegHandler.cs b/X86Disassembler/X86/Handlers/Inc/IncRegHandler.cs new file mode 100644 index 0000000..a0bd949 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Inc/IncRegHandler.cs @@ -0,0 +1,49 @@ +namespace X86Disassembler.X86.Handlers.Inc; + +/// +/// Handler for INC r32 instructions (0x40-0x47) +/// +public class IncRegHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the IncRegHandler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public IncRegHandler(byte[] codeBuffer, InstructionDecoder decoder, int length) + : base(codeBuffer, decoder, length) + { + } + + /// + /// 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) + { + // INC EAX = 0x40, INC ECX = 0x41, ..., INC EDI = 0x47 + return opcode >= 0x40 && opcode <= 0x47; + } + + /// + /// Decodes an INC r32 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) + { + // Calculate the register index (0 for EAX, 1 for ECX, etc.) + byte reg = (byte)(opcode - 0x40); + + // Set the mnemonic + instruction.Mnemonic = "inc"; + + // Set the operand (register name) + instruction.Operands = GetRegister32(reg); + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs index 7cc3169..4f66009 100644 --- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs +++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs @@ -5,7 +5,7 @@ using X86Disassembler.X86.Handlers.Call; using X86Disassembler.X86.Handlers.Cmp; using X86Disassembler.X86.Handlers.Dec; using X86Disassembler.X86.Handlers.FloatingPoint; -using X86Disassembler.X86.Handlers.Group5; +using X86Disassembler.X86.Handlers.Inc; using X86Disassembler.X86.Handlers.Jump; using X86Disassembler.X86.Handlers.Lea; using X86Disassembler.X86.Handlers.Mov; @@ -83,12 +83,12 @@ public class InstructionHandlerFactory // Register Dec handlers RegisterDecHandlers(); + // Register Inc handlers + RegisterIncHandlers(); + // Register Add handlers RegisterAddHandlers(); - // Register Group5 handlers - RegisterGroup5Handlers(); - // Register Data Transfer handlers RegisterDataTransferHandlers(); @@ -172,6 +172,7 @@ public class InstructionHandlerFactory { // Add Call handlers _handlers.Add(new CallRel32Handler(_codeBuffer, _decoder, _length)); + _handlers.Add(new CallRm32Handler(_codeBuffer, _decoder, _length)); } /// @@ -259,25 +260,25 @@ public class InstructionHandlerFactory _handlers.Add(new DecRegHandler(_codeBuffer, _decoder, _length)); } + /// + /// Registers all Inc instruction handlers + /// + private void RegisterIncHandlers() + { + // Add Inc handlers + _handlers.Add(new IncRegHandler(_codeBuffer, _decoder, _length)); + } + /// /// Registers all Add instruction handlers /// private void RegisterAddHandlers() { - // Add Add handlers + // Add ADD handlers _handlers.Add(new AddR32Rm32Handler(_codeBuffer, _decoder, _length)); _handlers.Add(new AddRm32R32Handler(_codeBuffer, _decoder, _length)); } - /// - /// Registers all Group5 instruction handlers - /// - private void RegisterGroup5Handlers() - { - // Add Group5 handlers - _handlers.Add(new CallRm32Handler(_codeBuffer, _decoder, _length)); - } - /// /// Registers all Data Transfer instruction handlers /// diff --git a/X86Disassembler/X86/OpcodeMap.cs b/X86Disassembler/X86/OpcodeMap.cs index 628957b..a157e70 100644 --- a/X86Disassembler/X86/OpcodeMap.cs +++ b/X86Disassembler/X86/OpcodeMap.cs @@ -72,6 +72,16 @@ public static class OpcodeMap OneByteOpcodes[0x4E] = "dec"; // DEC ESI OneByteOpcodes[0x4F] = "dec"; // DEC EDI + // INC instructions + OneByteOpcodes[0x40] = "inc"; // INC EAX + OneByteOpcodes[0x41] = "inc"; // INC ECX + OneByteOpcodes[0x42] = "inc"; // INC EDX + OneByteOpcodes[0x43] = "inc"; // INC EBX + OneByteOpcodes[0x44] = "inc"; // INC ESP + OneByteOpcodes[0x45] = "inc"; // INC EBP + OneByteOpcodes[0x46] = "inc"; // INC ESI + OneByteOpcodes[0x47] = "inc"; // INC EDI + // ADD instructions OneByteOpcodes[0x00] = "add"; // ADD r/m8, r8 OneByteOpcodes[0x01] = "add"; // ADD r/m32, r32 diff --git a/X86DisassemblerTests/IncInstructionTests.cs b/X86DisassemblerTests/IncInstructionTests.cs new file mode 100644 index 0000000..e56e28c --- /dev/null +++ b/X86DisassemblerTests/IncInstructionTests.cs @@ -0,0 +1,68 @@ +namespace X86DisassemblerTests; + +using System; +using Xunit; +using X86Disassembler.X86; + +/// +/// Tests for INC instruction handlers +/// +public class IncInstructionTests +{ + /// + /// Tests the INC EAX instruction (0x40) + /// + [Fact] + public void TestIncEax() + { + // Arrange + byte[] code = { 0x40 }; // INC EAX + + // Act + Disassembler disassembler = new Disassembler(code, 0x1000); + var instructions = disassembler.Disassemble(); + + // Assert + Assert.Single(instructions); + Assert.Equal("inc", instructions[0].Mnemonic); + Assert.Equal("eax", instructions[0].Operands); + } + + /// + /// Tests the INC ECX instruction (0x41) + /// + [Fact] + public void TestIncEcx() + { + // Arrange + byte[] code = { 0x41 }; // INC ECX + + // Act + Disassembler disassembler = new Disassembler(code, 0x1000); + var instructions = disassembler.Disassemble(); + + // Assert + Assert.Single(instructions); + Assert.Equal("inc", instructions[0].Mnemonic); + Assert.Equal("ecx", instructions[0].Operands); + } + + /// + /// Tests the INC EDI instruction (0x47) + /// + [Fact] + public void TestIncEdi() + { + // Arrange + byte[] code = { 0x47 }; // INC EDI + + // Act + Disassembler disassembler = new Disassembler(code, 0x1000); + var instructions = disassembler.Disassemble(); + + // Assert + Assert.Single(instructions); + Assert.Equal("inc", instructions[0].Mnemonic); + Assert.Equal("edi", instructions[0].Operands); + } +}