From e134452edab0c0fdcac6e46f77ee323cbffefcb2 Mon Sep 17 00:00:00 2001 From: bird_egop Date: Mon, 14 Apr 2025 00:33:39 +0300 Subject: [PATCH] Improved PUSH handlers by moving reg field check to CanHandle and adding proper boundary checking --- .../X86/Handlers/Push/PushImm32Handler.cs | 13 +++++-- .../X86/Handlers/Push/PushImm8Handler.cs | 5 +++ .../X86/Handlers/Push/PushRm32Handler.cs | 38 ++++++++++++------- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/X86Disassembler/X86/Handlers/Push/PushImm32Handler.cs b/X86Disassembler/X86/Handlers/Push/PushImm32Handler.cs index ebf98b4..26937af 100644 --- a/X86Disassembler/X86/Handlers/Push/PushImm32Handler.cs +++ b/X86Disassembler/X86/Handlers/Push/PushImm32Handler.cs @@ -11,11 +11,11 @@ public class PushImm32Handler : InstructionHandler /// The buffer containing the code to decode /// The instruction decoder that owns this handler /// The length of the buffer - public PushImm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) + public PushImm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length) : base(codeBuffer, decoder, length) { } - + /// /// Checks if this handler can decode the given opcode /// @@ -25,7 +25,7 @@ public class PushImm32Handler : InstructionHandler { return opcode == 0x68; } - + /// /// Decodes a PUSH imm32 instruction /// @@ -37,9 +37,14 @@ public class PushImm32Handler : InstructionHandler // Set the mnemonic instruction.Mnemonic = "push"; + if(!Decoder.CanReadUInt()) + { + return false; + } + // Read the immediate value uint imm32 = Decoder.ReadUInt32(); - + // Set the operands with 8-digit padding to match test expectations instruction.Operands = $"0x{imm32:X8}"; diff --git a/X86Disassembler/X86/Handlers/Push/PushImm8Handler.cs b/X86Disassembler/X86/Handlers/Push/PushImm8Handler.cs index 5057fd1..cfbd679 100644 --- a/X86Disassembler/X86/Handlers/Push/PushImm8Handler.cs +++ b/X86Disassembler/X86/Handlers/Push/PushImm8Handler.cs @@ -37,6 +37,11 @@ public class PushImm8Handler : InstructionHandler // Set the mnemonic instruction.Mnemonic = "push"; + if(!Decoder.CanReadByte()) + { + return false; + } + // Read the immediate value byte imm8 = Decoder.ReadByte(); diff --git a/X86Disassembler/X86/Handlers/Push/PushRm32Handler.cs b/X86Disassembler/X86/Handlers/Push/PushRm32Handler.cs index 70fe020..7e63cbe 100644 --- a/X86Disassembler/X86/Handlers/Push/PushRm32Handler.cs +++ b/X86Disassembler/X86/Handlers/Push/PushRm32Handler.cs @@ -23,7 +23,26 @@ public class PushRm32Handler : InstructionHandler /// True if this handler can decode the opcode public override bool CanHandle(byte opcode) { - return opcode == 0xFF; + // PUSH r/m32 is encoded as FF /6 + if (opcode != 0xFF) + { + return false; + } + + // Check if we have enough bytes to read the ModR/M byte + if (!Decoder.CanReadByte()) + { + return false; + } + + // Peek at the ModR/M byte without advancing the position + byte modRM = CodeBuffer[Decoder.GetPosition()]; + + // Extract the reg field (bits 3-5) + byte reg = (byte)((modRM & 0x38) >> 3); + + // PUSH r/m32 is encoded as FF /6 (reg field = 6) + return reg == 6; } /// @@ -34,9 +53,11 @@ public class PushRm32Handler : InstructionHandler /// True if the instruction was successfully decoded public override bool Decode(byte opcode, Instruction instruction) { - int position = Decoder.GetPosition(); - - if (position >= Length) + // Set the mnemonic + instruction.Mnemonic = "push"; + + // Check if we have enough bytes for the ModR/M byte + if (!Decoder.CanReadByte()) { return false; } @@ -44,15 +65,6 @@ public class PushRm32Handler : InstructionHandler // Read the ModR/M byte var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); - // PUSH r/m32 is encoded as FF /6 - if (reg != RegisterIndex.Sp) - { - return false; - } - - // Set the mnemonic - instruction.Mnemonic = "push"; - // For memory operands, set the operand if (mod != 3) // Memory operand {