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

📄 dcopctoinstr.pas

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

interface

uses
  dcInstrSource, DisAsmX, SysUtils;

type
  { IInstrOwner }

  TInstruction = class;

  IInstrOwner = interface(IUnknown)
    procedure AddInstr(Instr: TInstruction);
    function GetAddress:  TAddress;
    function GetSize: Integer;
    function GetCount: Integer;
    function GetItem(Index: Integer): TInstruction;
    function GetItemIndex(Item: TInstruction): Integer;

    property Address: TAddress read GetAddress;
    property Size: Integer read GetSize;
    property Count: Integer read GetCount;
    // Items are always sorted on address.
    property Items[Index: Integer]: TInstruction read GetItem;
    property ItemIndexes[Item: TInstruction]: Integer read GetItemIndex;
  end;

  EInstructionError = class(Exception);

  { TInstruction }

  TInstruction = class(TObject)
  private
    FAddress: TAddress;
    FSize: Integer;
  public
    constructor Create(AAddress: TAddress); virtual; abstract;
    constructor CreateSized(AAddress: TAddress; ASize: Integer);
    function AllowReplaceCallBack(const Instrs: array of TInstruction): Boolean;

    property Address: TAddress read FAddress;
    property Size: Integer read FSize;
  end;

  TInstructionClass = class of TInstruction;

  { TAsmInstr }

  TAsmInstr = class(TInstruction)
  private
    FInstrText: string;
  public
    constructor CreateOpc(AAddress: TAddress; ASize: Integer);
    constructor Create(AAddress: TAddress); override;
    function AllowReplaceCallBack(const Instrs: array of TInstruction): Boolean;

    property InstrText: string read FInstrText;
  end;

  { TAssignInstr }

  TAssignInstr = class(TInstruction)
  private
    FTarget: IInstrSource;
    FSource: IInstrSource;
  public
    constructor Create(AAddress: TAddress); override;
    constructor CreateAssign(AAddress: TAddress; ASize: Integer; ATarget, ASource: IInstrSource);

    property Target: IInstrSource read FTarget;
    property Source: IInstrSource read FSource;
  end;

  { TRetInstr }

  TRetInstr = class(TInstruction)
  private
    FPopSize: Integer;
  public
    constructor Create(AAddress: TAddress); override;

    property PopSize: Integer read FPopSize;
  end;

{ TODO -cAdditions : Add other instruction types. }

{  TCallInstr = class(TInstruction)
  private
    FTarget: IInstrSource;
  public
    constructor Create(AAddress: TAddress); override;

    property Target: IInstrSource read FTarget;
  end;

  TJumpInstr = class(TInstruction)
  private
    FTarget: IInstrSource;
  public
    constructor Create(AAddress: TAddress); override;

    property Target: IInstrSource read FTarget;
  end;
}

procedure CreateInstr(Address: TAddress; InstrOwner: IInstrOwner);

implementation

uses
  dcAssignInstrTable, DisAsm;

{ TInstruction }

constructor TInstruction.CreateSized(AAddress: TAddress; ASize: Integer);
begin
  inherited Create;
  FAddress := AAddress;
  FSize := ASize;
end;

function TInstruction.AllowReplaceCallBack(const Instrs: array of TInstruction): Boolean;
begin
  // Allow replace by default.
  Result := True;
end;

{ TAsmInstr }

constructor TAsmInstr.CreateOpc(AAddress: TAddress; ASize: Integer);
var
  J: Integer;
begin
  inherited CreateSized(AAddress, ASize);
  // Just creaet DB instructions
  for J := ASize -1 downto 1 do
    FInstrText := ', $' + IntToHex(Byte(Pointer(Address + J)^), 2) + FInstrText;
  FInstrText := 'DB  $' + IntToHex(Byte(Pointer(Address)^), 2) + FInstrText;
end;

constructor TAsmInstr.Create(AAddress: TAddress);
var
  ASize: Integer;
begin
  // Get the Instruction text and size.
  with TDisAsm.Create do
  try
    FInstrText := GetInstruction(AAddress, ASize);
  finally
    Free;
  end;
  inherited CreateSized(AAddress, ASize);
end;

function TAsmInstr.AllowReplaceCallBack(const Instrs: array of TInstruction): Boolean;
begin
  // Don't append if there is an Asm instr.
  Result := False;
end;

{ TAssignInstr }

constructor TAssignInstr.Create(AAddress: TAddress);
var
  Instr: TOpcInstr;
  ASize: Integer;
resourcestring
   SErrorInInstr = 'Error in instruction';
begin
  // Get the instruction.
  Instr := GetInstruction(AAddress, ASize);
  if (not (Instr.Mnemonic in [mMov, mPush, mPop])) or
     (Instr.LoRepPrefix <> lrpNone) or
     (Instr.SegPrefix <> spNone) or Instr.AddressSizePrefix or
     (Instr.Arguments[3].ArgumentType <> atNone) then
    raise EInstructionError.Create(SErrorInInstr);
  // inherited create using the Size of the instruction.
  inherited CreateSized(AAddress, ASize);
  // Convert Instr arguments to Target and Source.
  case Instr.Mnemonic of
    mPush:
      begin
        FSource := ConvArgToIInstr(Instr.Arguments[1]);
        FTarget := CreateRefSource(CreateRegSource(DisAsmX.rEsp, rtDWord), 4);
      end;
    mPop:
      begin
        FTarget := ConvArgToIInstr(Instr.Arguments[1]);
        FSource := CreateRefSource(CreateRegSource(DisAsmX.rEsp, rtDWord), 4);
      end;
    else
      begin
        FTarget := ConvArgToIInstr(Instr.Arguments[1]);
        FSource := ConvArgToIInstr(Instr.Arguments[2]);
      end;
  end;

  if (FTarget = nil) or (FSource = nil) then
    raise Exception.Create(SErrorInInstr);
end;

constructor TAssignInstr.CreateAssign(AAddress: TAddress; ASize: Integer; ATarget, ASource: IInstrSource);
begin
  inherited CreateSized(AAddress, ASize);
  FTarget := ATarget;
  FSource := ASource;
end;

{ TRetInstr }

constructor TRetInstr.Create(AAddress: TAddress);
var
  Instr: TOpcInstr;
  ASize: Integer;
resourcestring
   SErrorInInstr = 'Error in instruction';
begin
  // Get the instruction.
  Instr := GetInstruction(AAddress, ASize);
  if (Instr.Mnemonic <> mRet) or (Instr.LoRepPrefix <> lrpNone) or
     (Instr.SegPrefix <> spNone) or Instr.AddressSizePrefix or
     (Instr.Arguments[2].ArgumentType <> atNone) or
     (Instr.Arguments[3].ArgumentType <> atNone) then
    raise EInstructionError.Create(SErrorInInstr);
  // inherited create using the Size of the instruction.
  inherited CreateSized(AAddress, ASize);
  // Get PopSize from the first argument.
  case Instr.Arguments[1].ArgumentType of
    atNone: FPopSize := 0;
    atImm: FPopSize := Instr.Arguments[1].ImmValue;
    else
      raise EInstructionError.Create(SErrorInInstr);
  end;
end;

// Create the instrs type using GetInstruction in DisAsmX.
procedure CreateInstr(Address: TAddress; InstrOwner: IInstrOwner);
var
  OpcInstr: TOpcInstr;
  ASize: Integer;
  Instr: TInstruction;
begin
  // Default an Assembler instruction.
  try
    OpcInstr := GetInstruction(Address, ASize);
  except
    On EDisAsmError do
    begin
      InstrOwner.AddInstr(TAsmInstr.Create(Address));
      Exit;
    end;
  end;
  { TODO -cAdditions : Add support other mnemonic types. }
  case OpcInstr.Mnemonic of
    mMov: InstrOwner.AddInstr(TAssignInstr.Create(Address));
    mRet: InstrOwner.AddInstr(TRetInstr.Create(Address));
    mPush:
      begin
        InstrOwner.AddInstr(TAssignInstr.CreateAssign(Address, 0, CreateRegSource(DisAsmX.rEsp, rtDWord),
          CreateDuoSource(CreateRegSource(DisAsmX.rEsp, rtDWord), CreateConstSource(4), dstSub)));
        InstrOwner.AddInstr(TAssignInstr.Create(Address));
      end;
    mPop:
      begin
        Instr := TAssignInstr.Create(Address);
        InstrOwner.AddInstr(Instr);
        InstrOwner.AddInstr(TAssignInstr.CreateAssign(Instr.Address + Instr.Size, 0, CreateRegSource(DisAsmX.rEsp, rtDWord),
          CreateDuoSource(CreateRegSource(DisAsmX.rEsp, rtDWord), CreateConstSource(4), dstAdd)));
      end;
    else
      InstrOwner.AddInstr(TAsmInstr.Create(Address));
  end;
end;

end.

⌨️ 快捷键说明

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