mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2025-05-19 03:41:18 +03:00
Implemented SBB instruction handlers for the x86 disassembler
This commit is contained in:
parent
a62812f71c
commit
33dc0b0fa2
@ -100,9 +100,20 @@ public class InstructionHandlerFactory
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void RegisterSbbHandlers()
|
private void RegisterSbbHandlers()
|
||||||
{
|
{
|
||||||
// SBB immediate handlers
|
// SBB immediate handlers for 8-bit operands
|
||||||
|
_handlers.Add(new SbbImmFromRm8Handler(_decoder)); // SBB r/m8, imm8 (opcode 80 /3)
|
||||||
|
_handlers.Add(new SbbAlImmHandler(_decoder)); // SBB AL, imm8 (opcode 1C)
|
||||||
|
|
||||||
|
// SBB immediate handlers for 16-bit operands (with 0x66 prefix)
|
||||||
|
_handlers.Add(new SbbImmFromRm16Handler(_decoder)); // SBB r/m16, imm16 (opcode 81 /3 with 0x66 prefix)
|
||||||
|
_handlers.Add(new SbbImmFromRm16SignExtendedHandler(_decoder)); // SBB r/m16, imm8 (opcode 83 /3 with 0x66 prefix)
|
||||||
|
|
||||||
|
// SBB immediate handlers for 32-bit operands
|
||||||
_handlers.Add(new SbbImmFromRm32Handler(_decoder)); // SBB r/m32, imm32 (opcode 81 /3)
|
_handlers.Add(new SbbImmFromRm32Handler(_decoder)); // SBB r/m32, imm32 (opcode 81 /3)
|
||||||
_handlers.Add(new SbbImmFromRm32SignExtendedHandler(_decoder)); // SBB r/m32, imm8 (opcode 83 /3)
|
_handlers.Add(new SbbImmFromRm32SignExtendedHandler(_decoder)); // SBB r/m32, imm8 (opcode 83 /3)
|
||||||
|
|
||||||
|
// SBB accumulator handlers
|
||||||
|
_handlers.Add(new SbbAccumulatorImmHandler(_decoder)); // SBB AX/EAX, imm16/32 (opcode 1D)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -140,6 +151,15 @@ public class InstructionHandlerFactory
|
|||||||
// Add Return handlers
|
// Add Return handlers
|
||||||
_handlers.Add(new RetHandler(_decoder));
|
_handlers.Add(new RetHandler(_decoder));
|
||||||
_handlers.Add(new RetImmHandler(_decoder));
|
_handlers.Add(new RetImmHandler(_decoder));
|
||||||
|
|
||||||
|
// Add Far Return handlers
|
||||||
|
// 16-bit handlers with operand size prefix (must come first)
|
||||||
|
_handlers.Add(new Retf16Handler(_decoder)); // RETF (16-bit) (opcode 0xCB with 0x66 prefix)
|
||||||
|
_handlers.Add(new RetfImm16Handler(_decoder)); // RETF imm16 (16-bit) (opcode 0xCA with 0x66 prefix)
|
||||||
|
|
||||||
|
// 32-bit handlers (default)
|
||||||
|
_handlers.Add(new RetfHandler(_decoder)); // RETF (32-bit) (opcode 0xCB)
|
||||||
|
_handlers.Add(new RetfImmHandler(_decoder)); // RETF imm16 (32-bit) (opcode 0xCA)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
70
X86Disassembler/X86/Handlers/Sbb/SbbAccumulatorImmHandler.cs
Normal file
70
X86Disassembler/X86/Handlers/Sbb/SbbAccumulatorImmHandler.cs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
namespace X86Disassembler.X86.Handlers.Sbb;
|
||||||
|
|
||||||
|
using Operands;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handler for SBB AX/EAX, imm16/32 instruction (0x1D)
|
||||||
|
/// </summary>
|
||||||
|
public class SbbAccumulatorImmHandler : InstructionHandler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the SbbAccumulatorImmHandler class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decoder">The instruction decoder that owns this handler</param>
|
||||||
|
public SbbAccumulatorImmHandler(InstructionDecoder decoder)
|
||||||
|
: base(decoder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if this handler can decode the given opcode
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opcode">The opcode to check</param>
|
||||||
|
/// <returns>True if this handler can decode the opcode</returns>
|
||||||
|
public override bool CanHandle(byte opcode)
|
||||||
|
{
|
||||||
|
return opcode == 0x1D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decodes a SBB AX/EAX, imm16/32 instruction
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opcode">The opcode of the instruction</param>
|
||||||
|
/// <param name="instruction">The instruction object to populate</param>
|
||||||
|
/// <returns>True if the instruction was successfully decoded</returns>
|
||||||
|
public override bool Decode(byte opcode, Instruction instruction)
|
||||||
|
{
|
||||||
|
// Set the instruction type
|
||||||
|
instruction.Type = InstructionType.Sbb;
|
||||||
|
|
||||||
|
// Determine operand size based on prefix
|
||||||
|
int operandSize = Decoder.HasOperandSizePrefix() ? 16 : 32;
|
||||||
|
|
||||||
|
// Check if we have enough bytes for the immediate value
|
||||||
|
if (operandSize == 16 && !Decoder.CanReadUShort())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (operandSize == 32 && !Decoder.CanReadUInt())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the accumulator register operand (AX or EAX)
|
||||||
|
var accumulatorOperand = OperandFactory.CreateRegisterOperand(RegisterIndex.A, operandSize);
|
||||||
|
|
||||||
|
// Read and create the immediate operand based on operand size
|
||||||
|
var immOperand = operandSize == 16
|
||||||
|
? OperandFactory.CreateImmediateOperand(Decoder.ReadUInt16(), operandSize)
|
||||||
|
: OperandFactory.CreateImmediateOperand(Decoder.ReadUInt32(), operandSize);
|
||||||
|
|
||||||
|
// Set the structured operands
|
||||||
|
instruction.StructuredOperands =
|
||||||
|
[
|
||||||
|
accumulatorOperand,
|
||||||
|
immOperand
|
||||||
|
];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
64
X86Disassembler/X86/Handlers/Sbb/SbbAlImmHandler.cs
Normal file
64
X86Disassembler/X86/Handlers/Sbb/SbbAlImmHandler.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
namespace X86Disassembler.X86.Handlers.Sbb;
|
||||||
|
|
||||||
|
using Operands;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handler for SBB AL, imm8 instruction (0x1C)
|
||||||
|
/// </summary>
|
||||||
|
public class SbbAlImmHandler : InstructionHandler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the SbbAlImmHandler class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decoder">The instruction decoder that owns this handler</param>
|
||||||
|
public SbbAlImmHandler(InstructionDecoder decoder)
|
||||||
|
: base(decoder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if this handler can decode the given opcode
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opcode">The opcode to check</param>
|
||||||
|
/// <returns>True if this handler can decode the opcode</returns>
|
||||||
|
public override bool CanHandle(byte opcode)
|
||||||
|
{
|
||||||
|
return opcode == 0x1C;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decodes a SBB AL, imm8 instruction
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opcode">The opcode of the instruction</param>
|
||||||
|
/// <param name="instruction">The instruction object to populate</param>
|
||||||
|
/// <returns>True if the instruction was successfully decoded</returns>
|
||||||
|
public override bool Decode(byte opcode, Instruction instruction)
|
||||||
|
{
|
||||||
|
// Set the instruction type
|
||||||
|
instruction.Type = InstructionType.Sbb;
|
||||||
|
|
||||||
|
// Create the AL register operand
|
||||||
|
var alOperand = OperandFactory.CreateRegisterOperand(RegisterIndex.A, 8);
|
||||||
|
|
||||||
|
// Check if we have enough bytes for the immediate value
|
||||||
|
if (!Decoder.CanReadByte())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the immediate value
|
||||||
|
byte imm8 = Decoder.ReadByte();
|
||||||
|
|
||||||
|
// Create the immediate operand
|
||||||
|
var immOperand = OperandFactory.CreateImmediateOperand(imm8, 8);
|
||||||
|
|
||||||
|
// Set the structured operands
|
||||||
|
instruction.StructuredOperands =
|
||||||
|
[
|
||||||
|
alOperand,
|
||||||
|
immOperand
|
||||||
|
];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
85
X86Disassembler/X86/Handlers/Sbb/SbbImmFromRm16Handler.cs
Normal file
85
X86Disassembler/X86/Handlers/Sbb/SbbImmFromRm16Handler.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
using X86Disassembler.X86.Operands;
|
||||||
|
|
||||||
|
namespace X86Disassembler.X86.Handlers.Sbb;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handler for SBB r/m16, imm16 instruction (0x81 /3 with 0x66 prefix)
|
||||||
|
/// </summary>
|
||||||
|
public class SbbImmFromRm16Handler : InstructionHandler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the SbbImmFromRm16Handler class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decoder">The instruction decoder that owns this handler</param>
|
||||||
|
public SbbImmFromRm16Handler(InstructionDecoder decoder)
|
||||||
|
: base(decoder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if this handler can decode the given opcode
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opcode">The opcode to check</param>
|
||||||
|
/// <returns>True if this handler can decode the opcode</returns>
|
||||||
|
public override bool CanHandle(byte opcode)
|
||||||
|
{
|
||||||
|
if (opcode != 0x81)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Must have operand size prefix for 16-bit operation
|
||||||
|
if (!Decoder.HasOperandSizePrefix())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if the reg field of the ModR/M byte is 3 (SBB)
|
||||||
|
if (!Decoder.CanReadByte())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var reg = ModRMDecoder.PeakModRMReg();
|
||||||
|
|
||||||
|
return reg == 3; // 3 = SBB
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decodes a SBB r/m16, imm16 instruction
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opcode">The opcode of the instruction</param>
|
||||||
|
/// <param name="instruction">The instruction object to populate</param>
|
||||||
|
/// <returns>True if the instruction was successfully decoded</returns>
|
||||||
|
public override bool Decode(byte opcode, Instruction instruction)
|
||||||
|
{
|
||||||
|
// Set the instruction type
|
||||||
|
instruction.Type = InstructionType.Sbb;
|
||||||
|
|
||||||
|
if (!Decoder.CanReadByte())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the ModR/M byte
|
||||||
|
// For SBB r/m16, imm16 (0x81 /3 with 0x66 prefix):
|
||||||
|
// - The r/m field with mod specifies the destination operand (register or memory)
|
||||||
|
// - The immediate value is the source operand
|
||||||
|
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM16();
|
||||||
|
|
||||||
|
// Check if we have enough bytes for the immediate value
|
||||||
|
if (!Decoder.CanReadUShort())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the immediate value
|
||||||
|
ushort imm16 = Decoder.ReadUInt16();
|
||||||
|
|
||||||
|
// Create the immediate operand
|
||||||
|
var sourceOperand = OperandFactory.CreateImmediateOperand(imm16, 16);
|
||||||
|
|
||||||
|
// Set the structured operands
|
||||||
|
instruction.StructuredOperands =
|
||||||
|
[
|
||||||
|
destinationOperand,
|
||||||
|
sourceOperand
|
||||||
|
];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
using X86Disassembler.X86.Operands;
|
||||||
|
|
||||||
|
namespace X86Disassembler.X86.Handlers.Sbb;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handler for SBB r/m16, imm8 (sign-extended) instruction (0x83 /3 with 0x66 prefix)
|
||||||
|
/// </summary>
|
||||||
|
public class SbbImmFromRm16SignExtendedHandler : InstructionHandler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the SbbImmFromRm16SignExtendedHandler class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decoder">The instruction decoder that owns this handler</param>
|
||||||
|
public SbbImmFromRm16SignExtendedHandler(InstructionDecoder decoder)
|
||||||
|
: base(decoder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if this handler can decode the given opcode
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opcode">The opcode to check</param>
|
||||||
|
/// <returns>True if this handler can decode the opcode</returns>
|
||||||
|
public override bool CanHandle(byte opcode)
|
||||||
|
{
|
||||||
|
if (opcode != 0x83)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Must have operand size prefix for 16-bit operation
|
||||||
|
if (!Decoder.HasOperandSizePrefix())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if the reg field of the ModR/M byte is 3 (SBB)
|
||||||
|
if (!Decoder.CanReadByte())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var reg = ModRMDecoder.PeakModRMReg();
|
||||||
|
|
||||||
|
return reg == 3; // 3 = SBB
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decodes a SBB r/m16, imm8 (sign-extended) instruction
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opcode">The opcode of the instruction</param>
|
||||||
|
/// <param name="instruction">The instruction object to populate</param>
|
||||||
|
/// <returns>True if the instruction was successfully decoded</returns>
|
||||||
|
public override bool Decode(byte opcode, Instruction instruction)
|
||||||
|
{
|
||||||
|
// Set the instruction type
|
||||||
|
instruction.Type = InstructionType.Sbb;
|
||||||
|
|
||||||
|
if (!Decoder.CanReadByte())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the ModR/M byte
|
||||||
|
// For SBB r/m16, imm8 (sign-extended) (0x83 /3 with 0x66 prefix):
|
||||||
|
// - The r/m field with mod specifies the destination operand (register or memory)
|
||||||
|
// - The immediate value is the source operand
|
||||||
|
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM16();
|
||||||
|
|
||||||
|
// Check if we have enough bytes for the immediate value
|
||||||
|
if (!Decoder.CanReadByte())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign-extend to 16 bits
|
||||||
|
sbyte imm8 = (sbyte)Decoder.ReadByte();
|
||||||
|
|
||||||
|
// Create the immediate operand with sign extension
|
||||||
|
var sourceOperand = OperandFactory.CreateImmediateOperand((ushort)imm8, 16);
|
||||||
|
|
||||||
|
// Set the structured operands
|
||||||
|
instruction.StructuredOperands =
|
||||||
|
[
|
||||||
|
destinationOperand,
|
||||||
|
sourceOperand
|
||||||
|
];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
81
X86Disassembler/X86/Handlers/Sbb/SbbImmFromRm8Handler.cs
Normal file
81
X86Disassembler/X86/Handlers/Sbb/SbbImmFromRm8Handler.cs
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
using X86Disassembler.X86.Operands;
|
||||||
|
|
||||||
|
namespace X86Disassembler.X86.Handlers.Sbb;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handler for SBB r/m8, imm8 instruction (0x80 /3)
|
||||||
|
/// </summary>
|
||||||
|
public class SbbImmFromRm8Handler : InstructionHandler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the SbbImmFromRm8Handler class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decoder">The instruction decoder that owns this handler</param>
|
||||||
|
public SbbImmFromRm8Handler(InstructionDecoder decoder)
|
||||||
|
: base(decoder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if this handler can decode the given opcode
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opcode">The opcode to check</param>
|
||||||
|
/// <returns>True if this handler can decode the opcode</returns>
|
||||||
|
public override bool CanHandle(byte opcode)
|
||||||
|
{
|
||||||
|
if (opcode != 0x80)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if the reg field of the ModR/M byte is 3 (SBB)
|
||||||
|
if (!Decoder.CanReadByte())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var reg = ModRMDecoder.PeakModRMReg();
|
||||||
|
|
||||||
|
return reg == 3; // 3 = SBB
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decodes a SBB r/m8, imm8 instruction
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opcode">The opcode of the instruction</param>
|
||||||
|
/// <param name="instruction">The instruction object to populate</param>
|
||||||
|
/// <returns>True if the instruction was successfully decoded</returns>
|
||||||
|
public override bool Decode(byte opcode, Instruction instruction)
|
||||||
|
{
|
||||||
|
// Set the instruction type
|
||||||
|
instruction.Type = InstructionType.Sbb;
|
||||||
|
|
||||||
|
if (!Decoder.CanReadByte())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the ModR/M byte
|
||||||
|
// For SBB r/m8, imm8 (0x80 /3):
|
||||||
|
// - The r/m field with mod specifies the destination operand (register or memory)
|
||||||
|
// - The immediate value is the source operand
|
||||||
|
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM8();
|
||||||
|
|
||||||
|
// Check if we have enough bytes for the immediate value
|
||||||
|
if (!Decoder.CanReadByte())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the immediate value
|
||||||
|
byte imm8 = Decoder.ReadByte();
|
||||||
|
|
||||||
|
// Create the immediate operand
|
||||||
|
var sourceOperand = OperandFactory.CreateImmediateOperand(imm8, 8);
|
||||||
|
|
||||||
|
// Set the structured operands
|
||||||
|
instruction.StructuredOperands =
|
||||||
|
[
|
||||||
|
destinationOperand,
|
||||||
|
sourceOperand
|
||||||
|
];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user