From dbc9b420075fbdab0fd8de51084c2af3fa792d15 Mon Sep 17 00:00:00 2001 From: bird_egop Date: Sat, 12 Apr 2025 20:25:29 +0300 Subject: [PATCH] Removed obsolete handler classes and restored InstructionHandlerFactory --- .windsurfrules | 4 +- .../X86/Handlers/ArithmeticHandler.cs | 126 ------- .../X86/Handlers/ControlFlowHandler.cs | 343 ------------------ X86Disassembler/X86/Handlers/TestHandler.cs | 101 ------ 4 files changed, 3 insertions(+), 571 deletions(-) delete mode 100644 X86Disassembler/X86/Handlers/ArithmeticHandler.cs delete mode 100644 X86Disassembler/X86/Handlers/ControlFlowHandler.cs delete mode 100644 X86Disassembler/X86/Handlers/TestHandler.cs diff --git a/.windsurfrules b/.windsurfrules index bc3de2d..78aed38 100644 --- a/.windsurfrules +++ b/.windsurfrules @@ -16,4 +16,6 @@ never use terminal commands to edit code. In case of a failure, write it to user never address compiler warnings yourself. If you see a warning, suggest to address it. -when working with RVA variables, always add that to variable name, e.g. "nameRVA". \ No newline at end of file +when working with RVA variables, always add that to variable name, e.g. "nameRVA". + +always build only affected project, not full solution. \ No newline at end of file diff --git a/X86Disassembler/X86/Handlers/ArithmeticHandler.cs b/X86Disassembler/X86/Handlers/ArithmeticHandler.cs deleted file mode 100644 index f4e545e..0000000 --- a/X86Disassembler/X86/Handlers/ArithmeticHandler.cs +++ /dev/null @@ -1,126 +0,0 @@ -namespace X86Disassembler.X86.Handlers; - -/// -/// Handler for arithmetic and logical instructions (ADD, SUB, AND, OR, XOR, etc.) -/// -public class ArithmeticHandler : InstructionHandler -{ - /// - /// Initializes a new instance of the ArithmeticHandler class - /// - /// The buffer containing the code to decode - /// The instruction decoder that owns this handler - /// The length of the buffer - public ArithmeticHandler(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) - { - // XOR instructions - if (opcode >= 0x30 && opcode <= 0x35) - { - return true; - } - - return false; - } - - /// - /// Decodes an arithmetic or logical 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 mnemonic based on the opcode - instruction.Mnemonic = OpcodeMap.GetMnemonic(opcode); - - int position = Decoder.GetPosition(); - - if (position >= Length) - { - return false; - } - - switch (opcode) - { - case 0x30: // XOR r/m8, r8 - case 0x31: // XOR r/m32, r32 - { - // Read the ModR/M byte - var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); - - // Determine the source register - string sourceReg; - if (opcode == 0x30) // 8-bit registers - { - sourceReg = ModRMDecoder.GetRegister8(reg); - } - else // 32-bit registers - { - sourceReg = ModRMDecoder.GetRegister32(reg); - } - - // Set the operands - instruction.Operands = $"{destOperand}, {sourceReg}"; - return true; - } - - case 0x32: // XOR r8, r/m8 - case 0x33: // XOR r32, r/m32 - { - // Read the ModR/M byte - var (mod, reg, rm, srcOperand) = ModRMDecoder.ReadModRM(); - - // Determine the destination register - string destReg; - if (opcode == 0x32) // 8-bit registers - { - destReg = ModRMDecoder.GetRegister8(reg); - } - else // 32-bit registers - { - destReg = ModRMDecoder.GetRegister32(reg); - } - - // Set the operands - instruction.Operands = $"{destReg}, {srcOperand}"; - return true; - } - - case 0x34: // XOR AL, imm8 - { - if (position < Length) - { - byte imm8 = CodeBuffer[position]; - Decoder.SetPosition(position + 1); - instruction.Operands = $"al, 0x{imm8:X2}"; - return true; - } - break; - } - - case 0x35: // XOR EAX, imm32 - { - if (position + 3 < Length) - { - uint imm32 = BitConverter.ToUInt32(CodeBuffer, position); - Decoder.SetPosition(position + 4); - instruction.Operands = $"eax, 0x{imm32:X8}"; - return true; - } - break; - } - } - - return false; - } -} diff --git a/X86Disassembler/X86/Handlers/ControlFlowHandler.cs b/X86Disassembler/X86/Handlers/ControlFlowHandler.cs deleted file mode 100644 index 81b0440..0000000 --- a/X86Disassembler/X86/Handlers/ControlFlowHandler.cs +++ /dev/null @@ -1,343 +0,0 @@ -namespace X86Disassembler.X86.Handlers; - -/// -/// Handler for control flow instructions (JMP, CALL, RET, etc.) -/// -public class ControlFlowHandler : InstructionHandler -{ - // Condition codes for conditional jumps - private static readonly string[] ConditionCodes = { - "o", "no", "b", "ae", "e", "ne", "be", "a", - "s", "ns", "p", "np", "l", "ge", "le", "g" - }; - - /// - /// Initializes a new instance of the ControlFlowHandler class - /// - /// The buffer containing the code to decode - /// The instruction decoder that owns this handler - /// The length of the buffer - public ControlFlowHandler(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) - { - // Two-byte opcodes (0F prefix) - if (opcode == 0x0F) - { - int position = Decoder.GetPosition(); - if (position < Length) - { - byte secondByte = CodeBuffer[position]; - // Two-byte conditional jumps (0F 80-0F 8F) - if (secondByte >= 0x80 && secondByte <= 0x8F) - { - return true; - } - } - return false; - } - - // RET instruction - if (opcode == 0xC3 || opcode == 0xC2) - { - return true; - } - - // CALL instruction - if (opcode == 0xE8) - { - return true; - } - - // JMP instructions - if (opcode == 0xE9 || opcode == 0xEB) - { - return true; - } - - // Conditional jumps - if (opcode >= 0x70 && opcode <= 0x7F) - { - return true; - } - - // INT instructions - if (opcode == 0xCC || opcode == 0xCD) - { - return true; - } - - // JECXZ instruction - if (opcode == 0xE3) - { - return true; - } - - return false; - } - - /// - /// Decodes a control flow 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) - { - // Handle two-byte opcodes (0F prefix) - if (opcode == 0x0F) - { - int position = Decoder.GetPosition(); - if (position < Length) - { - byte secondByte = CodeBuffer[position]; - Decoder.SetPosition(position + 1); - - // Two-byte conditional jumps (0F 80-0F 8F) - if (secondByte >= 0x80 && secondByte <= 0x8F) - { - // Set mnemonic (j + condition code) - int condIndex = secondByte - 0x80; - instruction.Mnemonic = "j" + ConditionCodes[condIndex]; - - // Decode 32-bit relative jump - return DecodeTwoByteConditionalJump(instruction); - } - } - return false; - } - - // Set the mnemonic based on the opcode - instruction.Mnemonic = OpcodeMap.GetMnemonic(opcode); - - // Handle different types of control flow instructions - if (opcode == 0xC3) // RET - { - // No operands for RET - instruction.Operands = string.Empty; - return true; - } - else if (opcode == 0xC2) // RET imm16 - { - return DecodeRETImm16(instruction); - } - else if (opcode == 0xE8) // CALL rel32 - { - return DecodeCALLRel32(instruction); - } - else if (opcode == 0xE9) // JMP rel32 - { - return DecodeJMPRel32(instruction); - } - else if (opcode == 0xEB) // JMP rel8 - { - return DecodeJMPRel8(instruction); - } - else if (opcode >= 0x70 && opcode <= 0x7F) // Conditional jumps - { - return DecodeConditionalJump(opcode, instruction); - } - else if (opcode == 0xCC) // INT3 - { - // No operands for INT3 - instruction.Operands = string.Empty; - return true; - } - else if (opcode == 0xCD) // INT imm8 - { - return DecodeINTImm8(instruction); - } - else if (opcode == 0xE3) // JECXZ rel8 - { - return DecodeJECXZRel8(instruction); - } - - return false; - } - - /// - /// Decodes a RET instruction with 16-bit immediate operand - /// - private bool DecodeRETImm16(Instruction instruction) - { - int position = Decoder.GetPosition(); - - if (position + 2 > Length) - { - return false; - } - - // Read the immediate value - ushort imm16 = BitConverter.ToUInt16(CodeBuffer, position); - Decoder.SetPosition(position + 2); - - instruction.Operands = $"0x{imm16:X4}"; - return true; - } - - /// - /// Decodes a CALL instruction with 32-bit relative offset - /// - private bool DecodeCALLRel32(Instruction instruction) - { - int position = Decoder.GetPosition(); - - if (position + 4 > Length) - { - return false; - } - - // Read the relative offset - int offset = BitConverter.ToInt32(CodeBuffer, position); - Decoder.SetPosition(position + 4); - - // Calculate the target address (relative to the next instruction) - uint targetAddress = (uint)(position + offset + 4); // +4 because the offset is relative to the next instruction - - instruction.Operands = $"0x{targetAddress:X8}"; - return true; - } - - /// - /// Decodes a JMP instruction with 32-bit relative offset - /// - private bool DecodeJMPRel32(Instruction instruction) - { - int position = Decoder.GetPosition(); - - if (position + 4 > Length) - { - return false; - } - - // Read the relative offset - int offset = BitConverter.ToInt32(CodeBuffer, position); - Decoder.SetPosition(position + 4); - - // Calculate the target address (relative to the next instruction) - uint targetAddress = (uint)(position + offset + 4); // +4 because the offset is relative to the next instruction - - instruction.Operands = $"0x{targetAddress:X8}"; - return true; - } - - /// - /// Decodes a JMP instruction with 8-bit relative offset - /// - private bool DecodeJMPRel8(Instruction instruction) - { - int position = Decoder.GetPosition(); - - if (position >= Length) - { - return false; - } - - // Read the relative offset - sbyte offset = (sbyte)CodeBuffer[position]; - Decoder.SetPosition(position + 1); - - // Calculate the target address (relative to the next instruction) - uint targetAddress = (uint)(position + offset + 1); // +1 because the offset is relative to the next instruction - - instruction.Operands = $"0x{targetAddress:X8}"; - return true; - } - - /// - /// Decodes a conditional jump instruction - /// - private bool DecodeConditionalJump(byte opcode, Instruction instruction) - { - int position = Decoder.GetPosition(); - - if (position >= Length) - { - return false; - } - - // Read the relative offset - sbyte offset = (sbyte)CodeBuffer[position]; - Decoder.SetPosition(position + 1); - - // Calculate the target address (relative to the next instruction) - uint targetAddress = (uint)(position + offset + 1); // +1 because the offset is relative to the next instruction - - instruction.Operands = $"0x{targetAddress:X8}"; - return true; - } - - /// - /// Decodes a two-byte conditional jump instruction with 32-bit relative offset - /// - private bool DecodeTwoByteConditionalJump(Instruction instruction) - { - int position = Decoder.GetPosition(); - - if (position + 4 > Length) - { - return false; - } - - // Read the relative offset - int offset = BitConverter.ToInt32(CodeBuffer, position); - Decoder.SetPosition(position + 4); - - // Calculate the target address (relative to the next instruction) - uint targetAddress = (uint)(position + offset + 4); // +4 because the offset is relative to the next instruction - - instruction.Operands = $"0x{targetAddress:X8}"; - return true; - } - - /// - /// Decodes an INT instruction with 8-bit immediate operand - /// - private bool DecodeINTImm8(Instruction instruction) - { - int position = Decoder.GetPosition(); - - if (position >= Length) - { - return false; - } - - // Read the immediate value - byte imm8 = CodeBuffer[position]; - Decoder.SetPosition(position + 1); - - instruction.Operands = $"0x{imm8:X2}"; - return true; - } - - /// - /// Decodes a JECXZ instruction with 8-bit relative offset - /// - private bool DecodeJECXZRel8(Instruction instruction) - { - int position = Decoder.GetPosition(); - - if (position >= Length) - { - return false; - } - - // Read the relative offset - sbyte offset = (sbyte)CodeBuffer[position]; - Decoder.SetPosition(position + 1); - - // Calculate the target address (relative to the next instruction) - uint targetAddress = (uint)(position + offset + 1); // +1 because the offset is relative to the next instruction - - instruction.Operands = $"0x{targetAddress:X8}"; - return true; - } -} diff --git a/X86Disassembler/X86/Handlers/TestHandler.cs b/X86Disassembler/X86/Handlers/TestHandler.cs deleted file mode 100644 index 37b22f3..0000000 --- a/X86Disassembler/X86/Handlers/TestHandler.cs +++ /dev/null @@ -1,101 +0,0 @@ -namespace X86Disassembler.X86.Handlers; - -/// -/// Handler for TEST instructions -/// -public class TestHandler : InstructionHandler -{ - /// - /// Initializes a new instance of the TestHandler class - /// - /// The buffer containing the code to decode - /// The instruction decoder that owns this handler - /// The length of the buffer - public TestHandler(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) - { - return opcode == 0x84 || opcode == 0x85 || opcode == 0xA8 || opcode == 0xA9; - } - - /// - /// Decodes a TEST 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) - { - int position = Decoder.GetPosition(); - - if (position >= Length) - { - return false; - } - - // Set the mnemonic - instruction.Mnemonic = "test"; - - switch (opcode) - { - case 0x84: // TEST r/m8, r8 - case 0x85: // TEST r/m32, r32 - // Read the ModR/M byte - var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); - - // Determine the source register - string sourceReg; - if (opcode == 0x84) // 8-bit registers - { - sourceReg = ModRMDecoder.GetRegister8(reg); - } - else // 32-bit registers - { - sourceReg = ModRMDecoder.GetRegister32(reg); - } - - // Set the operands - instruction.Operands = $"{destOperand}, {sourceReg}"; - break; - - case 0xA8: // TEST AL, imm8 - if (position < Length) - { - byte imm8 = CodeBuffer[position]; - Decoder.SetPosition(position + 1); - instruction.Operands = $"al, 0x{imm8:X2}"; - } - else - { - instruction.Operands = "al, ???"; - } - break; - - case 0xA9: // TEST EAX, imm32 - if (position + 3 < Length) - { - uint imm32 = BitConverter.ToUInt32(CodeBuffer, position); - Decoder.SetPosition(position + 4); - instruction.Operands = $"eax, 0x{imm32:X8}"; - } - else - { - instruction.Operands = "eax, ???"; - } - break; - - default: - return false; - } - - return true; - } -}