📄 peanalystunit.pas
字号:
unit PEAnalystUnit;
interface
uses
Windows, SysUtils,
JwaWinnt,
PEHeaderUnit, UtilUnit;
type
TPEAnalyst = class
private
FPEHeader: TPEHeader;
FFileSize: Cardinal;
FHasTls: Bool;
FHasOverlay: Bool;
FOverlayOffset: Cardinal;
FOverlaySize: Cardinal;
function GetHeaderSize: Cardinal;
function GetImageSize: Cardinal;
function GetSectionCount: Cardinal;
function GetSectionHeaders(Index: Cardinal): PImageSectionHeader;
function GetPEHeaderPtr: Pointer;
function GetImageBase: Cardinal;
procedure SetImageBase(const Value: Cardinal);
function GetEntryPointRVA: Cardinal;
procedure SetEntryPointRVA(const Value: Cardinal);
function GetDataDirectory(Index: Cardinal): PImageDataDirectory;
function GetDataDirectoryCount: Cardinal;
function LastRawDataOffset: Cardinal;
function HasDllFlag: Bool;
public
constructor Create;
destructor Destroy; override;
function Assign(PEPtr: Pointer; FileSize: Cardinal): Bool;
function AddSection(Length: Cardinal): PImageSectionHeader;
function OffsetInSection(Offset: Cardinal): Cardinal;
function OffsettoRVA(Offset: Cardinal): Cardinal;
function RVAInSection(RVA: Cardinal): Cardinal;
function RVAtoOffset(RVA: Cardinal): Cardinal;
function RVAtoPtr(RVA: Cardinal): Pointer;
procedure UpdateImageSize;
procedure DeleteSection(Index: Cardinal);
property PEHeader: TPEHeader read FPEHeader;
property PEHeaderPtr: Pointer read GetPEHeaderPtr;
property DataDirectorys[Index: Cardinal]: PImageDataDirectory read GetDataDirectory;
property SectionHeaders[Index: Cardinal]: PImageSectionHeader read GetSectionHeaders;
property ImageBase: Cardinal read GetImageBase write SetImageBase;
property ImageSize: Cardinal read GetImageSize;
property HeaderSize: Cardinal read GetHeaderSize;
property FileSize: Cardinal read FFileSize;
property EntryPointRVA: Cardinal read GetEntryPointRVA write SetEntryPointRVA;
property SectionCount: Cardinal read GetSectionCount;
property DataDirectoryCount: Cardinal read GetDataDirectoryCount;
property HasTls: Bool read FHasTls;
property HasOverlay: Bool read FHasOverlay;
property OverlayOffset: Cardinal read FOverlayOffset;
property OverlaySize: Cardinal read FOverlaySize;
property IsDll: Bool read HasDllFlag;
end;
implementation
{ TPEAnalyst }
function TPEAnalyst.AddSection(Length: Cardinal): PImageSectionHeader;
var
i: Cardinal;
LastOffset, LastSize: Cardinal;
begin
result := nil;
if not FPEHeader.AddSection(result) then exit;
if Length > 0 then
result.Misc.VirtualSize := FPEHeader.CalcSectionAilgnment(Length)
else
result.Misc.VirtualSize := FPEHeader.FA;
LastOffset := 0;
LastSize := 0;
if SectionCount > 1 then
for i := 0 to SectionCount - 2 do
if LastOffset < SectionHeaders[i]^.PointerToRawData then
begin
LastOffset := SectionHeaders[i]^.PointerToRawData;
LastSize := SectionHeaders[i]^.SizeOfRawData;
end
else if (LastOffset = SectionHeaders[i]^.PointerToRawData) and
(LastSize < SectionHeaders[i]^.SizeOfRawData) then
begin
LastOffset := SectionHeaders[i]^.PointerToRawData;
LastSize := SectionHeaders[i]^.SizeOfRawData;
end;
result.SizeOfRawData := Length;
result.PointerToRawData := LastOffset + FPEHeader.CalcFileAilgnment(LastSize);
if result.PointerToRawData = 0 then
result.PointerToRawData := HeaderSize;
UpdateImageSize;
end;
function TPEAnalyst.Assign(PEPtr: Pointer; FileSize: Cardinal): Bool;
begin
FFileSize := FileSize;
result := FPEHeader.Assign(PEPtr);
if not result then exit;
FHasTls := DataDirectorys[9].VirtualAddress <> 0;
FOverlayOffset := LastRawDataOffset;
FHasOverlay := FOverlayOffset < FileSize;
if FHasOverlay then
FOverlaySize := FileSize - FOverlayOffset
else
begin
FOverlayOffset := 0;
FOverlaySize := 0;
end;
end;
constructor TPEAnalyst.Create;
begin
inherited;
FPEHeader := TPEHeader.Create;
FFileSize := 0;
end;
destructor TPEAnalyst.Destroy;
begin
FPEHeader.Free;
inherited;
end;
function TPEAnalyst.GetDataDirectory(Index: Cardinal): PImageDataDirectory;
begin
result := FPEHeader.DataDirectorys[Index];
end;
function TPEAnalyst.GetEntryPointRVA: Cardinal;
begin
result := FPEHeader.OptionalHeader32.AddressOfEntryPoint;
end;
function TPEAnalyst.GetHeaderSize: Cardinal;
begin
result := FPEHeader.HeaderSize;
end;
function TPEAnalyst.GetImageBase: Cardinal;
begin
result := FPEHeader.OptionalHeader32.ImageBase;
end;
function TPEAnalyst.GetImageSize: Cardinal;
begin
result := FPEHeader.OptionalHeader32.SizeOfImage;
end;
function TPEAnalyst.GetPEHeaderPtr: Pointer;
begin
result := PEHeader.DosHeader;
end;
function TPEAnalyst.GetSectionHeaders(Index: Cardinal): PImageSectionHeader;
begin
result := PEHeader.Sections[Index];
end;
function TPEAnalyst.GetSectionCount: Cardinal;
begin
result := FPEHeader.SectionCount;
end;
function TPEAnalyst.OffsetInSection(Offset: Cardinal): Cardinal;
begin
result := FPEHeader.OffsetInSection(Offset);
end;
function TPEAnalyst.OffsettoRVA(Offset: Cardinal): Cardinal;
begin
result := FPEHeader.OffsettoRVA(Offset);
end;
function TPEAnalyst.RVAInSection(RVA: Cardinal): Cardinal;
begin
result := FPEHeader.RVAInSection(RVA);
end;
function TPEAnalyst.RVAtoOffset(RVA: Cardinal): Cardinal;
begin
result := FPEHeader.RVAtoOffset(RVA);
end;
function TPEAnalyst.RVAtoPtr(RVA: Cardinal): Pointer;
begin
result := FPEHeader.RVAtoPtr(RVA);
end;
procedure TPEAnalyst.SetEntryPointRVA(const Value: Cardinal);
begin
FPEHeader.OptionalHeader32.AddressOfEntryPoint := Value;
end;
procedure TPEAnalyst.SetImageBase(const Value: Cardinal);
begin
FPEHeader.OptionalHeader32.ImageBase := Value;
end;
procedure TPEAnalyst.UpdateImageSize;
begin
FPEHeader.UpdateImageSize;
end;
procedure TPEAnalyst.DeleteSection(Index: Cardinal);
var
i: Cardinal;
begin
for i := 0 to DataDirectoryCount - 1 do
if (DataDirectorys[i]^.VirtualAddress > SectionHeaders[Index]^.VirtualAddress) and
(DataDirectorys[i]^.VirtualAddress + DataDirectorys[i]^.Size >
SectionHeaders[Index]^.VirtualAddress + SectionHeaders[Index]^.Misc.VirtualSize) then
begin
DataDirectorys[i]^.VirtualAddress := 0;
DataDirectorys[i]^.Size := 0;
end;
FPEHeader.WipeSectionHeader(Index);
end;
function TPEAnalyst.GetDataDirectoryCount: Cardinal;
begin
result := FPEHeader.DirectoryCount;
end;
function TPEAnalyst.LastRawDataOffset: Cardinal;
var
i, j: Cardinal;
begin
result := 0;
for i := 0 to SectionCount - 1 do
begin
j := SectionHeaders[i]^.PointerToRawData + SectionHeaders[i]^.SizeOfRawData;
if result < j then
result := j;
end;
end;
function TPEAnalyst.HasDllFlag: Bool;
begin
result := FPEHeader.FileHeader.Characteristics and $2000 = $2000;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -