mirror of
				https://github.com/sampletext32/ParkanPlayground.git
				synced 2025-11-04 07:19:45 +03:00 
			
		
		
		
	Implemented NOP instruction handlers for multi-byte NOP variants
This commit is contained in:
		@@ -10,6 +10,7 @@ using X86Disassembler.X86.Handlers.Inc;
 | 
			
		||||
using X86Disassembler.X86.Handlers.Jump;
 | 
			
		||||
using X86Disassembler.X86.Handlers.Lea;
 | 
			
		||||
using X86Disassembler.X86.Handlers.Mov;
 | 
			
		||||
using X86Disassembler.X86.Handlers.Nop;
 | 
			
		||||
using X86Disassembler.X86.Handlers.Or;
 | 
			
		||||
using X86Disassembler.X86.Handlers.Pop;
 | 
			
		||||
using X86Disassembler.X86.Handlers.Push;
 | 
			
		||||
@@ -78,6 +79,7 @@ public class InstructionHandlerFactory
 | 
			
		||||
        RegisterStringHandlers();
 | 
			
		||||
        RegisterMovHandlers();
 | 
			
		||||
        RegisterSubHandlers(); // Register SUB handlers
 | 
			
		||||
        RegisterNopHandlers(); // Register NOP handlers
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -396,6 +398,17 @@ public class InstructionHandlerFactory
 | 
			
		||||
        _handlers.Add(new SubImmFromRm8Handler(_codeBuffer, _decoder, _length));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Registers all NOP instruction handlers
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    private void RegisterNopHandlers()
 | 
			
		||||
    {
 | 
			
		||||
        // Register NOP handlers
 | 
			
		||||
        _handlers.Add(new NopHandler(_codeBuffer, _decoder, _length));
 | 
			
		||||
        _handlers.Add(new TwoByteNopHandler(_codeBuffer, _decoder, _length));
 | 
			
		||||
        _handlers.Add(new MultiByteNopHandler(_codeBuffer, _decoder, _length));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Gets the handler that can decode the given opcode
 | 
			
		||||
    /// </summary>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										99
									
								
								X86Disassembler/X86/Handlers/Nop/MultiByteNopHandler.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								X86Disassembler/X86/Handlers/Nop/MultiByteNopHandler.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
namespace X86Disassembler.X86.Handlers.Nop;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// Handler for multi-byte NOP instructions (0x0F 0x1F ...)
 | 
			
		||||
/// These are used for alignment and are encoded as NOP operations with specific memory operands
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class MultiByteNopHandler : InstructionHandler
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Initializes a new instance of the MultiByteNopHandler class
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="codeBuffer">The buffer containing the code to decode</param>
 | 
			
		||||
    /// <param name="decoder">The instruction decoder that owns this handler</param>
 | 
			
		||||
    /// <param name="length">The length of the buffer</param>
 | 
			
		||||
    public MultiByteNopHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
 | 
			
		||||
        : base(codeBuffer, decoder, length)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <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)
 | 
			
		||||
    {
 | 
			
		||||
        // Multi-byte NOPs start with 0x0F
 | 
			
		||||
        if (opcode != 0x0F)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        int position = Decoder.GetPosition();
 | 
			
		||||
        
 | 
			
		||||
        // Check if we have enough bytes to read the second opcode
 | 
			
		||||
        if (position >= Length)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Check if the second byte is 0x1F (part of the multi-byte NOP encoding)
 | 
			
		||||
        byte secondByte = CodeBuffer[position];
 | 
			
		||||
        return secondByte == 0x1F;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Decodes a multi-byte NOP 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 mnemonic
 | 
			
		||||
        instruction.Mnemonic = "nop";
 | 
			
		||||
        
 | 
			
		||||
        int position = Decoder.GetPosition();
 | 
			
		||||
        
 | 
			
		||||
        // Skip the second byte (0x1F)
 | 
			
		||||
        position++;
 | 
			
		||||
        
 | 
			
		||||
        // Check if we have enough bytes to read the ModR/M byte
 | 
			
		||||
        if (position >= Length)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Read the ModR/M byte
 | 
			
		||||
        byte modRM = CodeBuffer[position++];
 | 
			
		||||
        
 | 
			
		||||
        // Extract the fields from the ModR/M byte
 | 
			
		||||
        byte mod = (byte)((modRM & 0xC0) >> 6);
 | 
			
		||||
        byte reg = (byte)((modRM & 0x38) >> 3);
 | 
			
		||||
        byte rm = (byte)(modRM & 0x07);
 | 
			
		||||
        
 | 
			
		||||
        // Update the decoder position
 | 
			
		||||
        Decoder.SetPosition(position);
 | 
			
		||||
        
 | 
			
		||||
        // Decode the memory operand
 | 
			
		||||
        string memOperand;
 | 
			
		||||
        
 | 
			
		||||
        if (mod == 3)
 | 
			
		||||
        {
 | 
			
		||||
            // This is a register operand, which is not a valid multi-byte NOP
 | 
			
		||||
            // But we'll handle it anyway
 | 
			
		||||
            memOperand = ModRMDecoder.GetRegisterName(rm, 32);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // Get the memory operand string
 | 
			
		||||
            memOperand = ModRMDecoder.DecodeModRM(mod, rm, false);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Set the operands
 | 
			
		||||
        instruction.Operands = memOperand;
 | 
			
		||||
        
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								X86Disassembler/X86/Handlers/Nop/NopHandler.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								X86Disassembler/X86/Handlers/Nop/NopHandler.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
namespace X86Disassembler.X86.Handlers.Nop;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// Handler for the NOP instruction (opcode 0x90)
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class NopHandler : InstructionHandler
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Initializes a new instance of the NopHandler class
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="codeBuffer">The buffer containing the code to decode</param>
 | 
			
		||||
    /// <param name="decoder">The instruction decoder that owns this handler</param>
 | 
			
		||||
    /// <param name="length">The length of the buffer</param>
 | 
			
		||||
    public NopHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
 | 
			
		||||
        : base(codeBuffer, decoder, length)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <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 == 0x90;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Decodes a NOP 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 mnemonic
 | 
			
		||||
        instruction.Mnemonic = "nop";
 | 
			
		||||
        
 | 
			
		||||
        // NOP has no operands
 | 
			
		||||
        instruction.Operands = "";
 | 
			
		||||
        
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								X86Disassembler/X86/Handlers/Nop/TwoByteNopHandler.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								X86Disassembler/X86/Handlers/Nop/TwoByteNopHandler.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
namespace X86Disassembler.X86.Handlers.Nop;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// Handler for the 2-byte NOP instruction (0x66 0x90)
 | 
			
		||||
/// This is a NOP with an operand size prefix
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class TwoByteNopHandler : InstructionHandler
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Initializes a new instance of the TwoByteNopHandler class
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="codeBuffer">The buffer containing the code to decode</param>
 | 
			
		||||
    /// <param name="decoder">The instruction decoder that owns this handler</param>
 | 
			
		||||
    /// <param name="length">The length of the buffer</param>
 | 
			
		||||
    public TwoByteNopHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
 | 
			
		||||
        : base(codeBuffer, decoder, length)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <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)
 | 
			
		||||
    {
 | 
			
		||||
        // Check if the opcode is 0x90 and we have a 0x66 prefix
 | 
			
		||||
        return opcode == 0x90 && Decoder.HasOperandSizeOverridePrefix();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Decodes a 2-byte NOP 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 mnemonic
 | 
			
		||||
        instruction.Mnemonic = "nop";
 | 
			
		||||
        
 | 
			
		||||
        // NOP has no operands, even with the operand size prefix
 | 
			
		||||
        instruction.Operands = "";
 | 
			
		||||
        
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,2 +1,31 @@
 | 
			
		||||
# NOP instruction tests
 | 
			
		||||
# Format: RawBytes;Instructions
 | 
			
		||||
RawBytes;Instructions
 | 
			
		||||
 | 
			
		||||
# Basic NOP instruction (1-byte)
 | 
			
		||||
90;[{ "Mnemonic": "nop", "Operands": "" }]
 | 
			
		||||
 | 
			
		||||
# Multi-byte NOP instructions (used for alignment)
 | 
			
		||||
# 2-byte NOP
 | 
			
		||||
6690;[{ "Mnemonic": "nop", "Operands": "" }]
 | 
			
		||||
 | 
			
		||||
# 3-byte NOP (XCHG EAX, EAX)
 | 
			
		||||
0F1F00;[{ "Mnemonic": "nop", "Operands": "dword ptr [eax]" }]
 | 
			
		||||
 | 
			
		||||
# 4-byte NOP
 | 
			
		||||
0F1F4000;[{ "Mnemonic": "nop", "Operands": "dword ptr [eax+0x00]" }]
 | 
			
		||||
 | 
			
		||||
# 5-byte NOP
 | 
			
		||||
0F1F440000;[{ "Mnemonic": "nop", "Operands": "dword ptr [eax+eax]" }]
 | 
			
		||||
 | 
			
		||||
# 6-byte NOP
 | 
			
		||||
660F1F440000;[{ "Mnemonic": "nop", "Operands": "dword ptr [eax+eax]" }]
 | 
			
		||||
 | 
			
		||||
# 7-byte NOP
 | 
			
		||||
0F1F8000000000;[{ "Mnemonic": "nop", "Operands": "dword ptr [eax+0x00000000]" }]
 | 
			
		||||
 | 
			
		||||
# 8-byte NOP
 | 
			
		||||
0F1F840000000000;[{ "Mnemonic": "nop", "Operands": "dword ptr [eax+eax]" }]
 | 
			
		||||
 | 
			
		||||
# 9-byte NOP
 | 
			
		||||
660F1F840000000000;[{ "Mnemonic": "nop", "Operands": "dword ptr [eax+eax]" }]
 | 
			
		||||
 
 | 
			
		||||
| 
		
		
			 Can't render this file because it contains an unexpected character in line 2 and column 7. 
		
	 | 
		Reference in New Issue
	
	Block a user