diff --git a/X86Disassembler/Program.cs b/X86Disassembler/Program.cs
index cf27ff3..c19ded2 100644
--- a/X86Disassembler/Program.cs
+++ b/X86Disassembler/Program.cs
@@ -74,6 +74,16 @@ public class Program
// Disassemble all instructions
var instructions = disassembler.Disassemble();
+
+ var unknownIndex = instructions.FindIndex(
+ x => x.ToString()
+ .Contains("??") || x.ToString()
+ .Contains("TODO")
+ );
+ if (unknownIndex != -1)
+ {
+ _ = 5;
+ }
// Print the first 100 instructions
int count = Math.Min(100, instructions.Count);
diff --git a/X86Disassembler/X86/Handlers/Int3Handler.cs b/X86Disassembler/X86/Handlers/Int3Handler.cs
index d104af1..4bb26cd 100644
--- a/X86Disassembler/X86/Handlers/Int3Handler.cs
+++ b/X86Disassembler/X86/Handlers/Int3Handler.cs
@@ -1,12 +1,12 @@
namespace X86Disassembler.X86.Handlers;
///
-/// Handler for CALL rel32 instruction (0xE8)
+/// Handler for INT3 instruction (0xCC)
///
public class Int3Handler : InstructionHandler
{
///
- /// Initializes a new instance of the CallRel32Handler class
+ /// Initializes a new instance of the Int3Handler class
///
/// The buffer containing the code to decode
/// The instruction decoder that owns this handler
@@ -27,7 +27,7 @@ public class Int3Handler : InstructionHandler
}
///
- /// Decodes a CALL rel32 instruction
+ /// Decodes an INT3 instruction
///
/// The opcode of the instruction
/// The instruction object to populate
diff --git a/X86Disassembler/X86/Handlers/Mov/MovRegMemHandler.cs b/X86Disassembler/X86/Handlers/Mov/MovRegMemHandler.cs
index 7599714..b949bcf 100644
--- a/X86Disassembler/X86/Handlers/Mov/MovRegMemHandler.cs
+++ b/X86Disassembler/X86/Handlers/Mov/MovRegMemHandler.cs
@@ -34,36 +34,56 @@ public class MovRegMemHandler : InstructionHandler
/// True if the instruction was successfully decoded
public override bool Decode(byte opcode, Instruction instruction)
{
+ // Save the original position for raw bytes calculation
+ int startPosition = Decoder.GetPosition();
+
// Set the mnemonic
instruction.Mnemonic = "mov";
- int position = Decoder.GetPosition();
-
- if (position >= Length)
+ if (startPosition >= Length)
{
- return false;
+ instruction.Operands = "??";
+ instruction.RawBytes = new byte[] { opcode };
+ return true;
}
// Determine operand size (0 = 8-bit, 1 = 32-bit)
bool operandSize32 = (opcode & 0x01) != 0;
int operandSize = operandSize32 ? 32 : 8;
- // Read the ModR/M byte
- var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
+ // Use ModRMDecoder to decode the ModR/M byte
+ var (mod, reg, rm, rmOperand) = ModRMDecoder.ReadModRM(false); // false for 32-bit operand
// Get register name based on size
- string regName = ModRMDecoder.GetRegisterName(reg, operandSize);
+ string regName;
+ if (operandSize == 8)
+ {
+ regName = GetRegister8(reg);
+ }
+ else
+ {
+ regName = GetRegister32(reg);
+ }
- // For mod == 3, both operands are registers
- if (mod == 3)
+ // Get the position after decoding the ModR/M byte
+ int newPosition = Decoder.GetPosition();
+
+ // Set the operands - register is the destination, r/m is the source (for 0x8B)
+ // This matches the correct x86 instruction format: MOV r32, r/m32
+ instruction.Operands = $"{regName}, {rmOperand}";
+
+ // Set the raw bytes
+ int totalBytes = newPosition - startPosition + 1; // +1 for opcode
+ byte[] rawBytes = new byte[totalBytes];
+ rawBytes[0] = opcode;
+ for (int i = 0; i < totalBytes - 1; i++)
{
- string rmRegName = ModRMDecoder.GetRegisterName(rm, operandSize);
- instruction.Operands = $"{rmRegName}, {regName}";
- }
- else // Memory operand
- {
- instruction.Operands = $"{memOperand}, {regName}";
+ if (startPosition + i < Length)
+ {
+ rawBytes[i + 1] = CodeBuffer[startPosition + i];
+ }
}
+ instruction.RawBytes = rawBytes;
return true;
}
diff --git a/X86DisassemblerTests/Group1SignExtendedHandlerTests.cs b/X86DisassemblerTests/Group1SignExtendedHandlerTests.cs
index d38f4ba..638a281 100644
--- a/X86DisassemblerTests/Group1SignExtendedHandlerTests.cs
+++ b/X86DisassemblerTests/Group1SignExtendedHandlerTests.cs
@@ -37,8 +37,8 @@ public class Group1SignExtendedHandlerTests
{
// Arrange
// This is the sequence from the problematic example:
- // 08 83 C1 04 50 E8 42 01 00 00
- byte[] codeBuffer = new byte[] { 0x08, 0x83, 0xC1, 0x04, 0x50, 0xE8, 0x42, 0x01, 0x00, 0x00 };
+ // 83 C1 04 50 E8 42 01 00 00
+ byte[] codeBuffer = new byte[] { 0x83, 0xC1, 0x04, 0x50, 0xE8, 0x42, 0x01, 0x00, 0x00 };
var disassembler = new Disassembler(codeBuffer, 0);
// Act
@@ -47,15 +47,12 @@ public class Group1SignExtendedHandlerTests
// Assert
Assert.True(instructions.Count >= 3, $"Expected at least 3 instructions, but got {instructions.Count}");
- // First instruction should be OR r/m8, r8 (but might be incomplete)
- Assert.Equal("or", instructions[0].Mnemonic);
+ // First instruction should be ADD ecx, 0x04
+ Assert.Equal("add", instructions[0].Mnemonic);
+ Assert.Equal("ecx, 0x00000004", instructions[0].Operands);
- // Second instruction should be ADD ecx, 0x04
- Assert.Equal("add", instructions[1].Mnemonic);
- Assert.Equal("ecx, 0x00000004", instructions[1].Operands);
-
- // Third instruction should be PUSH eax
- Assert.Equal("push", instructions[2].Mnemonic);
- Assert.Equal("eax", instructions[2].Operands);
+ // Second instruction should be PUSH eax
+ Assert.Equal("push", instructions[1].Mnemonic);
+ Assert.Equal("eax", instructions[1].Operands);
}
}
diff --git a/X86DisassemblerTests/HandlerSelectionTests.cs b/X86DisassemblerTests/HandlerSelectionTests.cs
index aafddbf..34a8ccc 100644
--- a/X86DisassemblerTests/HandlerSelectionTests.cs
+++ b/X86DisassemblerTests/HandlerSelectionTests.cs
@@ -56,5 +56,6 @@ public class HandlerSelectionTests
// Third instruction should be PUSH eax
Assert.Equal("push", instructions[2].Mnemonic);
+ Assert.Equal("eax", instructions[2].Operands);
}
}