0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-05-19 03:41:18 +03:00

Removed obsolete handler classes and restored InstructionHandlerFactory

This commit is contained in:
bird_egop 2025-04-12 20:25:29 +03:00
parent 1442fd7060
commit dbc9b42007
4 changed files with 3 additions and 571 deletions

View File

@ -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".
when working with RVA variables, always add that to variable name, e.g. "nameRVA".
always build only affected project, not full solution.

View File

@ -1,126 +0,0 @@
namespace X86Disassembler.X86.Handlers;
/// <summary>
/// Handler for arithmetic and logical instructions (ADD, SUB, AND, OR, XOR, etc.)
/// </summary>
public class ArithmeticHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the ArithmeticHandler class
/// </summary>
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public ArithmeticHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// XOR instructions
if (opcode >= 0x30 && opcode <= 0x35)
{
return true;
}
return false;
}
/// <summary>
/// Decodes an arithmetic or logical instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
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;
}
}

View File

@ -1,343 +0,0 @@
namespace X86Disassembler.X86.Handlers;
/// <summary>
/// Handler for control flow instructions (JMP, CALL, RET, etc.)
/// </summary>
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"
};
/// <summary>
/// Initializes a new instance of the ControlFlowHandler class
/// </summary>
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public ControlFlowHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
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;
}
/// <summary>
/// Decodes a control flow instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
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;
}
/// <summary>
/// Decodes a RET instruction with 16-bit immediate operand
/// </summary>
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;
}
/// <summary>
/// Decodes a CALL instruction with 32-bit relative offset
/// </summary>
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;
}
/// <summary>
/// Decodes a JMP instruction with 32-bit relative offset
/// </summary>
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;
}
/// <summary>
/// Decodes a JMP instruction with 8-bit relative offset
/// </summary>
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;
}
/// <summary>
/// Decodes a conditional jump instruction
/// </summary>
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;
}
/// <summary>
/// Decodes a two-byte conditional jump instruction with 32-bit relative offset
/// </summary>
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;
}
/// <summary>
/// Decodes an INT instruction with 8-bit immediate operand
/// </summary>
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;
}
/// <summary>
/// Decodes a JECXZ instruction with 8-bit relative offset
/// </summary>
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;
}
}

View File

@ -1,101 +0,0 @@
namespace X86Disassembler.X86.Handlers;
/// <summary>
/// Handler for TEST instructions
/// </summary>
public class TestHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the TestHandler class
/// </summary>
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public TestHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
return opcode == 0x84 || opcode == 0x85 || opcode == 0xA8 || opcode == 0xA9;
}
/// <summary>
/// Decodes a TEST instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
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;
}
}