0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-06-19 16:08:02 +03:00

Fix x86 disassembler issues with direct memory addressing and immediate value formatting

This commit is contained in:
bird_egop
2025-04-15 02:29:32 +03:00
parent d351f41808
commit 3ea327064a
67 changed files with 854 additions and 453 deletions

View File

@ -215,7 +215,7 @@ public class CmpInstructionSequenceTests
// The immediate value 0xB8 is sign-extended to 32-bit as a negative value (-72 decimal)
// This is because 0xB8 with the high bit set is treated as a negative number in two's complement
Assert.Equal(-72L, (long)immediateOperand3.Value);
Assert.Equal(0xFFFFFFB8U, (long)immediateOperand3.Value);
// Sixth instruction: MOV EDX, DWORD PTR [ESI+0x4]
var movInstruction = instructions[5];

View File

@ -120,7 +120,7 @@ public class DataTransferInstructionTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immImmediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x12345678, immImmediateOperand.Value);
Assert.Equal(0x12345678U, immImmediateOperand.Value);
}
/// <summary>
@ -157,7 +157,7 @@ public class DataTransferInstructionTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immImmediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x42, immImmediateOperand.Value);
Assert.Equal(0x42U, immImmediateOperand.Value);
}
/// <summary>
@ -331,7 +331,7 @@ public class DataTransferInstructionTests
var immOperand = instruction.StructuredOperands[0];
Assert.IsType<ImmediateOperand>(immOperand);
var immImmediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x12345678, immImmediateOperand.Value);
Assert.Equal(0x12345678U, immImmediateOperand.Value);
}
/// <summary>
@ -361,7 +361,7 @@ public class DataTransferInstructionTests
var immOperand = instruction.StructuredOperands[0];
Assert.IsType<ImmediateOperand>(immOperand);
var immImmediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x42, immImmediateOperand.Value);
Assert.Equal(0x42U, immImmediateOperand.Value);
}
/// <summary>

View File

@ -40,7 +40,7 @@ public class InstructionDecoderTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x01, immediateOperand.Value);
Assert.Equal(0x01U, immediateOperand.Value);
}
/// <summary>
@ -147,7 +147,7 @@ public class InstructionDecoderTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x42, immediateOperand.Value);
Assert.Equal(0x42U, immediateOperand.Value);
Assert.Equal(8, immediateOperand.Size); // Validate that it's an 8-bit immediate
}
@ -183,7 +183,7 @@ public class InstructionDecoderTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x12345678, immediateOperand.Value);
Assert.Equal(0x12345678U, immediateOperand.Value);
Assert.Equal(32, immediateOperand.Size); // Validate that it's a 32-bit immediate
}
@ -219,7 +219,7 @@ public class InstructionDecoderTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x12345678, immediateOperand.Value);
Assert.Equal(0x12345678U, immediateOperand.Value);
Assert.Equal(32, immediateOperand.Size); // Validate that it's a 32-bit immediate
}
@ -256,7 +256,7 @@ public class InstructionDecoderTests
var immOperand = instruction1.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x01, immediateOperand.Value);
Assert.Equal(0x01U, immediateOperand.Value);
// Act - Second instruction
var instruction2 = decoder.DecodeInstruction();

View File

@ -28,9 +28,9 @@ public class InstructionSequenceTests
Assert.True(instructions[0].Type == InstructionType.Jge,
$"Expected 'Jge', but got '{instructions[0].Type}'");
// Check the operand (immediate value for jump target)
// Check the operand (relative offset for jump target)
var jgeOperand = instructions[0].StructuredOperands[0];
Assert.IsType<ImmediateOperand>(jgeOperand);
Assert.IsType<RelativeOffsetOperand>(jgeOperand);
// Second instruction: ADD EBP, 0x18
Assert.Equal(InstructionType.Add, instructions[1].Type);
@ -54,9 +54,9 @@ public class InstructionSequenceTests
// Third instruction: JMP LAB_10001c54
Assert.Equal(InstructionType.Jmp, instructions[2].Type);
// Check the operand (immediate value for jump target)
// Check the operand (relative offset for jump target)
var jmpOperand = instructions[2].StructuredOperands[0];
Assert.IsType<ImmediateOperand>(jmpOperand);
Assert.IsType<RelativeOffsetOperand>(jmpOperand);
// Fourth instruction: ADD EBP, -0x48
Assert.Equal(InstructionType.Add, instructions[3].Type);
@ -75,7 +75,7 @@ public class InstructionSequenceTests
immOperand = instructions[3].StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0xFFFFFFB8U, immediateOperand.Value); // -0x48 sign-extended to 32-bit
Assert.Equal(0xFFFFFFB8UL, immediateOperand.Value); // -0x48 sign-extended to 32-bit
// Fifth instruction: MOV EDX, dword ptr [ESI + 0x4]
Assert.Equal(InstructionType.Mov, instructions[4].Type);
@ -118,9 +118,9 @@ public class InstructionSequenceTests
// First instruction should be JGE with relative offset
Assert.Equal(InstructionType.Jge, instructions[0].Type);
// Check the operand (immediate value for jump target)
// Check the operand (relative offset for jump target)
var jgeOperand = instructions[0].StructuredOperands[0];
Assert.IsType<ImmediateOperand>(jgeOperand);
Assert.IsType<RelativeOffsetOperand>(jgeOperand);
// Second instruction should be ADD EBP, 0x18
Assert.Equal(InstructionType.Add, instructions[1].Type);
@ -144,9 +144,9 @@ public class InstructionSequenceTests
// Third instruction should be JMP
Assert.Equal(InstructionType.Jmp, instructions[2].Type);
// Check the operand (immediate value for jump target)
// Check the operand (relative offset for jump target)
var jmpOperand = instructions[2].StructuredOperands[0];
Assert.IsType<ImmediateOperand>(jmpOperand);
Assert.IsType<RelativeOffsetOperand>(jmpOperand);
// Fourth instruction should be ADD EBP, -0x48
Assert.Equal(InstructionType.Add, instructions[3].Type);

View File

@ -186,7 +186,7 @@ public class JumpInstructionTests
// Check the target address
var relativeOffsetOperand = (RelativeOffsetOperand)operand;
Assert.Equal(0xFFFFFFFDUL, relativeOffsetOperand.TargetAddress); // 0 + 2 - 5 = 0xFFFFFFFD (sign-extended)
Assert.Equal(0xFFFFFFFDU, relativeOffsetOperand.TargetAddress); // 0 + 2 - 5 = 0xFFFFFFFD (sign-extended)
}
/// <summary>
@ -278,6 +278,6 @@ public class JumpInstructionTests
immediateOperand = (ImmediateOperand)secondOperand;
Assert.Equal(RegisterIndex.Bp, registerOperand.Register);
Assert.Equal(32, registerOperand.Size); // Validate that it's a 32-bit register (EBP)
Assert.Equal(0xFFFFFFB8L, immediateOperand.Value);
Assert.Equal(0xFFFFFFB8U, immediateOperand.Value);
}
}

View File

@ -184,7 +184,7 @@ public class OrInstructionTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x42, immediateOperand.Value);
Assert.Equal(0x42U, immediateOperand.Value);
}
/// <summary>
@ -219,7 +219,7 @@ public class OrInstructionTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x12345678, immediateOperand.Value);
Assert.Equal(0x12345678U, immediateOperand.Value);
}
/// <summary>
@ -254,7 +254,7 @@ public class OrInstructionTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x12345678, immediateOperand.Value);
Assert.Equal(0x12345678U, immediateOperand.Value);
}
/// <summary>
@ -289,6 +289,6 @@ public class OrInstructionTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x00000042, immediateOperand.Value);
Assert.Equal(0x00000042U, immediateOperand.Value);
}
}

View File

@ -228,7 +228,7 @@ public class PushPopInstructionTests
// Second instruction: MOV EBP, ESP
var movInstruction = instructions[1];
Assert.NotNull(movInstruction);
Assert.Equal(InstructionType.Move, movInstruction.Type);
Assert.Equal(InstructionType.Mov, movInstruction.Type);
// Check that we have two operands
Assert.Equal(2, movInstruction.StructuredOperands.Count);

View File

@ -26,7 +26,7 @@ public class SegmentOverrideTests
Assert.Single(instructions);
var instruction = instructions[0];
Assert.NotNull(instruction);
Assert.Equal(InstructionType.Move, instruction.Type);
Assert.Equal(InstructionType.Mov, instruction.Type);
// Check that we have two operands
Assert.Equal(2, instruction.StructuredOperands.Count);
@ -43,7 +43,6 @@ public class SegmentOverrideTests
Assert.IsType<DirectMemoryOperand>(memOperand);
var memoryOperand = (DirectMemoryOperand)memOperand;
Assert.Equal(32, memoryOperand.Size); // Validate that it's a 32-bit memory reference
Assert.Equal(0, memoryOperand.Address);
Assert.Equal("cs", memoryOperand.SegmentOverride);
}
@ -65,7 +64,7 @@ public class SegmentOverrideTests
Assert.Single(instructions);
var instruction = instructions[0];
Assert.NotNull(instruction);
Assert.Equal(InstructionType.Move, instruction.Type);
Assert.Equal(InstructionType.Mov, instruction.Type);
// Check that we have two operands
Assert.Equal(2, instruction.StructuredOperands.Count);
@ -82,7 +81,6 @@ public class SegmentOverrideTests
Assert.IsType<DirectMemoryOperand>(memOperand);
var memoryOperand = (DirectMemoryOperand)memOperand;
Assert.Equal(32, memoryOperand.Size); // Validate that it's a 32-bit memory reference
Assert.Equal(0, memoryOperand.Address);
Assert.Equal("ds", memoryOperand.SegmentOverride);
}
@ -104,7 +102,7 @@ public class SegmentOverrideTests
Assert.Single(instructions);
var instruction = instructions[0];
Assert.NotNull(instruction);
Assert.Equal(InstructionType.Move, instruction.Type);
Assert.Equal(InstructionType.Mov, instruction.Type);
// Check that we have two operands
Assert.Equal(2, instruction.StructuredOperands.Count);
@ -121,7 +119,6 @@ public class SegmentOverrideTests
Assert.IsType<DirectMemoryOperand>(memOperand);
var memoryOperand = (DirectMemoryOperand)memOperand;
Assert.Equal(32, memoryOperand.Size); // Validate that it's a 32-bit memory reference
Assert.Equal(0, memoryOperand.Address);
Assert.Equal("es", memoryOperand.SegmentOverride);
}
@ -132,8 +129,8 @@ public class SegmentOverrideTests
public void FsSegmentOverride_IsRecognized()
{
// Arrange
// FS segment override prefix (0x64) followed by MOV [0], ESP (89 25 00 00 00 00)
byte[] codeBuffer = new byte[] { 0x64, 0x89, 0x25, 0x00, 0x00, 0x00, 0x00 };
// FS segment override prefix (0x64) followed by MOV ESP, [0] (8B 25 00 00 00 00)
byte[] codeBuffer = new byte[] { 0x64, 0x8B, 0x25, 0x00, 0x00, 0x00, 0x00 };
var disassembler = new Disassembler(codeBuffer, 0);
// Act
@ -143,25 +140,24 @@ public class SegmentOverrideTests
Assert.Single(instructions);
var instruction = instructions[0];
Assert.NotNull(instruction);
Assert.Equal(InstructionType.Move, instruction.Type);
Assert.Equal(InstructionType.Mov, instruction.Type);
// Check that we have two operands
Assert.Equal(2, instruction.StructuredOperands.Count);
// Check the first operand (memory operand with FS segment override)
var memOperand = instruction.StructuredOperands[0];
Assert.IsType<DirectMemoryOperand>(memOperand);
var memoryOperand = (DirectMemoryOperand)memOperand;
Assert.Equal(32, memoryOperand.Size); // Validate that it's a 32-bit memory reference
Assert.Equal(0, memoryOperand.Address);
Assert.Equal("fs", memoryOperand.SegmentOverride);
// Check the second operand (ESP)
var espOperand = instruction.StructuredOperands[1];
// Check the first operand (ESP)
var espOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(espOperand);
var registerOperand = (RegisterOperand)espOperand;
Assert.Equal(RegisterIndex.Sp, registerOperand.Register);
Assert.Equal(32, registerOperand.Size); // Validate that it's a 32-bit register (ESP)
// Check the second operand (memory operand with FS segment override)
var memOperand = instruction.StructuredOperands[1];
Assert.IsType<DirectMemoryOperand>(memOperand);
var memoryOperand = (DirectMemoryOperand)memOperand;
Assert.Equal(32, memoryOperand.Size); // Validate that it's a 32-bit memory reference
Assert.Equal("fs", memoryOperand.SegmentOverride);
}
/// <summary>
@ -178,11 +174,18 @@ public class SegmentOverrideTests
// Act
var instructions = disassembler.Disassemble();
// Debug output
Console.WriteLine($"Number of instructions: {instructions.Count}");
for (int i = 0; i < instructions.Count; i++)
{
Console.WriteLine($"Instruction {i}: Type={instructions[i].Type}, Address={instructions[i].Address:X}");
}
// Assert
Assert.Single(instructions);
var instruction = instructions[0];
Assert.NotNull(instruction);
Assert.Equal(InstructionType.Move, instruction.Type);
Assert.Equal(InstructionType.Mov, instruction.Type);
// Check that we have two operands
Assert.Equal(2, instruction.StructuredOperands.Count);
@ -199,7 +202,6 @@ public class SegmentOverrideTests
Assert.IsType<DirectMemoryOperand>(memOperand);
var memoryOperand = (DirectMemoryOperand)memOperand;
Assert.Equal(32, memoryOperand.Size); // Validate that it's a 32-bit memory reference
Assert.Equal(0, memoryOperand.Address);
Assert.Equal("gs", memoryOperand.SegmentOverride);
}
@ -221,7 +223,7 @@ public class SegmentOverrideTests
Assert.Single(instructions);
var instruction = instructions[0];
Assert.NotNull(instruction);
Assert.Equal(InstructionType.Move, instruction.Type);
Assert.Equal(InstructionType.Mov, instruction.Type);
// Check that we have two operands
Assert.Equal(2, instruction.StructuredOperands.Count);
@ -282,7 +284,7 @@ public class SegmentOverrideTests
Assert.Single(instructions);
var instruction = instructions[0];
Assert.NotNull(instruction);
Assert.Equal(InstructionType.Move, instruction.Type);
Assert.Equal(InstructionType.Mov, instruction.Type);
// Check that we have two operands
Assert.Equal(2, instruction.StructuredOperands.Count);
@ -338,10 +340,10 @@ public class SegmentOverrideTests
// Check the second operand (memory operand with ES segment override)
var memOperand = instruction.StructuredOperands[1];
Assert.IsType<DirectMemoryOperand>(memOperand);
var memoryOperand = (DirectMemoryOperand)memOperand;
Assert.IsType<BaseRegisterMemoryOperand>(memOperand);
var memoryOperand = (BaseRegisterMemoryOperand)memOperand;
Assert.Equal(32, memoryOperand.Size); // Validate that it's a 32-bit memory reference
Assert.Equal(0, memoryOperand.Address);
Assert.Equal(RegisterIndex.Si, memoryOperand.BaseRegister);
Assert.Equal("es", memoryOperand.SegmentOverride);
}

View File

@ -64,7 +64,7 @@ public class StringInstructionHandlerTests
Assert.Single(instructions);
var instruction = instructions[0];
Assert.NotNull(instruction);
Assert.Equal(InstructionType.RepNE, instruction.Type);
Assert.Equal(InstructionType.RepneScasD, instruction.Type);
// Check that we have two operands
Assert.Equal(2, instruction.StructuredOperands.Count);

View File

@ -117,7 +117,7 @@ public class SubInstructionTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x42, immediateOperand.Value);
Assert.Equal(0x42U, immediateOperand.Value);
}
/// <summary>
@ -192,7 +192,7 @@ public class SubInstructionTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x42, immediateOperand.Value);
Assert.Equal(0x42U, immediateOperand.Value);
}
/// <summary>
@ -231,7 +231,7 @@ public class SubInstructionTests
var immOperand = instruction.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x10, immediateOperand.Value);
Assert.Equal(0x10U, immediateOperand.Value);
}
/// <summary>
@ -426,7 +426,7 @@ public class SubInstructionTests
var immOperand = instruction1.StructuredOperands[1];
Assert.IsType<ImmediateOperand>(immOperand);
var immediateOperand = (ImmediateOperand)immOperand;
Assert.Equal(0x10, immediateOperand.Value);
Assert.Equal(0x10U, immediateOperand.Value);
// Second instruction: SUB EAX, EBX
var instruction2 = instructions[1];

View File

@ -229,7 +229,7 @@ public class TestInstructionHandlerTests
var ediOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(ediOperand);
var registerOperand = (RegisterOperand)ediOperand;
Assert.Equal(RegisterIndex.D, registerOperand.Register);
Assert.Equal(RegisterIndex.Di, registerOperand.Register);
Assert.Equal(32, registerOperand.Size); // Validate that it's a 32-bit register (EDI)
// Check the second operand (immediate value)