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

📄 pefixups.pas

📁 SrcDecompiler is about creating a Delphi program decompiler. The program is written for Delphi 4 or
💻 PAS
字号:

//    Author:          Python
//    Version:         0.0.1.0
//    LastModified:    2-17-2000
//    LatestVersion:   http://thunder.prohosting.com/~pytho/
//    Copyright (c) 1999, 2000 Python. All rights reserved

unit peFixups;

interface

uses
  Classes;

type
  TPEFixup = record
    FixupType: Byte;
    Address: PChar;
  end;

  { TFixups }

  TFixups = class(TObject)
  private
    FList: Pointer;
    FCount: Integer;
    FPEFile: TObject;
    function GetFixup(Index: Integer): TPEFixup;
  public
    constructor Create(PEFile: TObject);
    destructor Destroy; override;
    procedure ApplyFixups;
    procedure Del0Fixups;

    function Add(Fixup: TPEFixup): Integer; overload;
    function Add(AFixupType: Byte; AAddress: PChar): Integer; overload;
    procedure Delete(Index: Integer);

    function FindFixup(Address: PChar): Integer;
    function FindFixupAfter(Address: PChar): Integer;
    function FindFixupTo(Address: PChar): Integer;
    function FindFixupToAfter(Address: PChar): Integer;

    property Items[Index: Integer]: TPEFixup read GetFixup; default;
    property Count: Integer read FCount;
  end;

implementation

uses
  PEFile, Windows;

{ TFixups }

type
  TPEFixups = array[0..MaxListSize] of TPEFixup;

constructor TFixups.Create(PEFile: TObject);
var
  FixupTable: PChar;
  EndFixupBlock: PChar;
  PageRVA: Integer;
  XPEFile: TPEFile absolute PEFile;
begin
  inherited Create;
  FPEFile := PEFile;

  FixupTable := XPEFile.FileBase +
        PIMAGE_NT_HEADERS(XPEFile.FileBase + PImageDosHeader(XPEFile.FileBase)^._lfanew)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
  // While PageRVA <> 0 apply fixup Block.
  while PInteger(FixupTable)^ <> 0 do
  begin
    // Save page RVA.
    PageRVA := PInteger(FixupTable)^;
    // Calculate end fixup block
    EndFixupBlock := Fixuptable + PInteger(FixupTable + 4)^;
    // skip page rva and fixup block.
    Inc(FixupTable, 8);

    while FixupTable < EndFixupBlock do
    begin
      // Save the fixup in the fixup list
      Add(Byte(FixupTable[1]) shr 4,
          XPEFile.FileBase + pageRVA + (PWord(FixupTable)^ and $0FFF));

      // Next fixup.
      Inc(FixupTable, 2);
    end;
  end;
end;

destructor TFixups.Destroy;
begin
  FreeMem(FList, FCount * SizeOf(TPEFixup));
  inherited Destroy;
end;

procedure TFixups.ApplyFixups;
var
  I: Integer;
  Delta: Integer;
begin
  // Calculate Delta
  Delta := TPEFile(FPEFile).FileBase - TPEFile(FPEFile).ImageBase;
  // Apply Delta
  if Delta <> 0 then
    for I := Count -1 downto 0 do
      case TPEFixups(FList^)[I].FixupType of
        // Nothing.
        0: ;
        // High
        1: Inc(PWord(TPEFixups(FList^)[I].Address)^, Delta shr 4);
        // Low
        2: Inc(PWord(TPEFixups(FList^)[I].Address)^, Word(Delta));
        // HighLow
        3: Inc(PDWord(TPEFixups(FList^)[I].Address)^, Delta);
      end;
end;

procedure TFixups.Del0Fixups;
var
  I: Integer;
begin
  // Delete fixups with fixuptype 0 (those who do nothing).
  for I := Count -1 downto 0 do
    if TPEFixups(FList^)[I].FixupType = 0 then
      Delete(I);
end;

function TFixups.GetFixup(Index: Integer): TPEFixup;
begin
  Result := TPEFixups(FList^)[Index];
end;

function TFixups.Add(Fixup: TPEFixup): Integer;
begin
  Inc(FCount);
  ReallocMem(FList, FCount * SizeOf(TPEFixup));
  // Search the place where the fixup must be inserted.
  for Result := FCount -1 downto 0 do
    if (Result = 0) or (TPEFixups(FList^)[Result -1].Address < Fixup.Address) then
    begin
      Move(TPEFixups(FList^)[Result], TPEFixups(FList^)[Result +1],
       (FCount - Result -1) * SizeOf(TPEFixup));
      TPEFixups(FList^)[Result] := Fixup;
      Exit;
    end;
  Result := -1;
end;

function TFixups.Add(AFixupType: Byte; AAddress: PChar): Integer;
var
  Fixup: TPEFixup;
begin
  Fixup.FixupType := AFixupType;
  Fixup.Address := AAddress;
  Result := Add(Fixup);
end;

procedure TFixups.Delete(Index: Integer);
begin
  Dec(FCount);
  Move(TPEFixups(FList^)[Index +1], TPEFixups(FList^)[Index],
     (FCount - Index) * SizeOf(TPEFixup));
  ReallocMem(FList, FCount * SizeOf(TPEFixup));
end;

function TFixups.FindFixup(Address: PChar): Integer;
var
  H, I, C: Integer;
begin
  // Fixups are ordened on address, so search using quick search.
  Result := 0;
  H := FCount - 1;
  while Result <= H do
  begin
    I := (Result + H) shr 1;
    C := TPEFixups(FList^)[I].Address - Address;
    if C < 0 then Result := I + 1 else
    begin
      H := I - 1;
      if C = 0 then
        Exit;
    end;
  end;
  Result := -1;
end;

function TFixups.FindFixupAfter(Address: PChar): Integer;
var
  H, I, C: Integer;
begin
  // Fixups are ordened on address, so search using quick search.
  Result := 0;
  H := FCount - 1;
  while Result <= H do
  begin
    I := (Result + H) shr 1;
    C := TPEFixups(FList^)[I].Address - Address;
    if C <= 0 then
      Result := I + 1
    else
      H := I - 1;
  end;
  if Result >= Count then
    Result := -1;
end;

function TFixups.FindFixupTo(Address: PChar): Integer;
begin
  // Loop though all the fixups.
  for Result := 0 to Count -1 do
    if PPChar(TPEFixups(FList^)[Result].Address)^ = Address then
      Exit;
  Result := -1;
end;

function TFixups.FindFixupToAfter(Address: PChar): Integer;
var
  LowestAddress: PChar;
  I: Integer;
begin
  LowestAddress := pointer(MaxInt);
  Result := -1;
  for I := 0 to Count -1 do
    if (PPChar(TPEFixups(FList^)[I].Address)^ > Address) and
       (PPChar(TPEFixups(FList^)[I].Address)^ < LowestAddress) then
    begin
      Result := I;
      LowestAddress := PPChar(TPEFixups(FList^)[Result].Address)^;
    end;
end;

end.

⌨️ 快捷键说明

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