0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-06-20 16:18:37 +03:00

Updated instruction handlers to use Type and StructuredOperands instead of Mnemonic and Operands

This commit is contained in:
bird_egop
2025-04-14 22:08:50 +03:00
parent c516e063e7
commit 685eeda03d
136 changed files with 3694 additions and 2584 deletions

View File

@ -1,5 +1,7 @@
namespace X86Disassembler.X86;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handles decoding of ModR/M bytes in x86 instructions
/// </summary>
@ -20,40 +22,28 @@ public class ModRMDecoder
private static readonly string[] RegisterNames16 = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"};
private static readonly string[] RegisterNames32 = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
// Buffer containing the code to decode
private readonly byte[] _codeBuffer;
// The instruction decoder that owns this ModRM decoder
private readonly InstructionDecoder _decoder;
// Length of the buffer
private readonly int _length;
/// <summary>
/// Initializes a new instance of the ModRMDecoder class
/// </summary>
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this ModRM decoder</param>
/// <param name="length">The length of the buffer</param>
public ModRMDecoder(byte[] codeBuffer, InstructionDecoder decoder, int length)
public ModRMDecoder(InstructionDecoder decoder)
{
_codeBuffer = codeBuffer;
_decoder = decoder;
_length = length;
}
/// <summary>
/// Decodes a ModR/M byte to get the operand string
/// Decodes a ModR/M byte to get the operand
/// </summary>
/// <param name="mod">The mod field (2 bits)</param>
/// <param name="rmIndex">The r/m field as RegisterIndex</param>
/// <param name="is64Bit">True if the operand is 64-bit</param>
/// <returns>The operand string</returns>
public string DecodeModRM(byte mod, RegisterIndex rmIndex, bool is64Bit)
/// <returns>The operand object</returns>
public Operand DecodeModRM(byte mod, RegisterIndex rmIndex, bool is64Bit)
{
string sizePrefix = is64Bit
? "qword"
: "dword";
int operandSize = is64Bit ? 64 : 32;
switch (mod)
{
@ -64,10 +54,11 @@ public class ModRMDecoder
if (_decoder.CanReadUInt())
{
uint disp32 = _decoder.ReadUInt32();
return $"{sizePrefix} ptr [0x{disp32:X8}]";
return OperandFactory.CreateDirectMemoryOperand(disp32, operandSize);
}
return $"{sizePrefix} ptr [???]";
// Fallback for incomplete data
return OperandFactory.CreateDirectMemoryOperand(0, operandSize);
}
// Special case: [ESP] is encoded with SIB byte
@ -80,11 +71,12 @@ public class ModRMDecoder
return DecodeSIB(sib, 0, is64Bit);
}
return $"{sizePrefix} ptr [???]";
// Fallback for incomplete data
return OperandFactory.CreateBaseRegisterMemoryOperand(RegisterIndex.Si, operandSize);
}
// Regular case: [reg]
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
return OperandFactory.CreateBaseRegisterMemoryOperand(rmIndex, operandSize);
case 1: // [reg + disp8]
if (rmIndex == RegisterIndex.Si) // SIB + disp8 (was ESP/SP)
@ -93,31 +85,30 @@ public class ModRMDecoder
if (_decoder.CanReadByte())
{
byte sib = _decoder.ReadByte();
uint disp8 = (uint) (sbyte) _decoder.ReadByte();
return DecodeSIB(sib, disp8, is64Bit);
sbyte disp8 = (sbyte)(_decoder.CanReadByte() ? _decoder.ReadByte() : 0);
return DecodeSIB(sib, (uint)disp8, is64Bit);
}
return $"{sizePrefix} ptr [???]";
// Fallback for incomplete data
return OperandFactory.CreateBaseRegisterMemoryOperand(RegisterIndex.Si, operandSize);
}
else
{
if (_decoder.CanReadByte())
{
sbyte disp8 = (sbyte) _decoder.ReadByte();
sbyte disp8 = (sbyte)_decoder.ReadByte();
// Only show displacement if it's not zero
if (disp8 == 0)
{
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
return OperandFactory.CreateBaseRegisterMemoryOperand(rmIndex, operandSize);
}
string dispStr8 = disp8 < 0
? $"-0x{-disp8:X2}"
: $"+0x{disp8:X2}";
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}{dispStr8}]";
return OperandFactory.CreateDisplacementMemoryOperand(rmIndex, disp8, operandSize);
}
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+???]";
// Fallback for incomplete data
return OperandFactory.CreateBaseRegisterMemoryOperand(rmIndex, operandSize);
}
case 2: // [reg + disp32]
@ -131,7 +122,8 @@ public class ModRMDecoder
return DecodeSIB(sib, disp32, is64Bit);
}
return $"{sizePrefix} ptr [???]";
// Fallback for incomplete data
return OperandFactory.CreateBaseRegisterMemoryOperand(RegisterIndex.Si, operandSize);
}
else
{
@ -142,22 +134,22 @@ public class ModRMDecoder
// Only show displacement if it's not zero
if (disp32 == 0)
{
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
return OperandFactory.CreateBaseRegisterMemoryOperand(rmIndex, operandSize);
}
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+0x{disp32:X8}]";
return OperandFactory.CreateDisplacementMemoryOperand(rmIndex, (int)disp32, operandSize);
}
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+???]";
// Fallback for incomplete data
return OperandFactory.CreateBaseRegisterMemoryOperand(rmIndex, operandSize);
}
case 3: // reg (direct register access)
return is64Bit
? $"mm{(int) rmIndex}"
: GetRegisterName(rmIndex, 32);
return OperandFactory.CreateRegisterOperand(rmIndex, operandSize);
default:
return "???";
// Fallback for invalid mod value
return OperandFactory.CreateRegisterOperand(RegisterIndex.A, operandSize);
}
}
@ -165,22 +157,22 @@ public class ModRMDecoder
/// Reads and decodes a ModR/M byte
/// </summary>
/// <param name="is64Bit">True if the operand is 64-bit</param>
/// <returns>A tuple containing the mod, reg, rm fields and the decoded operand string</returns>
public (byte mod, RegisterIndex reg, RegisterIndex rm, string operand) ReadModRM(bool is64Bit = false)
/// <returns>A tuple containing the mod, reg, rm fields and the decoded operand</returns>
public (byte mod, RegisterIndex reg, RegisterIndex rm, Operand operand) ReadModRM(bool is64Bit = false)
{
if (!_decoder.CanReadByte())
{
return (0, RegisterIndex.A, RegisterIndex.A, "???");
return (0, RegisterIndex.A, RegisterIndex.A, OperandFactory.CreateRegisterOperand(RegisterIndex.A, is64Bit ? 64 : 32));
}
byte modRM = _decoder.ReadByte();
// Extract fields from ModR/M byte
byte mod = (byte) ((modRM & MOD_MASK) >> 6);
RegisterIndex reg = (RegisterIndex) ((modRM & REG_MASK) >> 3);
RegisterIndex rm = (RegisterIndex) (modRM & RM_MASK);
byte mod = (byte)((modRM & MOD_MASK) >> 6);
RegisterIndex reg = (RegisterIndex)((modRM & REG_MASK) >> 3);
RegisterIndex rm = (RegisterIndex)(modRM & RM_MASK);
string operand = DecodeModRM(mod, rm, is64Bit);
Operand operand = DecodeModRM(mod, rm, is64Bit);
return (mod, reg, rm, operand);
}
@ -191,17 +183,15 @@ public class ModRMDecoder
/// <param name="sib">The SIB byte</param>
/// <param name="displacement">The displacement value</param>
/// <param name="is64Bit">True if the operand is 64-bit</param>
/// <returns>The decoded SIB string</returns>
private string DecodeSIB(byte sib, uint displacement, bool is64Bit)
/// <returns>The decoded SIB operand</returns>
private Operand DecodeSIB(byte sib, uint displacement, bool is64Bit)
{
string sizePrefix = is64Bit
? "qword"
: "dword";
int operandSize = is64Bit ? 64 : 32;
// Extract fields from SIB byte
byte scale = (byte) ((sib & SIB_SCALE_MASK) >> 6);
RegisterIndex index = (RegisterIndex) ((sib & SIB_INDEX_MASK) >> 3);
RegisterIndex @base = (RegisterIndex) (sib & SIB_BASE_MASK);
byte scale = (byte)((sib & SIB_SCALE_MASK) >> 6);
RegisterIndex index = (RegisterIndex)((sib & SIB_INDEX_MASK) >> 3);
RegisterIndex @base = (RegisterIndex)(sib & SIB_BASE_MASK);
// Special case: ESP/SP (4) in index field means no index register
if (index == RegisterIndex.Si)
@ -212,37 +202,32 @@ public class ModRMDecoder
if (_decoder.CanReadUInt())
{
uint disp32 = _decoder.ReadUInt32();
return $"{sizePrefix} ptr [0x{disp32:X8}]";
return OperandFactory.CreateDirectMemoryOperand(disp32, operandSize);
}
return $"{sizePrefix} ptr [???]";
// Fallback for incomplete data
return OperandFactory.CreateDirectMemoryOperand(0, operandSize);
}
// Base register only
// Only show displacement if it's not zero
// Base register only with displacement
if (displacement == 0)
{
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}]";
return OperandFactory.CreateBaseRegisterMemoryOperand(@base, operandSize);
}
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+0x{displacement:X}]";
return OperandFactory.CreateDisplacementMemoryOperand(@base, (int)displacement, operandSize);
}
// Normal case with base and index registers
int scaleFactor = 1 << scale; // 1, 2, 4, or 8
// Only include the scale factor if it's not 1
string scaleStr = scaleFactor > 1
? $"*{scaleFactor}"
: "";
// Only show displacement if it's not zero
if (displacement == 0)
{
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+{GetRegisterName(index, 32)}{scaleStr}]";
}
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+{GetRegisterName(index, 32)}{scaleStr}+0x{displacement:X}]";
// Create a scaled index memory operand
return OperandFactory.CreateScaledIndexMemoryOperand(
index,
scaleFactor,
@base,
(int)displacement,
operandSize);
}
/// <summary>
@ -254,7 +239,7 @@ public class ModRMDecoder
public static string GetRegisterName(RegisterIndex regIndex, int size)
{
// Convert RegisterIndex to raw index for array access
int index = (int) regIndex;
int index = (int)regIndex;
return size switch
{