mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2025-05-19 03:41:18 +03:00
Moved AND instruction handlers from ArithmeticImmediate to dedicated And namespace for better organization
This commit is contained in:
parent
af94b88868
commit
e8a16e7ecd
@ -1,84 +0,0 @@
|
||||
namespace X86Disassembler.X86.Handlers.ArithmeticImmediate;
|
||||
|
||||
/// <summary>
|
||||
/// Handler for AND r/m32, imm32 instruction (0x81 /4)
|
||||
/// </summary>
|
||||
public class AndImmWithRm32Handler : InstructionHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the AndImmWithRm32Handler 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 AndImmWithRm32Handler(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)
|
||||
{
|
||||
if (opcode != 0x81)
|
||||
return false;
|
||||
|
||||
// Check if the reg field of the ModR/M byte is 4 (AND)
|
||||
int position = Decoder.GetPosition();
|
||||
if (position >= Length)
|
||||
return false;
|
||||
|
||||
byte modRM = CodeBuffer[position];
|
||||
byte reg = (byte)((modRM & 0x38) >> 3);
|
||||
|
||||
return reg == 4; // 4 = AND
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodes an AND r/m32, imm32 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
|
||||
instruction.Mnemonic = "and";
|
||||
|
||||
int position = Decoder.GetPosition();
|
||||
|
||||
if (position >= Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the ModR/M byte
|
||||
byte modRM = CodeBuffer[position++];
|
||||
Decoder.SetPosition(position);
|
||||
|
||||
// Extract the fields from the ModR/M byte
|
||||
byte mod = (byte)((modRM & 0xC0) >> 6);
|
||||
byte reg = (byte)((modRM & 0x38) >> 3); // Should be 4 for AND
|
||||
byte rm = (byte)(modRM & 0x07);
|
||||
|
||||
// Decode the destination operand
|
||||
string destOperand = ModRMDecoder.DecodeModRM(mod, rm, false);
|
||||
|
||||
// Read the immediate value
|
||||
if (position + 3 >= Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
|
||||
Decoder.SetPosition(position + 4);
|
||||
|
||||
// Set the operands
|
||||
instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
namespace X86Disassembler.X86.Handlers.ArithmeticImmediate;
|
||||
|
||||
/// <summary>
|
||||
/// Handler for AND r/m32, imm8 (sign-extended) instruction (0x83 /4)
|
||||
/// </summary>
|
||||
public class AndImmWithRm32SignExtendedHandler : InstructionHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the AndImmWithRm32SignExtendedHandler 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 AndImmWithRm32SignExtendedHandler(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)
|
||||
{
|
||||
if (opcode != 0x83)
|
||||
return false;
|
||||
|
||||
// Check if the reg field of the ModR/M byte is 4 (AND)
|
||||
int position = Decoder.GetPosition();
|
||||
if (position >= Length)
|
||||
return false;
|
||||
|
||||
byte modRM = CodeBuffer[position];
|
||||
byte reg = (byte)((modRM & 0x38) >> 3);
|
||||
|
||||
return reg == 4; // 4 = AND
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodes an AND r/m32, imm8 (sign-extended) 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
|
||||
instruction.Mnemonic = "and";
|
||||
|
||||
int position = Decoder.GetPosition();
|
||||
|
||||
if (position >= Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the ModR/M byte
|
||||
byte modRM = CodeBuffer[position++];
|
||||
Decoder.SetPosition(position);
|
||||
|
||||
// Extract the fields from the ModR/M byte
|
||||
byte mod = (byte)((modRM & 0xC0) >> 6);
|
||||
byte reg = (byte)((modRM & 0x38) >> 3); // Should be 4 for AND
|
||||
byte rm = (byte)(modRM & 0x07);
|
||||
|
||||
// Decode the destination operand
|
||||
string destOperand = ModRMDecoder.DecodeModRM(mod, rm, false);
|
||||
|
||||
// Read the immediate value (sign-extended from 8 to 32 bits)
|
||||
if (position >= Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
sbyte imm8 = (sbyte)CodeBuffer[position];
|
||||
int imm32 = imm8; // Sign-extend to 32 bits
|
||||
Decoder.SetPosition(position + 1);
|
||||
|
||||
// Set the operands
|
||||
instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -114,10 +114,6 @@ public class InstructionHandlerFactory
|
||||
_handlers.Add(new SbbImmFromRm32Handler(_codeBuffer, _decoder, _length));
|
||||
_handlers.Add(new SbbImmFromRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
|
||||
|
||||
// AND handlers
|
||||
_handlers.Add(new AndImmWithRm32Handler(_codeBuffer, _decoder, _length));
|
||||
_handlers.Add(new AndImmWithRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
|
||||
|
||||
// SUB handlers
|
||||
_handlers.Add(new SubImmFromRm32Handler(_codeBuffer, _decoder, _length));
|
||||
_handlers.Add(new SubImmFromRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
|
||||
|
@ -1,90 +0,0 @@
|
||||
namespace X86DisassemblerTests;
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
using X86Disassembler.X86;
|
||||
using X86Disassembler.X86.Handlers;
|
||||
using X86Disassembler.X86.Handlers.ArithmeticImmediate;
|
||||
using X86Disassembler.X86.Handlers.Inc;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for debugging the specific problematic sequence
|
||||
/// </summary>
|
||||
public class SequenceDebuggingTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests each byte in the problematic sequence individually
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Debug_ProblematicSequence_ByteByByte()
|
||||
{
|
||||
// The problematic sequence
|
||||
byte[] fullSequence = new byte[] { 0x08, 0x83, 0xC1, 0x04, 0x50, 0xE8, 0x42, 0x01, 0x00, 0x00 };
|
||||
|
||||
// Test each byte individually
|
||||
for (int i = 0; i < fullSequence.Length; i++)
|
||||
{
|
||||
byte opcode = fullSequence[i];
|
||||
string expectedMnemonic = GetExpectedMnemonic(opcode);
|
||||
|
||||
// Create a buffer with just this byte
|
||||
byte[] buffer = new byte[] { opcode };
|
||||
var decoder = new InstructionDecoder(buffer, buffer.Length);
|
||||
var factory = new InstructionHandlerFactory(buffer, decoder, buffer.Length);
|
||||
|
||||
// Get the handler for this opcode
|
||||
var handler = factory.GetHandler(opcode);
|
||||
|
||||
// Output debug information
|
||||
Console.WriteLine($"Byte 0x{opcode:X2} at position {i}: Handler = {(handler != null ? handler.GetType().Name : "null")}");
|
||||
|
||||
// If we have a handler, decode the instruction
|
||||
if (handler != null)
|
||||
{
|
||||
var instruction = new Instruction();
|
||||
bool success = handler.Decode(opcode, instruction);
|
||||
Console.WriteLine($" Decoded as: {instruction.Mnemonic} {instruction.Operands}");
|
||||
}
|
||||
}
|
||||
|
||||
// Now test the specific sequence 0x83 0xC1 0x04 (ADD ecx, 0x04)
|
||||
byte[] addSequence = new byte[] { 0x83, 0xC1, 0x04 };
|
||||
var addDecoder = new InstructionDecoder(addSequence, addSequence.Length);
|
||||
var addInstruction = addDecoder.DecodeInstruction();
|
||||
|
||||
Console.WriteLine($"\nDecoding 0x83 0xC1 0x04 directly: {addInstruction?.Mnemonic} {addInstruction?.Operands}");
|
||||
|
||||
// Now test the sequence 0x08 0x83 0xC1 0x04
|
||||
byte[] orAddSequence = new byte[] { 0x08, 0x83, 0xC1, 0x04 };
|
||||
var orAddDecoder = new InstructionDecoder(orAddSequence, orAddSequence.Length);
|
||||
|
||||
// Decode the first instruction (0x08)
|
||||
var orInstruction = orAddDecoder.DecodeInstruction();
|
||||
Console.WriteLine($"\nDecoding 0x08 in sequence 0x08 0x83 0xC1 0x04: {orInstruction?.Mnemonic} {orInstruction?.Operands}");
|
||||
|
||||
// Decode the second instruction (0x83 0xC1 0x04)
|
||||
var secondInstruction = orAddDecoder.DecodeInstruction();
|
||||
Console.WriteLine($"Decoding 0x83 0xC1 0x04 after 0x08: {secondInstruction?.Mnemonic} {secondInstruction?.Operands}");
|
||||
|
||||
// Assert that we get the expected mnemonic for the second instruction
|
||||
Assert.Equal("add", secondInstruction?.Mnemonic);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the expected mnemonic for a given opcode
|
||||
/// </summary>
|
||||
private string GetExpectedMnemonic(byte opcode)
|
||||
{
|
||||
return opcode switch
|
||||
{
|
||||
0x08 => "or",
|
||||
0x83 => "add", // Assuming reg field is 0 (ADD)
|
||||
0x50 => "push",
|
||||
0xE8 => "call",
|
||||
0x40 => "inc",
|
||||
0x41 => "inc",
|
||||
0x42 => "inc",
|
||||
_ => "??"
|
||||
};
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user