mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2025-05-21 21:01:17 +03:00
remove direct position changes from modrmdecoder
This commit is contained in:
parent
99b93523a4
commit
c9e854a663
@ -16,9 +16,9 @@ public class ModRMDecoder
|
|||||||
private const byte SIB_BASE_MASK = 0x07; // 00000111b
|
private const byte SIB_BASE_MASK = 0x07; // 00000111b
|
||||||
|
|
||||||
// Register names for different sizes
|
// Register names for different sizes
|
||||||
private static readonly string[] RegisterNames8 = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
|
private static readonly string[] RegisterNames8 = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
|
||||||
private static readonly string[] RegisterNames16 = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
|
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" };
|
private static readonly string[] RegisterNames32 = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
|
||||||
|
|
||||||
// Buffer containing the code to decode
|
// Buffer containing the code to decode
|
||||||
private readonly byte[] _codeBuffer;
|
private readonly byte[] _codeBuffer;
|
||||||
@ -51,8 +51,9 @@ public class ModRMDecoder
|
|||||||
/// <returns>The operand string</returns>
|
/// <returns>The operand string</returns>
|
||||||
public string DecodeModRM(byte mod, RegisterIndex rmIndex, bool is64Bit)
|
public string DecodeModRM(byte mod, RegisterIndex rmIndex, bool is64Bit)
|
||||||
{
|
{
|
||||||
string sizePrefix = is64Bit ? "qword" : "dword";
|
string sizePrefix = is64Bit
|
||||||
int position = _decoder.GetPosition();
|
? "qword"
|
||||||
|
: "dword";
|
||||||
|
|
||||||
switch (mod)
|
switch (mod)
|
||||||
{
|
{
|
||||||
@ -60,51 +61,49 @@ public class ModRMDecoder
|
|||||||
// Special case: [EBP] is encoded as disp32 with no base register
|
// Special case: [EBP] is encoded as disp32 with no base register
|
||||||
if (rmIndex == RegisterIndex.Di) // disp32 (was EBP/BP)
|
if (rmIndex == RegisterIndex.Di) // disp32 (was EBP/BP)
|
||||||
{
|
{
|
||||||
if (position + 4 <= _length)
|
if (_decoder.CanReadUInt())
|
||||||
{
|
{
|
||||||
uint disp32 = BitConverter.ToUInt32(_codeBuffer, position);
|
uint disp32 = _decoder.ReadUInt32();
|
||||||
_decoder.SetPosition(position + 4);
|
|
||||||
return $"{sizePrefix} ptr [0x{disp32:X8}]";
|
return $"{sizePrefix} ptr [0x{disp32:X8}]";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"{sizePrefix} ptr [???]";
|
return $"{sizePrefix} ptr [???]";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case: [ESP] is encoded with SIB byte
|
// Special case: [ESP] is encoded with SIB byte
|
||||||
else if (rmIndex == RegisterIndex.Si) // SIB (was ESP/SP)
|
if (rmIndex == RegisterIndex.Si) // SIB (was ESP/SP)
|
||||||
{
|
{
|
||||||
// Handle SIB byte
|
// Handle SIB byte
|
||||||
if (position < _length)
|
if (_decoder.CanReadByte())
|
||||||
{
|
{
|
||||||
byte sib = _codeBuffer[position];
|
byte sib = _decoder.ReadByte();
|
||||||
_decoder.SetPosition(position + 1);
|
|
||||||
return DecodeSIB(sib, 0, is64Bit);
|
return DecodeSIB(sib, 0, is64Bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"{sizePrefix} ptr [???]";
|
return $"{sizePrefix} ptr [???]";
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Regular case: [reg]
|
// Regular case: [reg]
|
||||||
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
|
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
|
||||||
}
|
|
||||||
|
|
||||||
case 1: // [reg + disp8]
|
case 1: // [reg + disp8]
|
||||||
if (rmIndex == RegisterIndex.Si) // SIB + disp8 (was ESP/SP)
|
if (rmIndex == RegisterIndex.Si) // SIB + disp8 (was ESP/SP)
|
||||||
{
|
{
|
||||||
// Handle SIB byte
|
// Handle SIB byte
|
||||||
if (position + 1 < _length)
|
if (_decoder.CanReadByte())
|
||||||
{
|
{
|
||||||
byte sib = _codeBuffer[position];
|
byte sib = _decoder.ReadByte();
|
||||||
sbyte disp8 = (sbyte)_codeBuffer[position + 1];
|
uint disp8 = (uint) (sbyte) _decoder.ReadByte();
|
||||||
_decoder.SetPosition(position + 2);
|
|
||||||
return DecodeSIB(sib, disp8, is64Bit);
|
return DecodeSIB(sib, disp8, is64Bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"{sizePrefix} ptr [???]";
|
return $"{sizePrefix} ptr [???]";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (position < _length)
|
if (_decoder.CanReadByte())
|
||||||
{
|
{
|
||||||
sbyte disp8 = (sbyte)_codeBuffer[position];
|
sbyte disp8 = (sbyte) _decoder.ReadByte();
|
||||||
_decoder.SetPosition(position + 1);
|
|
||||||
|
|
||||||
// Only show displacement if it's not zero
|
// Only show displacement if it's not zero
|
||||||
if (disp8 == 0)
|
if (disp8 == 0)
|
||||||
@ -112,9 +111,12 @@ public class ModRMDecoder
|
|||||||
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
|
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
|
||||||
}
|
}
|
||||||
|
|
||||||
string dispStr8 = disp8 < 0 ? $"-0x{-disp8:X2}" : $"+0x{disp8:X2}";
|
string dispStr8 = disp8 < 0
|
||||||
|
? $"-0x{-disp8:X2}"
|
||||||
|
: $"+0x{disp8:X2}";
|
||||||
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}{dispStr8}]";
|
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}{dispStr8}]";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+???]";
|
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+???]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,21 +124,20 @@ public class ModRMDecoder
|
|||||||
if (rmIndex == RegisterIndex.Si) // SIB + disp32 (was ESP/SP)
|
if (rmIndex == RegisterIndex.Si) // SIB + disp32 (was ESP/SP)
|
||||||
{
|
{
|
||||||
// Handle SIB byte
|
// Handle SIB byte
|
||||||
if (position + 4 < _length)
|
if (_decoder.CanReadUInt())
|
||||||
{
|
{
|
||||||
byte sib = _codeBuffer[position];
|
byte sib = _decoder.ReadByte();
|
||||||
int disp32 = BitConverter.ToInt32(_codeBuffer, position + 1);
|
uint disp32 = _decoder.ReadUInt32();
|
||||||
_decoder.SetPosition(position + 5);
|
|
||||||
return DecodeSIB(sib, disp32, is64Bit);
|
return DecodeSIB(sib, disp32, is64Bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"{sizePrefix} ptr [???]";
|
return $"{sizePrefix} ptr [???]";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (position + 4 <= _length)
|
if (_decoder.CanReadUInt())
|
||||||
{
|
{
|
||||||
int disp32 = BitConverter.ToInt32(_codeBuffer, position);
|
uint disp32 = _decoder.ReadUInt32();
|
||||||
_decoder.SetPosition(position + 4);
|
|
||||||
|
|
||||||
// Only show displacement if it's not zero
|
// Only show displacement if it's not zero
|
||||||
if (disp32 == 0)
|
if (disp32 == 0)
|
||||||
@ -144,14 +145,16 @@ public class ModRMDecoder
|
|||||||
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
|
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
|
||||||
}
|
}
|
||||||
|
|
||||||
string dispStr32 = disp32 < 0 ? $"-0x{-disp32:X8}" : $"+0x{disp32:X8}";
|
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+0x{disp32:X8}]";
|
||||||
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}{dispStr32}]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+???]";
|
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+???]";
|
||||||
}
|
}
|
||||||
|
|
||||||
case 3: // reg (direct register access)
|
case 3: // reg (direct register access)
|
||||||
return is64Bit ? $"mm{(int)rmIndex}" : GetRegisterName(rmIndex, 32);
|
return is64Bit
|
||||||
|
? $"mm{(int) rmIndex}"
|
||||||
|
: GetRegisterName(rmIndex, 32);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "???";
|
return "???";
|
||||||
@ -165,20 +168,17 @@ public class ModRMDecoder
|
|||||||
/// <returns>A tuple containing the mod, reg, rm fields and the decoded operand string</returns>
|
/// <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)
|
public (byte mod, RegisterIndex reg, RegisterIndex rm, string operand) ReadModRM(bool is64Bit = false)
|
||||||
{
|
{
|
||||||
int position = _decoder.GetPosition();
|
if (!_decoder.CanReadByte())
|
||||||
|
|
||||||
if (position >= _length)
|
|
||||||
{
|
{
|
||||||
return (0, RegisterIndex.A, RegisterIndex.A, "???");
|
return (0, RegisterIndex.A, RegisterIndex.A, "???");
|
||||||
}
|
}
|
||||||
|
|
||||||
byte modRM = _codeBuffer[position];
|
byte modRM = _decoder.ReadByte();
|
||||||
_decoder.SetPosition(position + 1);
|
|
||||||
|
|
||||||
// Extract fields from ModR/M byte
|
// Extract fields from ModR/M byte
|
||||||
byte mod = (byte)((modRM & MOD_MASK) >> 6);
|
byte mod = (byte) ((modRM & MOD_MASK) >> 6);
|
||||||
RegisterIndex reg = (RegisterIndex)((modRM & REG_MASK) >> 3);
|
RegisterIndex reg = (RegisterIndex) ((modRM & REG_MASK) >> 3);
|
||||||
RegisterIndex rm = (RegisterIndex)(modRM & RM_MASK);
|
RegisterIndex rm = (RegisterIndex) (modRM & RM_MASK);
|
||||||
|
|
||||||
string operand = DecodeModRM(mod, rm, is64Bit);
|
string operand = DecodeModRM(mod, rm, is64Bit);
|
||||||
|
|
||||||
@ -192,15 +192,16 @@ public class ModRMDecoder
|
|||||||
/// <param name="displacement">The displacement value</param>
|
/// <param name="displacement">The displacement value</param>
|
||||||
/// <param name="is64Bit">True if the operand is 64-bit</param>
|
/// <param name="is64Bit">True if the operand is 64-bit</param>
|
||||||
/// <returns>The decoded SIB string</returns>
|
/// <returns>The decoded SIB string</returns>
|
||||||
private string DecodeSIB(byte sib, int displacement, bool is64Bit)
|
private string DecodeSIB(byte sib, uint displacement, bool is64Bit)
|
||||||
{
|
{
|
||||||
string sizePrefix = is64Bit ? "qword" : "dword";
|
string sizePrefix = is64Bit
|
||||||
int position = _decoder.GetPosition();
|
? "qword"
|
||||||
|
: "dword";
|
||||||
|
|
||||||
// Extract fields from SIB byte
|
// Extract fields from SIB byte
|
||||||
byte scale = (byte)((sib & SIB_SCALE_MASK) >> 6);
|
byte scale = (byte) ((sib & SIB_SCALE_MASK) >> 6);
|
||||||
RegisterIndex index = (RegisterIndex)((sib & SIB_INDEX_MASK) >> 3);
|
RegisterIndex index = (RegisterIndex) ((sib & SIB_INDEX_MASK) >> 3);
|
||||||
RegisterIndex @base = (RegisterIndex)(sib & SIB_BASE_MASK);
|
RegisterIndex @base = (RegisterIndex) (sib & SIB_BASE_MASK);
|
||||||
|
|
||||||
// Special case: ESP/SP (4) in index field means no index register
|
// Special case: ESP/SP (4) in index field means no index register
|
||||||
if (index == RegisterIndex.Si)
|
if (index == RegisterIndex.Si)
|
||||||
@ -208,16 +209,15 @@ public class ModRMDecoder
|
|||||||
// Special case: EBP/BP (5) in base field with no displacement means disp32 only
|
// Special case: EBP/BP (5) in base field with no displacement means disp32 only
|
||||||
if (@base == RegisterIndex.Di && displacement == 0)
|
if (@base == RegisterIndex.Di && displacement == 0)
|
||||||
{
|
{
|
||||||
if (position + 4 <= _length)
|
if (_decoder.CanReadUInt())
|
||||||
{
|
{
|
||||||
uint disp32 = BitConverter.ToUInt32(_codeBuffer, position);
|
uint disp32 = _decoder.ReadUInt32();
|
||||||
_decoder.SetPosition(position + 4);
|
|
||||||
return $"{sizePrefix} ptr [0x{disp32:X8}]";
|
return $"{sizePrefix} ptr [0x{disp32:X8}]";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"{sizePrefix} ptr [???]";
|
return $"{sizePrefix} ptr [???]";
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Base register only
|
// Base register only
|
||||||
// Only show displacement if it's not zero
|
// Only show displacement if it's not zero
|
||||||
if (displacement == 0)
|
if (displacement == 0)
|
||||||
@ -225,18 +225,16 @@ public class ModRMDecoder
|
|||||||
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}]";
|
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}]";
|
||||||
}
|
}
|
||||||
|
|
||||||
string baseDispStr = displacement < 0 ?
|
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+0x{displacement:X}]";
|
||||||
$"-0x{-displacement:X}" :
|
|
||||||
$"+0x{displacement:X}";
|
|
||||||
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}{baseDispStr}]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal case with base and index registers
|
// Normal case with base and index registers
|
||||||
int scaleFactor = 1 << scale; // 1, 2, 4, or 8
|
int scaleFactor = 1 << scale; // 1, 2, 4, or 8
|
||||||
|
|
||||||
// Only include the scale factor if it's not 1
|
// Only include the scale factor if it's not 1
|
||||||
string scaleStr = scaleFactor > 1 ? $"*{scaleFactor}" : "";
|
string scaleStr = scaleFactor > 1
|
||||||
|
? $"*{scaleFactor}"
|
||||||
|
: "";
|
||||||
|
|
||||||
// Only show displacement if it's not zero
|
// Only show displacement if it's not zero
|
||||||
if (displacement == 0)
|
if (displacement == 0)
|
||||||
@ -244,11 +242,7 @@ public class ModRMDecoder
|
|||||||
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+{GetRegisterName(index, 32)}{scaleStr}]";
|
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+{GetRegisterName(index, 32)}{scaleStr}]";
|
||||||
}
|
}
|
||||||
|
|
||||||
string indexDispStr = displacement < 0 ?
|
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+{GetRegisterName(index, 32)}{scaleStr}+0x{displacement:X}]";
|
||||||
$"-0x{-displacement:X}" :
|
|
||||||
$"+0x{displacement:X}";
|
|
||||||
|
|
||||||
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+{GetRegisterName(index, 32)}{scaleStr}{indexDispStr}]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -260,7 +254,7 @@ public class ModRMDecoder
|
|||||||
public static string GetRegisterName(RegisterIndex regIndex, int size)
|
public static string GetRegisterName(RegisterIndex regIndex, int size)
|
||||||
{
|
{
|
||||||
// Convert RegisterIndex to raw index for array access
|
// Convert RegisterIndex to raw index for array access
|
||||||
int index = (int)regIndex;
|
int index = (int) regIndex;
|
||||||
|
|
||||||
return size switch
|
return size switch
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user