?? pefixups.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 + -