⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disasmx.pas

📁 这是个反向工程delphi的程序的全部源代码.能分析几乎所有的结构 Revendepro is a program to reverse engineer Delphi program. Reven
💻 PAS
字号:
unit DisAsmX;

interface

uses
  SysUtils, dcAssignInstrTable;

type
  TAddress = PAnsiChar;
  PAddress = ^TAddress;

  TFlag = (fZero, fOverflow);

  TArgumentType = (atNone, atRegv, atRefv, atImm);

  TRegister = (rEax, rEcx, rEdx, rEbx, rEsp, rEbp, rEsi, rEdi);
  TRegisterType = (rtLowByte, rtHighByte, rtLowWord, rtDWord);

  TdaRef = record
    MultiplyReg1: Integer;
    ARegister1: TRegister;
    MultiplyReg2: Integer;
    ARegister2: TRegister;
    Immidiate: TAddress;
    ImmidiateAddress: TAddress;
  end;

  TArgument = record
    ArgumentType: TArgumentType;
    case TArgumentType of
      atNone:
        ();
      atRefv:
        ( Ref: TdaRef );
      atRegv:
        ( Reg: TRegister );
      atImm:
        ( ImmValue: Cardinal;
          ImmAddress: TAddress);
  end;

  TLoRepPrefix = (lrpNone, lrpLock, lrpRepNE, lrpRep);

const
  LowLoRepPrefix = lrpLock;
  HighLoRepPrefix = lrpRep;

type
  TSegmentPrefix = (spNone, spCS, spSS, spDS, spES, spFS, spGS);

const
  LowSegPrefix = spCS;
  HighSegPrefix = spGS;

type
  TOpcInstr = record
    LoRepPrefix: TLoRepPrefix;
    SegPrefix: TSegmentPrefix;
    AddressSizePrefix: Boolean;
    OperandSizePrefix: Boolean;
    Mnemonic: TMnemonic;
    Arguments: array[1..3] of TArgument;
  end;

  EDisAsmError = class(Exception);

const
  // Lock Rep prefixes
  LockPrefix = #$F0;
  RepNEPrefix = #$F2;
  RepPrefix = #$F3;

  LoRepPrefixes: array[LowLoRepPrefix .. HighLoRepPrefix] of AnsiChar =
    (LockPrefix, RepNEPrefix, RepPrefix);

  // Segment prefixes
  CSPrefix = #$2E;
  SSPrefix = #$36;
  DSPrefix = #$3E;
  ESPrefix = #$26;
  FSPrefix = #$64;
  GSPrefix = #$65;

  SegPrefixes: array[LowSegPrefix .. HighSegPrefix] of AnsiChar =
    (CSPrefix, SSPrefix, dsPrefix, esPrefix, fsPrefix, gsPrefix);

  // Operand size prefix
  OperandSizePrefix = #$66;

  // Address size prefix
  AddressSizePrefix = #$67;

const
  modrmReg = $38;  // Reg part of the ModRM byte, ??XXX???
  modrmMod = $C0;  // Mod part of the ModRM byte, XX??????
  modrmRM =  $07;  // RM part of the ModRM byte,  ?????XXX

resourcestring
  SInvalidInstructionError = 'Invalid instruction opcode at %p';
  SNotYetSupported = 'This opcode is not yet supported';
  SErrorInCode = 'This error shouldn''t occur';

function GetInstruction(Address: TAddress; var Size: Integer): TOpcInstr;

implementation

// Reads the instruction at Address and return the Size and 
function GetInstruction(Address: TAddress; var Size: Integer): TOpcInstr;
var
  Instr: TOpcInstr absolute Result;

  procedure CheckPrefixes;
  var
    NotChanged: Boolean;
    LoRepPrefix: TLoRepPrefix;
    SegPrefix: TSegmentPrefix;
  begin
    repeat
      NotChanged := True;
      // Check LoRepPrefix.
      for LoRepPrefix := LowLoRepPrefix to HighLoRepPrefix do
        if Address[Size] = LoRepPrefixes[LoRepPrefix] then
        begin
          // Prefix may not already been set.
          if Instr.LoRepPrefix <> lrpNone then
            raise EDisAsmError.CreateFmt(SInvalidInstructionError, [Pointer(Address)]);
          // Set the vars.
          Instr.LoRepPrefix := LoRepPrefix;
          NotChanged := False;
          Size := Size + 1;
        end;
      // Check SegPrefix.
      for SegPrefix := LowSegPrefix to HighSegPrefix do
        if Address[Size] = SegPrefixes[SegPrefix] then
        begin
          // Prefix may not already been set.
          if Instr.SegPrefix <> spNone then
            raise EDisAsmError.CreateFmt(SInvalidInstructionError, [Pointer(Address)]);
          // Set the vars.
          Instr.SegPrefix := SegPrefix;
          NotChanged := False;
          Size := Size + 1;
        end;
      // Check Operand Size prefix.
      if Address[Size] = OperandSizePrefix then
      begin
        // Prefix may not already been set.
        if Instr.OperandSizePrefix then
          raise EDisAsmError.CreateFmt(SInvalidInstructionError, [Pointer(Address)]);
        // Set the vars.
        Instr.OperandSizePrefix := True;
        NotChanged := False;
        Size := Size + 1;
      end;
      // Check Address Size prefix
      if Address[Size] = AddressSizePrefix then
      begin
        // Prefix may not already been set.
        if Instr.AddressSizePrefix then
          raise EDisAsmError.CreateFmt(SInvalidInstructionError, [Pointer(Address)]);
        // Set the vars.
        Instr.AddressSizePrefix := True;
        NotChanged := False;
        Size := Size + 1;
      end;
    until NotChanged;
  end;  // End CheckPrefixes

// Only read the ModRM byte the first time it is asked.
// After that return the previous read ModRM byte
var
  XHasModRM: Boolean;
  XModRM: Byte;

  function ReadByte: Byte;
  begin
    Result := Byte(Address[Size]);
    Inc(Size, 1);
  end;

  function ModRM: Byte;
  begin
    if not XHasModRM then
    begin
      XModRM := ReadByte;
      XHasModRM := True;
    end;
    Result := XModRM;
  end;

var
  Opc: TOpcode;
  I: Integer;

  procedure GetEffectiveAddress(const Arg: TArgumentOpcType);
  var
    RM: Byte;
    AMod: Byte;
  const
    RegArgType: array[TArgumentOpcType] of TArgumentType =
       (atNone, atRegv, atNone, atNone, atNone, atNone);
  begin
    RM := ModRM and modrmRM;
    AMod := ModRm and modrmMod shr 6;

    if AMod = 3 then
    begin
      // Effective address is a register.
      Instr.Arguments[I].ArgumentType := RegArgType[Arg];
      Instr.Arguments[I].Reg := TRegister(RM);
    end
    else
    begin
      // Effective address is not an register.
      raise EDisAsmError.Create(SNotYetSupported);
    end;
  end; // End GetEffectiveAddress.

const
  OpcodeRegs: array[TArgumentOpcType] of TRegister =
    (rEax, rEax, rEax, rEax, {aotRegEAXv} rEax, {aotRegEBPv} rEbp);
begin
  Size := 0;
  FillChar(Instr, SizeOf(TOpcInstr), 0);
  XHasModRM := False;

  CheckPrefixes;

  // Get the opcode information.
  Opc := OneByteOpcodes[AnsiChar(ReadByte)];

  Instr.Mnemonic := Opc.M;

  // Get the Mnemonic.
  for I := 1 to 3 do
    case Opc.A[I] of
      aotNone: ;
      aotModRMRMv: GetEffectiveAddress(Opc.A[I]);
      aotModRMRegv:
        begin
          Instr.Arguments[I].ArgumentType := atRegv;
          Instr.Arguments[I].Reg := TRegister((ModRM and ModRMReg) div 8);
        end;
      aotImmb:
        begin
          Instr.Arguments[I].ArgumentType := atImm;
          Instr.Arguments[I].ImmAddress := Address + Size;
          Instr.Arguments[I].ImmValue := Cardinal(ReadByte);
        end;
      aotRegEAXv, aotRegEBPv:
        begin
          Instr.Arguments[I].ArgumentType := atRegv;
          Instr.Arguments[I].Reg := OpcodeRegs[Opc.A[I]];
        end;
      else
        raise EDisAsmError.Create(SErrorInCode);
    end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -