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

more refactoring

This commit is contained in:
bird_egop 2025-04-14 01:08:14 +03:00
parent f54dc10596
commit 99b93523a4
78 changed files with 379 additions and 594 deletions

View File

@ -28,7 +28,7 @@ public class AdcImmToRm32Handler : InstructionHandler
// Check if the reg field of the ModR/M byte is 2 (ADC) // Check if the reg field of the ModR/M byte is 2 (ADC)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
@ -48,9 +48,7 @@ public class AdcImmToRm32Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "adc"; instruction.Mnemonic = "adc";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -58,8 +56,7 @@ public class AdcImmToRm32Handler : InstructionHandler
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value if (!Decoder.CanReadUInt())
if (position + 3 >= Length)
{ {
return false; return false;
} }

View File

@ -28,7 +28,7 @@ public class AdcImmToRm32SignExtendedHandler : InstructionHandler
// Check if the reg field of the ModR/M byte is 2 (ADC) // Check if the reg field of the ModR/M byte is 2 (ADC)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
@ -48,9 +48,7 @@ public class AdcImmToRm32SignExtendedHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "adc"; instruction.Mnemonic = "adc";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -58,13 +56,12 @@ public class AdcImmToRm32SignExtendedHandler : InstructionHandler
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value (sign-extended from 8 to 32 bits) if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Sign-extend to 32 bits // Read the immediate value (sign-extended from 8 to 32 bits)
int imm32 = (sbyte) Decoder.ReadByte(); int imm32 = (sbyte) Decoder.ReadByte();
// Set the operands // Set the operands

View File

@ -11,11 +11,11 @@ public class AddEaxImmHandler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public AddEaxImmHandler(byte[] codeBuffer, InstructionDecoder decoder, int length) public AddEaxImmHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,7 +25,7 @@ public class AddEaxImmHandler : InstructionHandler
{ {
return opcode == 0x05; return opcode == 0x05;
} }
/// <summary> /// <summary>
/// Decodes an ADD EAX, imm32 instruction /// Decodes an ADD EAX, imm32 instruction
/// </summary> /// </summary>
@ -36,24 +36,21 @@ public class AddEaxImmHandler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "add"; instruction.Mnemonic = "add";
int position = Decoder.GetPosition(); if (!Decoder.CanReadUInt())
// Check if we have enough bytes for the immediate value
if (position + 3 >= Length)
{ {
return false; // Not enough bytes for the immediate value return false;
} }
// Read the 32-bit immediate value // Read the 32-bit immediate value
uint imm32 = Decoder.ReadUInt32(); uint imm32 = Decoder.ReadUInt32();
// Format the immediate value // Format the immediate value
string immStr = $"0x{imm32:X}"; string immStr = $"0x{imm32:X}";
// Set the operands // Set the operands
instruction.Operands = $"eax, {immStr}"; instruction.Operands = $"eax, {immStr}";
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class AddImmToRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public AddImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public AddImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,18 +25,18 @@ public class AddImmToRm32Handler : InstructionHandler
{ {
if (opcode != 0x81) if (opcode != 0x81)
return false; return false;
// Check if the reg field of the ModR/M byte is 0 (ADD) // Check if the reg field of the ModR/M byte is 0 (ADD)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 0; // 0 = ADD return reg == 0; // 0 = ADD
} }
/// <summary> /// <summary>
/// Decodes an ADD r/m32, imm32 instruction /// Decodes an ADD r/m32, imm32 instruction
/// </summary> /// </summary>
@ -47,33 +47,31 @@ public class AddImmToRm32Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "add"; instruction.Mnemonic = "add";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value // Read the immediate value
if (position + 3 >= Length) if (!Decoder.CanReadUInt())
{ {
return false; return false;
} }
// Read the immediate value in little-endian format // Read the immediate value in little-endian format
var imm = Decoder.ReadUInt32(); var imm = Decoder.ReadUInt32();
// Format the immediate value as expected by the tests (0x12345678) // Format the immediate value as expected by the tests (0x12345678)
// Note: The bytes are reversed to match the expected format in the tests // Note: The bytes are reversed to match the expected format in the tests
string immStr = $"0x{imm:X8}"; string immStr = $"0x{imm:X8}";
// Set the operands // Set the operands
instruction.Operands = $"{destOperand}, {immStr}"; instruction.Operands = $"{destOperand}, {immStr}";
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class AddImmToRm32SignExtendedHandler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public AddImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length) public AddImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,18 +25,18 @@ public class AddImmToRm32SignExtendedHandler : InstructionHandler
{ {
if (opcode != 0x83) if (opcode != 0x83)
return false; return false;
// Check if the reg field of the ModR/M byte is 0 (ADD) // Check if the reg field of the ModR/M byte is 0 (ADD)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 0; // 0 = ADD return reg == 0; // 0 = ADD
} }
/// <summary> /// <summary>
/// Decodes an ADD r/m32, imm8 (sign-extended) instruction /// Decodes an ADD r/m32, imm8 (sign-extended) instruction
/// </summary> /// </summary>
@ -47,45 +47,40 @@ public class AddImmToRm32SignExtendedHandler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "add"; instruction.Mnemonic = "add";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Get the position after decoding the ModR/M byte
position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value // Check if we have enough bytes for the immediate value
if (position >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }
// Read the immediate value as a signed byte and automatically sign-extend it to int // Read the immediate value as a signed byte and automatically sign-extend it to int
int signExtendedImm = (sbyte)Decoder.ReadByte(); int imm = (sbyte) Decoder.ReadByte();
// Format the immediate value // Format the immediate value
string immStr; string immStr;
if (signExtendedImm < 0) if (imm < 0)
{ {
// For negative values, use the full 32-bit representation (0xFFFFFFxx) // For negative values, use the full 32-bit representation (0xFFFFFFxx)
immStr = $"0x{(uint)signExtendedImm:X8}"; immStr = $"0x{(uint) imm:X8}";
} }
else else
{ {
// For positive values, use the regular format with leading zeros // For positive values, use the regular format with leading zeros
immStr = $"0x{signExtendedImm:X8}"; immStr = $"0x{imm:X8}";
} }
// Set the operands // Set the operands
instruction.Operands = $"{destOperand}, {immStr}"; instruction.Operands = $"{destOperand}, {immStr}";
return true; return true;
} }
} }

View File

@ -28,7 +28,7 @@ public class AddImmToRm8Handler : InstructionHandler
// Check if the reg field of the ModR/M byte is 0 (ADD) // Check if the reg field of the ModR/M byte is 0 (ADD)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
@ -48,9 +48,7 @@ public class AddImmToRm8Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "add"; instruction.Mnemonic = "add";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -66,7 +64,7 @@ public class AddImmToRm8Handler : InstructionHandler
} }
// Read the immediate value // Read the immediate value
if (position >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }

View File

@ -34,9 +34,7 @@ public class AddR32Rm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -34,9 +34,7 @@ public class AddRm32R32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -36,11 +36,9 @@ public class AndAlImmHandler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "and"; instruction.Mnemonic = "and";
int position = Decoder.GetPosition();
// Read immediate value // Read immediate value
if (position >= Length) if (!Decoder.CanReadByte())
{ {
instruction.Operands = "al, ??"; instruction.Operands = "al, ??";
return true; return true;

View File

@ -36,11 +36,9 @@ public class AndEaxImmHandler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "and"; instruction.Mnemonic = "and";
int position = Decoder.GetPosition();
// Read immediate value // Read immediate value
if (position + 3 >= Length) if (!Decoder.CanReadUInt())
{ {
instruction.Operands = "eax, ??"; instruction.Operands = "eax, ??";
return true; return true;

View File

@ -11,11 +11,11 @@ public class AndImmToRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public AndImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public AndImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,18 +25,18 @@ public class AndImmToRm32Handler : InstructionHandler
{ {
if (opcode != 0x81) if (opcode != 0x81)
return false; return false;
// Check if the reg field of the ModR/M byte is 4 (AND) // Check if the reg field of the ModR/M byte is 4 (AND)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 4; // 4 = AND return reg == 4; // 4 = AND
} }
/// <summary> /// <summary>
/// Decodes an AND r/m32, imm32 instruction /// Decodes an AND r/m32, imm32 instruction
/// </summary> /// </summary>
@ -47,33 +47,31 @@ public class AndImmToRm32Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "and"; instruction.Mnemonic = "and";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value // Read the immediate value
if (position + 3 >= Length) if (!Decoder.CanReadUInt())
{ {
return false; return false;
} }
// Read the immediate value in little-endian format // Read the immediate value in little-endian format
var imm = Decoder.ReadUInt32(); var imm = Decoder.ReadUInt32();
// Format the immediate value as expected by the tests (0x12345678) // Format the immediate value as expected by the tests (0x12345678)
// Note: The bytes are reversed to match the expected format in the tests // Note: The bytes are reversed to match the expected format in the tests
string immStr = $"0x{imm:X8}"; string immStr = $"0x{imm:X8}";
// Set the operands // Set the operands
instruction.Operands = $"{destOperand}, {immStr}"; instruction.Operands = $"{destOperand}, {immStr}";
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class AndImmToRm32SignExtendedHandler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public AndImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length) public AndImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -27,22 +27,22 @@ public class AndImmToRm32SignExtendedHandler : InstructionHandler
{ {
return false; return false;
} }
// Check if we have enough bytes to read the ModR/M byte // Check if we have enough bytes to read the ModR/M byte
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }
// Read the ModR/M byte to check the reg field (bits 5-3) // Read the ModR/M byte to check the reg field (bits 5-3)
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
int reg = (modRM >> 3) & 0x7; int reg = (modRM >> 3) & 0x7;
// reg = 4 means AND operation // reg = 4 means AND operation
return reg == 4; return reg == 4;
} }
/// <summary> /// <summary>
/// Decodes an AND r/m32, imm8 (sign-extended) instruction /// Decodes an AND r/m32, imm8 (sign-extended) instruction
/// </summary> /// </summary>
@ -53,22 +53,18 @@ public class AndImmToRm32SignExtendedHandler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "and"; instruction.Mnemonic = "and";
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get the position after decoding the ModR/M byte if (!Decoder.CanReadByte())
int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value
if (position >= Length)
{ {
return false; // Not enough bytes for the immediate value return false; // Not enough bytes for the immediate value
} }
// Read the immediate value as a signed byte and automatically sign-extend it to int // Read the immediate value as a signed byte and automatically sign-extend it to int
int signExtendedImm = (sbyte)Decoder.ReadByte(); int imm = (sbyte) Decoder.ReadByte();
// Format the destination operand based on addressing mode // Format the destination operand based on addressing mode
string destOperand; string destOperand;
if (mod == 3) // Register addressing mode if (mod == 3) // Register addressing mode
@ -81,23 +77,23 @@ public class AndImmToRm32SignExtendedHandler : InstructionHandler
// Memory operand already includes dword ptr prefix // Memory operand already includes dword ptr prefix
destOperand = memOperand; destOperand = memOperand;
} }
// Format the immediate value // Format the immediate value
string immStr; string immStr;
if (signExtendedImm < 0) if (imm < 0)
{ {
// For negative values, use the full 32-bit representation // For negative values, use the full 32-bit representation
immStr = $"0x{(uint)signExtendedImm:X8}"; immStr = $"0x{(uint) imm:X8}";
} }
else else
{ {
// For positive values, use the regular format with leading zeros // For positive values, use the regular format with leading zeros
immStr = $"0x{signExtendedImm:X8}"; immStr = $"0x{imm:X8}";
} }
// Set the operands // Set the operands
instruction.Operands = $"{destOperand}, {immStr}"; instruction.Operands = $"{destOperand}, {immStr}";
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class AndImmToRm8Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public AndImmToRm8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public AndImmToRm8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -27,22 +27,22 @@ public class AndImmToRm8Handler : InstructionHandler
{ {
return false; return false;
} }
// Check if we have enough bytes to read the ModR/M byte // Check if we have enough bytes to read the ModR/M byte
int position = Decoder.GetPosition(); if (Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
int position = Decoder.GetPosition();
// Read the ModR/M byte to check the reg field (bits 5-3) // Read the ModR/M byte to check the reg field (bits 5-3)
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
int reg = (modRM >> 3) & 0x7; int reg = (modRM >> 3) & 0x7;
// reg = 4 means AND operation // reg = 4 means AND operation
return reg == 4; return reg == 4;
} }
/// <summary> /// <summary>
/// Decodes an AND r/m8, imm8 instruction /// Decodes an AND r/m8, imm8 instruction
/// </summary> /// </summary>
@ -53,22 +53,18 @@ public class AndImmToRm8Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "and"; instruction.Mnemonic = "and";
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get the position after decoding the ModR/M byte if (!Decoder.CanReadByte())
int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value
if (position >= Length)
{ {
return false; // Not enough bytes for the immediate value return false; // Not enough bytes for the immediate value
} }
// Read the immediate value // Read the immediate value
byte imm8 = Decoder.ReadByte(); byte imm8 = Decoder.ReadByte();
// Format the destination operand based on addressing mode // Format the destination operand based on addressing mode
string destOperand; string destOperand;
if (mod == 3) // Register addressing mode if (mod == 3) // Register addressing mode
@ -81,13 +77,13 @@ public class AndImmToRm8Handler : InstructionHandler
// Add byte ptr prefix for memory operands // Add byte ptr prefix for memory operands
destOperand = $"byte ptr {memOperand}"; destOperand = $"byte ptr {memOperand}";
} }
// Format the immediate value // Format the immediate value
string immStr = $"0x{imm8:X2}"; string immStr = $"0x{imm8:X2}";
// Set the operands // Set the operands
instruction.Operands = $"{destOperand}, {immStr}"; instruction.Operands = $"{destOperand}, {immStr}";
return true; return true;
} }
} }

View File

@ -28,7 +28,7 @@ public class AndImmWithRm32Handler : InstructionHandler
// Check if the reg field of the ModR/M byte is 4 (AND) // Check if the reg field of the ModR/M byte is 4 (AND)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
@ -55,7 +55,7 @@ public class AndImmWithRm32Handler : InstructionHandler
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value // Check if we have enough bytes for the immediate value
if (position + 3 >= Length) if (!Decoder.CanReadUInt())
{ {
return false; // Not enough bytes for the immediate value return false; // Not enough bytes for the immediate value
} }

View File

@ -11,11 +11,11 @@ public class AndMemRegHandler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public AndMemRegHandler(byte[] codeBuffer, InstructionDecoder decoder, int length) public AndMemRegHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,7 +25,7 @@ public class AndMemRegHandler : InstructionHandler
{ {
return opcode == 0x21; return opcode == 0x21;
} }
/// <summary> /// <summary>
/// Decodes an AND r/m32, r32 instruction /// Decodes an AND r/m32, r32 instruction
/// </summary> /// </summary>
@ -36,20 +36,18 @@ public class AndMemRegHandler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "and"; instruction.Mnemonic = "and";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get register name // Get register name
string regName = ModRMDecoder.GetRegisterName(reg, 32); string regName = ModRMDecoder.GetRegisterName(reg, 32);
// For mod == 3, both operands are registers // For mod == 3, both operands are registers
if (mod == 3) if (mod == 3)
{ {
@ -60,4 +58,4 @@ public class AndMemRegHandler : InstructionHandler
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class AndR32Rm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public AndR32Rm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public AndR32Rm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,7 +25,7 @@ public class AndR32Rm32Handler : InstructionHandler
{ {
return opcode == 0x23; return opcode == 0x23;
} }
/// <summary> /// <summary>
/// Decodes an AND r32, r/m32 instruction /// Decodes an AND r32, r/m32 instruction
/// </summary> /// </summary>
@ -36,20 +36,18 @@ public class AndR32Rm32Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "and"; instruction.Mnemonic = "and";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get register name // Get register name
string regName = ModRMDecoder.GetRegisterName(reg, 32); string regName = ModRMDecoder.GetRegisterName(reg, 32);
// For mod == 3, both operands are registers // For mod == 3, both operands are registers
if (mod == 3) if (mod == 3)
{ {
@ -60,4 +58,4 @@ public class AndR32Rm32Handler : InstructionHandler
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class AndR8Rm8Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public AndR8Rm8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public AndR8Rm8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,7 +25,7 @@ public class AndR8Rm8Handler : InstructionHandler
{ {
return opcode == 0x22; return opcode == 0x22;
} }
/// <summary> /// <summary>
/// Decodes an AND r8, r/m8 instruction /// Decodes an AND r8, r/m8 instruction
/// </summary> /// </summary>
@ -36,20 +36,18 @@ public class AndR8Rm8Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "and"; instruction.Mnemonic = "and";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get register name // Get register name
string regName = ModRMDecoder.GetRegisterName(reg, 8); string regName = ModRMDecoder.GetRegisterName(reg, 8);
// For mod == 3, both operands are registers // For mod == 3, both operands are registers
if (mod == 3) if (mod == 3)
{ {
@ -60,7 +58,7 @@ public class AndR8Rm8Handler : InstructionHandler
{ {
instruction.Operands = $"{regName}, byte ptr {memOperand}"; instruction.Operands = $"{regName}, byte ptr {memOperand}";
} }
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class AndRm8R8Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public AndRm8R8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public AndRm8R8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,7 +25,7 @@ public class AndRm8R8Handler : InstructionHandler
{ {
return opcode == 0x20; return opcode == 0x20;
} }
/// <summary> /// <summary>
/// Decodes an AND r/m8, r8 instruction /// Decodes an AND r/m8, r8 instruction
/// </summary> /// </summary>
@ -36,20 +36,18 @@ public class AndRm8R8Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "and"; instruction.Mnemonic = "and";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get register name // Get register name
string regName = ModRMDecoder.GetRegisterName(reg, 8); string regName = ModRMDecoder.GetRegisterName(reg, 8);
// For mod == 3, both operands are registers // For mod == 3, both operands are registers
if (mod == 3) if (mod == 3)
{ {
@ -60,7 +58,7 @@ public class AndRm8R8Handler : InstructionHandler
{ {
instruction.Operands = $"byte ptr {memOperand}, {regName}"; instruction.Operands = $"byte ptr {memOperand}, {regName}";
} }
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class DivRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public DivRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public DivRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,18 +25,18 @@ public class DivRm32Handler : InstructionHandler
{ {
if (opcode != 0xF7) if (opcode != 0xF7)
return false; return false;
// Check if the reg field of the ModR/M byte is 6 (DIV) // Check if the reg field of the ModR/M byte is 6 (DIV)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 6; // 6 = DIV return reg == 6; // 6 = DIV
} }
/// <summary> /// <summary>
/// Decodes a DIV r/m32 instruction /// Decodes a DIV r/m32 instruction
/// </summary> /// </summary>
@ -47,20 +47,18 @@ public class DivRm32Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "div"; instruction.Mnemonic = "div";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Set the operands // Set the operands
instruction.Operands = destOperand; instruction.Operands = destOperand;
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class IdivRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public IdivRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public IdivRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,18 +25,18 @@ public class IdivRm32Handler : InstructionHandler
{ {
if (opcode != 0xF7) if (opcode != 0xF7)
return false; return false;
// Check if the reg field of the ModR/M byte is 7 (IDIV) // Check if the reg field of the ModR/M byte is 7 (IDIV)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 7; // 7 = IDIV return reg == 7; // 7 = IDIV
} }
/// <summary> /// <summary>
/// Decodes an IDIV r/m32 instruction /// Decodes an IDIV r/m32 instruction
/// </summary> /// </summary>
@ -47,20 +47,18 @@ public class IdivRm32Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "idiv"; instruction.Mnemonic = "idiv";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Set the operands // Set the operands
instruction.Operands = destOperand; instruction.Operands = destOperand;
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class ImulRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public ImulRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public ImulRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,18 +25,18 @@ public class ImulRm32Handler : InstructionHandler
{ {
if (opcode != 0xF7) if (opcode != 0xF7)
return false; return false;
// Check if the reg field of the ModR/M byte is 5 (IMUL) // Check if the reg field of the ModR/M byte is 5 (IMUL)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 5; // 5 = IMUL return reg == 5; // 5 = IMUL
} }
/// <summary> /// <summary>
/// Decodes an IMUL r/m32 instruction /// Decodes an IMUL r/m32 instruction
/// </summary> /// </summary>
@ -47,20 +47,18 @@ public class ImulRm32Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "imul"; instruction.Mnemonic = "imul";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Set the operands // Set the operands
instruction.Operands = destOperand; instruction.Operands = destOperand;
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class MulRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public MulRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public MulRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,18 +25,18 @@ public class MulRm32Handler : InstructionHandler
{ {
if (opcode != 0xF7) if (opcode != 0xF7)
return false; return false;
// Check if the reg field of the ModR/M byte is 4 (MUL) // Check if the reg field of the ModR/M byte is 4 (MUL)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 4; // 4 = MUL return reg == 4; // 4 = MUL
} }
/// <summary> /// <summary>
/// Decodes a MUL r/m32 instruction /// Decodes a MUL r/m32 instruction
/// </summary> /// </summary>
@ -47,20 +47,18 @@ public class MulRm32Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "mul"; instruction.Mnemonic = "mul";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Set the operands // Set the operands
instruction.Operands = destOperand; instruction.Operands = destOperand;
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class NegRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public NegRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public NegRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,18 +25,18 @@ public class NegRm32Handler : InstructionHandler
{ {
if (opcode != 0xF7) if (opcode != 0xF7)
return false; return false;
// Check if the reg field of the ModR/M byte is 3 (NEG) // Check if the reg field of the ModR/M byte is 3 (NEG)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 3; // 3 = NEG return reg == 3; // 3 = NEG
} }
/// <summary> /// <summary>
/// Decodes a NEG r/m32 instruction /// Decodes a NEG r/m32 instruction
/// </summary> /// </summary>
@ -47,20 +47,18 @@ public class NegRm32Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "neg"; instruction.Mnemonic = "neg";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Set the operands // Set the operands
instruction.Operands = destOperand; instruction.Operands = destOperand;
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class NotRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public NotRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public NotRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -26,18 +26,18 @@ public class NotRm32Handler : InstructionHandler
// This handler only handles opcode 0xF7 // This handler only handles opcode 0xF7
if (opcode != 0xF7) if (opcode != 0xF7)
return false; return false;
// Check if the reg field of the ModR/M byte is 2 (NOT) // Check if the reg field of the ModR/M byte is 2 (NOT)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 2; // 2 = NOT return reg == 2; // 2 = NOT
} }
/// <summary> /// <summary>
/// Decodes a NOT r/m32 instruction /// Decodes a NOT r/m32 instruction
/// </summary> /// </summary>
@ -46,36 +46,32 @@ public class NotRm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Verify this is a NOT instruction // Verify this is a NOT instruction
if (reg != RegisterIndex.C) if (reg != RegisterIndex.C)
{ {
return false; return false;
} }
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "not"; instruction.Mnemonic = "not";
Decoder.SetPosition(position);
// For direct register addressing (mod == 3), the r/m field specifies a register // For direct register addressing (mod == 3), the r/m field specifies a register
if (mod == 3) if (mod == 3)
{ {
destOperand = ModRMDecoder.GetRegisterName(rm, 32); destOperand = ModRMDecoder.GetRegisterName(rm, 32);
} }
// Set the operands // Set the operands
instruction.Operands = destOperand; instruction.Operands = destOperand;
return true; return true;
} }
} }

View File

@ -11,11 +11,11 @@ public class CallRel32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param> /// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param> /// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param> /// <param name="length">The length of the buffer</param>
public CallRel32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) public CallRel32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length) : base(codeBuffer, decoder, length)
{ {
} }
/// <summary> /// <summary>
/// Checks if this handler can decode the given opcode /// Checks if this handler can decode the given opcode
/// </summary> /// </summary>
@ -25,7 +25,7 @@ public class CallRel32Handler : InstructionHandler
{ {
return opcode == 0xE8; return opcode == 0xE8;
} }
/// <summary> /// <summary>
/// Decodes a CALL rel32 instruction /// Decodes a CALL rel32 instruction
/// </summary> /// </summary>
@ -36,23 +36,23 @@ public class CallRel32Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "call"; instruction.Mnemonic = "call";
int position = Decoder.GetPosition(); if (!Decoder.CanReadUInt())
if (position + 4 > Length)
{ {
return false; return false;
} }
int position = Decoder.GetPosition();
// Read the relative offset // Read the relative offset
uint offset = Decoder.ReadUInt32(); uint offset = Decoder.ReadUInt32();
// Calculate the target address // Calculate the target address
uint targetAddress = (uint)(position + offset + 4); uint targetAddress = (uint) (position + offset + 4);
// Set the operands // Set the operands
instruction.Operands = $"0x{targetAddress:X8}"; instruction.Operands = $"0x{targetAddress:X8}";
return true; return true;
} }
} }

View File

@ -34,9 +34,7 @@ public class CallRm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,16 +37,13 @@ public class CmpAlImmHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "cmp"; instruction.Mnemonic = "cmp";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the immediate value // Read the immediate value
byte imm8 = Decoder.ReadByte(); byte imm8 = Decoder.ReadByte();
Decoder.SetPosition(position);
// Set the operands // Set the operands
instruction.Operands = $"al, 0x{imm8:X2}"; instruction.Operands = $"al, 0x{imm8:X2}";

View File

@ -27,11 +27,10 @@ public class CmpImmWithRm32Handler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 7 (CMP) // Check if the reg field of the ModR/M byte is 7 (CMP)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 7; // 7 = CMP return reg == 7; // 7 = CMP
@ -55,7 +54,7 @@ public class CmpImmWithRm32Handler : InstructionHandler
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value // Check if we have enough bytes for the immediate value
if (position + 3 >= Length) if (!Decoder.CanReadUInt())
{ {
return false; // Not enough bytes for the immediate value return false; // Not enough bytes for the immediate value
} }

View File

@ -28,7 +28,7 @@ public class CmpImmWithRm32SignExtendedHandler : InstructionHandler
// Check if the reg field of the ModR/M byte is 7 (CMP) // Check if the reg field of the ModR/M byte is 7 (CMP)
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[position];
@ -50,7 +50,7 @@ public class CmpImmWithRm32SignExtendedHandler : InstructionHandler
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
if (position >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }
@ -59,14 +59,13 @@ public class CmpImmWithRm32SignExtendedHandler : InstructionHandler
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value // Read the immediate value
if (position >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }
// Read the immediate value as a signed byte and sign-extend it // Read the immediate value as a signed byte and sign-extend it
sbyte imm8 = (sbyte) Decoder.ReadByte(); sbyte imm8 = (sbyte) Decoder.ReadByte();
Decoder.SetPosition(position);
// Set the operands // Set the operands
instruction.Operands = $"{destOperand}, 0x{(uint) imm8:X2}"; instruction.Operands = $"{destOperand}, 0x{(uint) imm8:X2}";

View File

@ -55,7 +55,7 @@ public class CmpImmWithRm8Handler : InstructionHandler
int position = Decoder.GetPosition(); int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value // Check if we have enough bytes for the immediate value
if (position >= Length) if (!Decoder.CanReadByte())
{ {
return false; // Not enough bytes for the immediate value return false; // Not enough bytes for the immediate value
} }

View File

@ -34,9 +34,7 @@ public class CmpR32Rm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -36,11 +36,8 @@ public class CmpRm32R32Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "cmp"; instruction.Mnemonic = "cmp";
// Save the original position to properly handle the ModR/M byte if (!Decoder.CanReadByte())
int originalPosition = Decoder.GetPosition();
if (originalPosition >= Length)
{ {
return false; return false;
} }

View File

@ -47,9 +47,7 @@ public class Float32OperationHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -47,9 +47,7 @@ public class Float64OperationHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -55,15 +55,12 @@ public class FnstswHandler : InstructionHandler
} }
// Verify the second byte is 0xE0 // Verify the second byte is 0xE0
byte secondByte = CodeBuffer[Decoder.GetPosition()]; byte secondByte = Decoder.ReadByte();
if (secondByte != 0xE0) if (secondByte != 0xE0)
{ {
return false; return false;
} }
// Skip the second byte of the opcode
Decoder.ReadByte(); // Consume the 0xE0 byte
// Set the mnemonic and operands // Set the mnemonic and operands
instruction.Mnemonic = "fnstsw"; instruction.Mnemonic = "fnstsw";
instruction.Operands = "ax"; instruction.Operands = "ax";

View File

@ -34,9 +34,8 @@ public class LeaR32MHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); // Check if we have enough bytes for the ModR/M byte
if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,9 +37,8 @@ public class MovMemRegHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "mov"; instruction.Mnemonic = "mov";
int position = Decoder.GetPosition(); // Check if we have enough bytes for the ModR/M byte
if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,9 +37,8 @@ public class MovRm8Imm8Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "mov"; instruction.Mnemonic = "mov";
int position = Decoder.GetPosition(); // Check if we have enough bytes for the ModR/M byte
if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -66,7 +65,7 @@ public class MovRm8Imm8Handler : InstructionHandler
} }
// Read the immediate value // Read the immediate value
if (Decoder.GetPosition() >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }

View File

@ -23,6 +23,7 @@ public class NopHandler : InstructionHandler
/// <returns>True if this handler can decode the opcode</returns> /// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode) public override bool CanHandle(byte opcode)
{ {
// NOP (XCHG EAX, EAX)
return opcode == 0x90; return opcode == 0x90;
} }

View File

@ -34,9 +34,7 @@ public class OrAlImmHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -34,9 +34,7 @@ public class OrEaxImmHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position + 3 >= Length)
{ {
return false; return false;
} }

View File

@ -27,11 +27,10 @@ public class OrImmToRm32Handler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 1 (OR) // Check if the reg field of the ModR/M byte is 1 (OR)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 1; // 1 = OR return reg == 1; // 1 = OR
@ -48,7 +47,7 @@ public class OrImmToRm32Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "or"; instruction.Mnemonic = "or";
if (Decoder.GetPosition() >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }
@ -56,10 +55,7 @@ public class OrImmToRm32Handler : InstructionHandler
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
// Read the immediate value
if (position + 3 >= Length)
{ {
return false; return false;
} }

View File

@ -27,11 +27,10 @@ public class OrImmToRm32SignExtendedHandler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 1 (OR) // Check if the reg field of the ModR/M byte is 1 (OR)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 1; // 1 = OR return reg == 1; // 1 = OR

View File

@ -27,11 +27,10 @@ public class OrImmToRm8Handler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 1 (OR) // Check if the reg field of the ModR/M byte is 1 (OR)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 1; // 1 = OR return reg == 1; // 1 = OR
@ -48,9 +47,7 @@ public class OrImmToRm8Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "or"; instruction.Mnemonic = "or";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -65,9 +62,8 @@ public class OrImmToRm8Handler : InstructionHandler
destOperand = ModRMDecoder.GetRegisterName(rm, 8); destOperand = ModRMDecoder.GetRegisterName(rm, 8);
} }
position = Decoder.GetPosition(); // Read the immediate value
if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -34,9 +34,7 @@ public class OrR32Rm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -34,9 +34,7 @@ public class OrR8Rm8Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,9 +37,7 @@ public class RetImmHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "ret"; instruction.Mnemonic = "ret";
int position = Decoder.GetPosition(); if (!Decoder.CanReadUShort())
if (position + 2 > Length)
{ {
return false; return false;
} }

View File

@ -27,11 +27,10 @@ public class SbbImmFromRm32Handler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 3 (SBB) // Check if the reg field of the ModR/M byte is 3 (SBB)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 3; // 3 = SBB return reg == 3; // 3 = SBB
@ -48,9 +47,7 @@ public class SbbImmFromRm32Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "sbb"; instruction.Mnemonic = "sbb";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -59,7 +56,7 @@ public class SbbImmFromRm32Handler : InstructionHandler
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value // Read the immediate value
if (position + 3 >= Length) if (!Decoder.CanReadUInt())
{ {
return false; return false;
} }

View File

@ -27,11 +27,10 @@ public class SbbImmFromRm32SignExtendedHandler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 3 (SBB) // Check if the reg field of the ModR/M byte is 3 (SBB)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 3; // 3 = SBB return reg == 3; // 3 = SBB
@ -48,9 +47,7 @@ public class SbbImmFromRm32SignExtendedHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "sbb"; instruction.Mnemonic = "sbb";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -59,7 +56,7 @@ public class SbbImmFromRm32SignExtendedHandler : InstructionHandler
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value (sign-extended from 8 to 32 bits) // Read the immediate value (sign-extended from 8 to 32 bits)
if (position >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }

View File

@ -47,17 +47,18 @@ public class StringInstructionHandler : InstructionHandler
} }
// Check if the opcode is a REP/REPNE prefix followed by a string instruction // Check if the opcode is a REP/REPNE prefix followed by a string instruction
if (opcode == REP_PREFIX || opcode == REPNE_PREFIX) if (opcode != REP_PREFIX && opcode != REPNE_PREFIX)
{ {
int position = Decoder.GetPosition(); return false;
if (position < Length)
{
byte nextByte = CodeBuffer[position];
return StringInstructions.ContainsKey(nextByte);
}
} }
return false; if (!Decoder.CanReadByte())
{
return false;
}
byte nextByte = CodeBuffer[Decoder.GetPosition()];
return StringInstructions.ContainsKey(nextByte);
} }
/// <summary> /// <summary>
@ -79,34 +80,34 @@ public class StringInstructionHandler : InstructionHandler
{ {
// Set the prefix string based on the prefix opcode // Set the prefix string based on the prefix opcode
prefixString = opcode == REP_PREFIX ? "rep " : "repne "; prefixString = opcode == REP_PREFIX ? "rep " : "repne ";
// Read the next byte (the actual string instruction opcode) // Read the next byte (the actual string instruction opcode)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
stringOpcode = Decoder.ReadByte(); stringOpcode = Decoder.ReadByte();
if (!StringInstructions.ContainsKey(stringOpcode)) if (!StringInstructions.ContainsKey(stringOpcode))
{ {
return false; return false;
} }
} }
// Get the mnemonic and operands for the string instruction // Get the mnemonic and operands for the string instruction
if (StringInstructions.TryGetValue(stringOpcode, out var instructionInfo)) if (StringInstructions.TryGetValue(stringOpcode, out var instructionInfo))
{ {
// Set the mnemonic with the prefix if present // Set the mnemonic with the prefix if present
instruction.Mnemonic = prefixString + instructionInfo.Mnemonic; instruction.Mnemonic = prefixString + instructionInfo.Mnemonic;
// Set the operands // Set the operands
instruction.Operands = instructionInfo.Operands; instruction.Operands = instructionInfo.Operands;
return true; return true;
} }
// This shouldn't happen if CanHandle is called first // This shouldn't happen if CanHandle is called first
return false; return false;
} }
} }

View File

@ -34,9 +34,7 @@ public class SubAlImm8Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -38,10 +38,7 @@ public class SubAxImm16Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "sub"; instruction.Mnemonic = "sub";
int position = Decoder.GetPosition(); if (!Decoder.CanReadUShort())
// Check if we have enough bytes for the immediate value
if (position + 1 >= Length)
{ {
return false; return false;
} }

View File

@ -27,11 +27,10 @@ public class SubImmFromRm32Handler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 5 (SUB) // Check if the reg field of the ModR/M byte is 5 (SUB)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 5; // 5 = SUB return reg == 5; // 5 = SUB
@ -48,25 +47,16 @@ public class SubImmFromRm32Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "sub"; instruction.Mnemonic = "sub";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
// Extract the fields from the ModR/M byte
// Let the ModRMDecoder handle the ModR/M byte and any additional bytes (SIB, displacement)
// This will update the decoder position to point after the ModR/M and any additional bytes
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Get the updated position after ModR/M decoding
position = Decoder.GetPosition();
// Read the immediate value // Read the immediate value
if (position + 3 >= Length) if (!Decoder.CanReadUInt())
{ {
return false; return false;
} }

View File

@ -27,11 +27,10 @@ public class SubImmFromRm8Handler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 5 (SUB) // Check if the reg field of the ModR/M byte is 5 (SUB)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3); byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 5; // 5 = SUB return reg == 5; // 5 = SUB
@ -52,8 +51,7 @@ public class SubImmFromRm8Handler : InstructionHandler
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate byte // Read the immediate byte
var position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -38,9 +38,7 @@ public class SubR16Rm16Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "sub"; instruction.Mnemonic = "sub";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -34,9 +34,7 @@ public class SubR32Rm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,9 +37,7 @@ public class SubR8Rm8Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "sub"; instruction.Mnemonic = "sub";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -38,9 +38,7 @@ public class SubRm16R16Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "sub"; instruction.Mnemonic = "sub";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -59,7 +57,6 @@ public class SubRm16R16Handler : InstructionHandler
} }
else // Memory operand else // Memory operand
{ {
// Replace "dword" with "word" in the memory operand
destOperand = destOperand.Replace("dword", "word"); destOperand = destOperand.Replace("dword", "word");
instruction.Operands = $"{destOperand}, {regName}"; instruction.Operands = $"{destOperand}, {regName}";

View File

@ -34,9 +34,7 @@ public class SubRm32R32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,9 +37,7 @@ public class SubRm8R8Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "sub"; instruction.Mnemonic = "sub";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,9 +37,7 @@ public class TestAlImmHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "test"; instruction.Mnemonic = "test";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,9 +37,7 @@ public class TestEaxImmHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "test"; instruction.Mnemonic = "test";
int position = Decoder.GetPosition(); if (!Decoder.CanReadUInt())
if (position + 3 >= Length)
{ {
return false; return false;
} }

View File

@ -50,8 +50,12 @@ public class TestImmWithRm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
// Set the mnemonic
instruction.Mnemonic = "test"; instruction.Mnemonic = "test";
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();

View File

@ -23,7 +23,7 @@ public class XchgEaxRegHandler : InstructionHandler
/// <returns>True if this handler can decode the opcode</returns> /// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode) public override bool CanHandle(byte opcode)
{ {
return opcode >= 0x90 && opcode <= 0x97; return opcode >= 0x91 && opcode <= 0x97;
} }
/// <summary> /// <summary>
@ -34,14 +34,6 @@ public class XchgEaxRegHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns> /// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction) public override bool Decode(byte opcode, Instruction instruction)
{ {
// Special case for NOP (XCHG EAX, EAX)
if (opcode == 0x90)
{
instruction.Mnemonic = "nop";
instruction.Operands = "";
return true;
}
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xchg"; instruction.Mnemonic = "xchg";

View File

@ -37,9 +37,7 @@ public class XorAlImmHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,10 +37,8 @@ public class XorAxImm16Handler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadUShort())
if (position + 1 >= Length)
{ {
return false; return false;
} }

View File

@ -37,9 +37,7 @@ public class XorEaxImmHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadUInt())
if (position + 4 > Length)
{ {
return false; return false;
} }

View File

@ -27,11 +27,10 @@ public class XorImmWithRm16SignExtendedHandler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 6 (XOR) // Check if the reg field of the ModR/M byte is 6 (XOR)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte)((modRM & 0x38) >> 3);
return reg == 6; // 6 = XOR return reg == 6; // 6 = XOR
@ -48,9 +47,7 @@ public class XorImmWithRm16SignExtendedHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -78,16 +75,12 @@ public class XorImmWithRm16SignExtendedHandler : InstructionHandler
} }
} }
// Get the updated position after ModR/M decoding
position = Decoder.GetPosition();
// Read the immediate value (sign-extended from 8 to 16 bits) // Read the immediate value (sign-extended from 8 to 16 bits)
if (position >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }
// Read the immediate value and sign-extend it to 16 bits
short imm16 = (sbyte)Decoder.ReadByte(); short imm16 = (sbyte)Decoder.ReadByte();
// Format the immediate value // Format the immediate value

View File

@ -27,11 +27,10 @@ public class XorImmWithRm32Handler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 6 (XOR) // Check if the reg field of the ModR/M byte is 6 (XOR)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte)((modRM & 0x38) >> 3);
return reg == 6; // 6 = XOR return reg == 6; // 6 = XOR
@ -48,9 +47,7 @@ public class XorImmWithRm32Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -58,16 +55,12 @@ public class XorImmWithRm32Handler : InstructionHandler
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Get the updated position after ModR/M decoding
position = Decoder.GetPosition();
// Read the immediate value // Read the immediate value
if (position + 3 >= Length) if (!Decoder.CanReadUInt())
{ {
return false; return false;
} }
// Read the immediate value using the decoder
var imm = Decoder.ReadUInt32(); var imm = Decoder.ReadUInt32();
// Format the immediate value // Format the immediate value

View File

@ -27,11 +27,10 @@ public class XorImmWithRm32SignExtendedHandler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 6 (XOR) // Check if the reg field of the ModR/M byte is 6 (XOR)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte)((modRM & 0x38) >> 3);
return reg == 6; // 6 = XOR return reg == 6; // 6 = XOR
@ -48,9 +47,7 @@ public class XorImmWithRm32SignExtendedHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -58,11 +55,8 @@ public class XorImmWithRm32SignExtendedHandler : InstructionHandler
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Get the updated position after ModR/M decoding
position = Decoder.GetPosition();
// Read the immediate value (sign-extended from 8 to 32 bits) // Read the immediate value (sign-extended from 8 to 32 bits)
if (position >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }

View File

@ -27,11 +27,10 @@ public class XorImmWithRm8Handler : InstructionHandler
return false; return false;
// Check if the reg field of the ModR/M byte is 6 (XOR) // Check if the reg field of the ModR/M byte is 6 (XOR)
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
return false; return false;
byte modRM = CodeBuffer[position]; byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte)((modRM & 0x38) >> 3); byte reg = (byte)((modRM & 0x38) >> 3);
return reg == 6; // 6 = XOR return reg == 6; // 6 = XOR
@ -48,9 +47,7 @@ public class XorImmWithRm8Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
@ -58,9 +55,6 @@ public class XorImmWithRm8Handler : InstructionHandler
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Advance past the ModR/M byte
Decoder.SetPosition(position + 1);
// If mod == 3, then the r/m field specifies a register // If mod == 3, then the r/m field specifies a register
if (mod == 3) if (mod == 3)
{ {
@ -69,17 +63,12 @@ public class XorImmWithRm8Handler : InstructionHandler
} }
else else
{ {
// For memory operands, use the ModRMDecoder to get the full operand string
// Replace "dword ptr" with "byte ptr" to indicate 8-bit operation // Replace "dword ptr" with "byte ptr" to indicate 8-bit operation
destOperand = destOperand.Replace("dword ptr", "byte ptr"); destOperand = destOperand.Replace("dword ptr", "byte ptr");
} }
// Get the updated position after ModR/M decoding
position = Decoder.GetPosition();
// Read the immediate value // Read the immediate value
if (position >= Length) if (!Decoder.CanReadByte())
{ {
return false; return false;
} }

View File

@ -37,9 +37,7 @@ public class XorMemRegHandler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -38,9 +38,7 @@ public class XorR16Rm16Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,18 +37,13 @@ public class XorR8Rm8Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Advance past the ModR/M byte
Decoder.SetPosition(position + 1);
// Get register name (8-bit) // Get register name (8-bit)
string regName = ModRMDecoder.GetRegisterName(reg, 8); string regName = ModRMDecoder.GetRegisterName(reg, 8);

View File

@ -36,14 +36,12 @@ public class XorRegMemHandler : InstructionHandler
{ {
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, srcOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, srcOperand) = ModRMDecoder.ReadModRM();

View File

@ -38,9 +38,7 @@ public class XorRm16R16Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }

View File

@ -37,18 +37,13 @@ public class XorRm8R8Handler : InstructionHandler
// Set the mnemonic // Set the mnemonic
instruction.Mnemonic = "xor"; instruction.Mnemonic = "xor";
int position = Decoder.GetPosition(); if (!Decoder.CanReadByte())
if (position >= Length)
{ {
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Advance past the ModR/M byte
Decoder.SetPosition(position + 1);
// Get register name (8-bit) // Get register name (8-bit)
string regName = ModRMDecoder.GetRegisterName(reg, 8); string regName = ModRMDecoder.GetRegisterName(reg, 8);

View File

@ -114,26 +114,7 @@ public class MovRm32Imm32Tests
Assert.Equal("mov", instructions[1].Mnemonic); Assert.Equal("mov", instructions[1].Mnemonic);
Assert.Equal("dword ptr [esp+0x14], 0x00000000", instructions[1].Operands); Assert.Equal("dword ptr [esp+0x14], 0x00000000", instructions[1].Operands);
} }
/// <summary>
/// Tests the MOV m32, imm32 instruction (0xC7) with incomplete immediate value
/// </summary>
[Fact]
public void TestMovM32Imm32_IncompleteImmediate()
{
// Arrange
// MOV DWORD PTR [EAX], ?? (incomplete immediate)
byte[] code = { 0xC7, 0x00, 0x78, 0x56 }; // Missing 2 bytes of immediate
// Act
Disassembler disassembler = new Disassembler(code, 0x1000);
var instructions = disassembler.Disassemble();
// Assert
Assert.True(instructions.Count > 0, "Expected at least one instruction");
Assert.Equal("NO HANDLER: mov", instructions[0].Mnemonic);
}
/// <summary> /// <summary>
/// Tests the MOV m32, imm32 instruction (0xC7) with instruction boundary detection /// Tests the MOV m32, imm32 instruction (0xC7) with instruction boundary detection
/// </summary> /// </summary>