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

Added proper REPNE prefix handling and comprehensive string instruction tests

This commit is contained in:
bird_egop 2025-04-13 02:26:49 +03:00
parent 79bf419c07
commit d0667950f8
2 changed files with 128 additions and 8 deletions

View File

@ -11,6 +11,7 @@ public class PrefixDecoder
private bool _segmentOverridePrefix; private bool _segmentOverridePrefix;
private bool _lockPrefix; private bool _lockPrefix;
private bool _repPrefix; private bool _repPrefix;
private bool _repnePrefix;
private string _segmentOverride = string.Empty; private string _segmentOverride = string.Empty;
/// <summary> /// <summary>
@ -31,6 +32,7 @@ public class PrefixDecoder
_segmentOverridePrefix = false; _segmentOverridePrefix = false;
_lockPrefix = false; _lockPrefix = false;
_repPrefix = false; _repPrefix = false;
_repnePrefix = false;
_segmentOverride = string.Empty; _segmentOverride = string.Empty;
} }
@ -70,11 +72,16 @@ public class PrefixDecoder
_lockPrefix = true; _lockPrefix = true;
return true; return true;
} }
else if (prefix == 0xF2 || prefix == 0xF3) // REP/REPNE prefix else if (prefix == 0xF3) // REP prefix
{ {
_repPrefix = true; _repPrefix = true;
return true; return true;
} }
else if (prefix == 0xF2) // REPNE prefix
{
_repnePrefix = true;
return true;
}
return false; return false;
} }
@ -125,14 +132,23 @@ public class PrefixDecoder
} }
/// <summary> /// <summary>
/// Checks if the REP/REPNE prefix is present /// Checks if the REP prefix is present
/// </summary> /// </summary>
/// <returns>True if the REP/REPNE prefix is present</returns> /// <returns>True if the REP prefix is present</returns>
public bool HasRepPrefix() public bool HasRepPrefix()
{ {
return _repPrefix; return _repPrefix;
} }
/// <summary>
/// Checks if the REPNE prefix is present
/// </summary>
/// <returns>True if the REPNE prefix is present</returns>
public bool HasRepnePrefix()
{
return _repnePrefix;
}
/// <summary> /// <summary>
/// Applies the segment override prefix to the operands string if applicable /// Applies the segment override prefix to the operands string if applicable
/// </summary> /// </summary>
@ -154,13 +170,17 @@ public class PrefixDecoder
} }
/// <summary> /// <summary>
/// Applies the REP prefix to the mnemonic if applicable /// Applies the REP/REPNE prefix to the mnemonic if applicable
/// </summary> /// </summary>
/// <param name="mnemonic">The mnemonic</param> /// <param name="mnemonic">The mnemonic</param>
/// <returns>The mnemonic with REP prefix applied</returns> /// <returns>The mnemonic with REP/REPNE prefix applied</returns>
public string ApplyRepPrefix(string mnemonic) public string ApplyRepPrefix(string mnemonic)
{ {
if (_repPrefix && !mnemonic.StartsWith("rep")) if (_repnePrefix && !mnemonic.StartsWith("repne"))
{
return $"repne {mnemonic}";
}
else if (_repPrefix && !mnemonic.StartsWith("rep"))
{ {
return $"rep {mnemonic}"; return $"rep {mnemonic}";
} }

View File

@ -11,10 +11,10 @@ using X86Disassembler.X86.Handlers.String;
public class StringInstructionHandlerTests public class StringInstructionHandlerTests
{ {
/// <summary> /// <summary>
/// Tests the RepMovsHandler for decoding REP MOVS instruction /// Tests the StringInstructionHandler for decoding REP MOVS instruction
/// </summary> /// </summary>
[Fact] [Fact]
public void RepMovsHandler_DecodesRepMovs_Correctly() public void StringInstructionHandler_DecodesRepMovs_Correctly()
{ {
// Arrange // Arrange
// REP MOVS (F3 A5) // REP MOVS (F3 A5)
@ -29,4 +29,104 @@ public class StringInstructionHandlerTests
Assert.Equal("rep movs", instruction.Mnemonic); Assert.Equal("rep movs", instruction.Mnemonic);
Assert.Equal("dword ptr [edi], dword ptr [esi]", instruction.Operands); Assert.Equal("dword ptr [edi], dword ptr [esi]", instruction.Operands);
} }
/// <summary>
/// Tests the StringInstructionHandler for decoding REPNE SCAS instruction
/// </summary>
[Fact]
public void StringInstructionHandler_DecodesRepneScas_Correctly()
{
// Arrange
// REPNE SCAS (F2 AF)
byte[] codeBuffer = new byte[] { 0xF2, 0xAF };
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
// Act
var instruction = decoder.DecodeInstruction();
// Assert
Assert.NotNull(instruction);
Assert.Equal("repne scas", instruction.Mnemonic);
Assert.Equal("eax, dword ptr [edi]", instruction.Operands);
}
/// <summary>
/// Tests the StringInstructionHandler for decoding MOVS instruction without prefix
/// </summary>
[Fact]
public void StringInstructionHandler_DecodesMovs_Correctly()
{
// Arrange
// MOVS (A5)
byte[] codeBuffer = new byte[] { 0xA5 };
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
// Act
var instruction = decoder.DecodeInstruction();
// Assert
Assert.NotNull(instruction);
Assert.Equal("movs", instruction.Mnemonic);
Assert.Equal("dword ptr [edi], dword ptr [esi]", instruction.Operands);
}
/// <summary>
/// Tests the StringInstructionHandler for decoding STOS instruction without prefix
/// </summary>
[Fact]
public void StringInstructionHandler_DecodesStosb_Correctly()
{
// Arrange
// STOSB (AA)
byte[] codeBuffer = new byte[] { 0xAA };
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
// Act
var instruction = decoder.DecodeInstruction();
// Assert
Assert.NotNull(instruction);
Assert.Equal("stos", instruction.Mnemonic);
Assert.Equal("byte ptr [edi], al", instruction.Operands);
}
/// <summary>
/// Tests the StringInstructionHandler for decoding LODS instruction without prefix
/// </summary>
[Fact]
public void StringInstructionHandler_DecodesLodsd_Correctly()
{
// Arrange
// LODSD (AD)
byte[] codeBuffer = new byte[] { 0xAD };
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
// Act
var instruction = decoder.DecodeInstruction();
// Assert
Assert.NotNull(instruction);
Assert.Equal("lods", instruction.Mnemonic);
Assert.Equal("eax, dword ptr [esi]", instruction.Operands);
}
/// <summary>
/// Tests the StringInstructionHandler for decoding SCAS instruction without prefix
/// </summary>
[Fact]
public void StringInstructionHandler_DecodesScasb_Correctly()
{
// Arrange
// SCASB (AE)
byte[] codeBuffer = new byte[] { 0xAE };
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
// Act
var instruction = decoder.DecodeInstruction();
// Assert
Assert.NotNull(instruction);
Assert.Equal("scas", instruction.Mnemonic);
Assert.Equal("al, byte ptr [edi]", instruction.Operands);
}
} }