From 2d0f701dd1f264d62ccfa23c00f43fafa0894da7 Mon Sep 17 00:00:00 2001 From: bird_egop Date: Mon, 14 Apr 2025 00:17:31 +0300 Subject: [PATCH] Simplified TwoByteConditionalJumpHandler and MovRegMemHandler by improving boundary checking and target address calculation --- .../Jump/TwoByteConditionalJumpHandler.cs | 36 ++++++++++--------- .../X86/Handlers/Mov/MovRegMemHandler.cs | 34 +++--------------- 2 files changed, 25 insertions(+), 45 deletions(-) diff --git a/X86Disassembler/X86/Handlers/Jump/TwoByteConditionalJumpHandler.cs b/X86Disassembler/X86/Handlers/Jump/TwoByteConditionalJumpHandler.cs index 76d5b0d..8759b88 100644 --- a/X86Disassembler/X86/Handlers/Jump/TwoByteConditionalJumpHandler.cs +++ b/X86Disassembler/X86/Handlers/Jump/TwoByteConditionalJumpHandler.cs @@ -31,18 +31,20 @@ public class TwoByteConditionalJumpHandler : InstructionHandler public override bool CanHandle(byte opcode) { // Two-byte conditional jumps start with 0x0F - if (opcode == 0x0F) + if (opcode != 0x0F) { - int position = Decoder.GetPosition(); - if (position < Length) - { - byte secondByte = CodeBuffer[position]; - // Second byte must be in the range 0x80-0x8F - return secondByte >= 0x80 && secondByte <= 0x8F; - } + return false; } - return false; + int position = Decoder.GetPosition(); + if (!Decoder.CanReadByte()) + { + return false; + } + + byte secondByte = CodeBuffer[position]; + // Second byte must be in the range 0x80-0x8F + return secondByte >= 0x80 && secondByte <= 0x8F; } /// @@ -55,20 +57,21 @@ public class TwoByteConditionalJumpHandler : InstructionHandler { int position = Decoder.GetPosition(); - if (position >= Length) - { + // Check if we have enough bytes for the second byte + if (!Decoder.CanReadByte()) + { return false; } // Read the second byte of the opcode - byte secondByte = CodeBuffer[position++]; - Decoder.SetPosition(position); + byte secondByte = Decoder.ReadByte(); // Get the mnemonic from the table int index = secondByte - 0x80; instruction.Mnemonic = ConditionalJumpMnemonics[index]; - if (position + 4 > Length) + // Check if we have enough bytes for the offset + if (!Decoder.CanReadUInt()) { return false; } @@ -77,9 +80,10 @@ public class TwoByteConditionalJumpHandler : InstructionHandler uint offset = Decoder.ReadUInt32(); // Calculate the target address - uint targetAddress = (uint)(position + offset + 4); + // For two-byte conditional jumps, the instruction is 6 bytes: first opcode (1) + second opcode (1) + offset (4) + uint targetAddress = (uint)(instruction.Address + 6 + offset); - // Set the operands + // Format the target address instruction.Operands = $"0x{targetAddress:X8}"; return true; diff --git a/X86Disassembler/X86/Handlers/Mov/MovRegMemHandler.cs b/X86Disassembler/X86/Handlers/Mov/MovRegMemHandler.cs index 4117eb5..63299a4 100644 --- a/X86Disassembler/X86/Handlers/Mov/MovRegMemHandler.cs +++ b/X86Disassembler/X86/Handlers/Mov/MovRegMemHandler.cs @@ -34,52 +34,28 @@ public class MovRegMemHandler : InstructionHandler /// True if the instruction was successfully decoded public override bool Decode(byte opcode, Instruction instruction) { - // Save the original position for raw bytes calculation - int startPosition = Decoder.GetPosition(); - // Set the mnemonic instruction.Mnemonic = "mov"; - if (startPosition >= Length) + // Check if we have enough bytes for the ModR/M byte + if (!Decoder.CanReadByte()) { - instruction.Operands = "??"; - instruction.RawBytes = new byte[] {opcode}; - return true; + return false; } // Determine operand size (0 = 8-bit, 1 = 32-bit) - bool operandSize32 = (opcode & 0x01) != 0; - int operandSize = operandSize32 - ? 32 - : 8; + int operandSize = (opcode & 0x01) != 0 ? 32 : 8; // Use ModRMDecoder to decode the ModR/M byte - var (mod, reg, rm, rmOperand) = ModRMDecoder.ReadModRM(); // false for 32-bit operand + var (mod, reg, rm, rmOperand) = ModRMDecoder.ReadModRM(); // Get register name based on size string regName = ModRMDecoder.GetRegisterName(reg, operandSize); - // Get the position after decoding the ModR/M byte - int newPosition = Decoder.GetPosition(); - // Set the operands - register is the destination, r/m is the source (for 0x8B) // This matches the correct x86 instruction format: MOV r32, r/m32 instruction.Operands = $"{regName}, {rmOperand}"; - // Set the raw bytes - int totalBytes = newPosition - startPosition + 1; // +1 for opcode - byte[] rawBytes = new byte[totalBytes]; - rawBytes[0] = opcode; - for (int i = 0; i < totalBytes - 1; i++) - { - if (startPosition + i < Length) - { - rawBytes[i + 1] = CodeBuffer[startPosition + i]; - } - } - - instruction.RawBytes = rawBytes; - return true; } } \ No newline at end of file