📄 jclpeimage.pas
字号:
{**************************************************************************************************}
{ }
{ Project JEDI Code Library (JCL) }
{ }
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
{ you may not use this file except in compliance with the License. You may obtain a copy of the }
{ License at http://www.mozilla.org/MPL/ }
{ }
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
{ ANY KIND, either express or implied. See the License for the specific language governing rights }
{ and limitations under the License. }
{ }
{ The Original Code is JclPeImage.pas. }
{ }
{ The Initial Developer of the Original Code is Petr Vones. Portions created by Petr Vones are }
{ Copyright (C) Petr Vones. All Rights Reserved. }
{ }
{ Contributor(s): }
{ Marcel van Brakel }
{ Robert Marquardt (marquardt) }
{ Uwe Schuster (uschuster) }
{ Matthias Thoma (mthoma) }
{ Petr Vones (pvones) }
{ Hallvard Vassbotn }
{ }
{**************************************************************************************************}
{ }
{ This unit contains various classes and support routines to read the contents of portable }
{ executable (PE) files. You can use these classes to, for example examine the contents of the }
{ imports section of an executable. In addition the unit contains support for Borland specific }
{ structures and name unmangling. }
{ }
{ Unit owner: Petr Vones }
{ }
{**************************************************************************************************}
// Last modified: $Date: 2005/03/09 23:52:19 $
// For history see end of file
unit JclPeImage;
{$I jcl.inc}
{$I windowsonly.inc}
interface
uses
Windows, Classes, SysUtils, TypInfo, Contnrs,
JclBase, JclDateTime, JclFileUtils, JclStrings, JclSysInfo, JclWin32;
type
// Smart name compare function
TJclSmartCompOption = (scSimpleCompare, scIgnoreCase);
TJclSmartCompOptions = set of TJclSmartCompOption;
function PeStripFunctionAW(const FunctionName: string): string;
function PeSmartFunctionNameSame(const ComparedName, FunctionName: string;
Options: TJclSmartCompOptions = []): Boolean;
type
// Base list
EJclPeImageError = class(EJclError);
TJclPeImage = class;
TJclPeBorImage = class;
TJclPeImageClass = class of TJclPeImage;
TJclPeImageBaseList = class(TObjectList)
private
FImage: TJclPeImage;
public
constructor Create(AImage: TJclPeImage);
property Image: TJclPeImage read FImage;
end;
// Images cache
TJclPeImagesCache = class(TObject)
private
FList: TStringList;
function GetCount: Integer;
function GetImages(const FileName: TFileName): TJclPeImage;
protected
function GetPeImageClass: TJclPeImageClass; virtual;
public
constructor Create;
destructor Destroy; override;
procedure Clear;
property Images[const FileName: TFileName]: TJclPeImage read GetImages; default;
property Count: Integer read GetCount;
end;
TJclPeBorImagesCache = class(TJclPeImagesCache)
private
function GetImages(const FileName: TFileName): TJclPeBorImage;
protected
function GetPeImageClass: TJclPeImageClass; override;
public
property Images[const FileName: TFileName]: TJclPeBorImage read GetImages; default;
end;
// Import section related classes
TJclPeImportSort = (isName, isOrdinal, isHint, isLibImport);
TJclPeImportLibSort = (ilName, ilIndex);
TJclPeImportKind = (ikImport, ikDelayImport, ikBoundImport);
TJclPeResolveCheck = (icNotChecked, icResolved, icUnresolved);
TJclPeLinkerProducer = (lrBorland, lrMicrosoft);
// lrBorland -> Delphi PE files
// lrMicrosoft -> MSVC and BCB PE files
TJclPeImportLibItem = class;
TJclPeImportFuncItem = class(TObject)
private
FOrdinal: Word;
FHint: Word;
FImportLib: TJclPeImportLibItem;
FName: PChar;
FIndirectImportName: Boolean;
FResolveCheck: TJclPeResolveCheck;
function GetIsByOrdinal: Boolean;
function GetName: string;
protected
procedure SetIndirectImportName(P: PChar);
public
destructor Destroy; override;
property Ordinal: Word read FOrdinal;
property Hint: Word read FHint;
property ImportLib: TJclPeImportLibItem read FImportLib;
property IndirectImportName: Boolean read FIndirectImportName;
property IsByOrdinal: Boolean read GetIsByOrdinal;
property Name: string read GetName;
property ResolveCheck: TJclPeResolveCheck read FResolveCheck;
end;
TJclPeImportLibItem = class(TJclPeImageBaseList)
private
FImportDescriptor: Pointer;
FImportDirectoryIndex: Integer;
FImportKind: TJclPeImportKind;
FLastSortType: TJclPeImportSort;
FLastSortDescending: Boolean;
FName: PChar;
FSorted: Boolean;
FTotalResolveCheck: TJclPeResolveCheck;
FThunk: PImageThunkData;
FThunkData: PImageThunkData;
function GetCount: Integer;
function GetFileName: TFileName;
function GetItems(Index: Integer): TJclPeImportFuncItem;
function GetOriginalName: string;
function GetName: string;
protected
procedure CheckImports(ExportImage: TJclPeImage);
procedure CreateList;
public
constructor Create(AImage: TJclPeImage);
procedure SortList(SortType: TJclPeImportSort; Descending: Boolean = False);
property Count: Integer read GetCount;
property FileName: TFileName read GetFileName;
property ImportDescriptor: Pointer read FImportDescriptor;
property ImportDirectoryIndex: Integer read FImportDirectoryIndex;
property ImportKind: TJclPeImportKind read FImportKind;
property Items[Index: Integer]: TJclPeImportFuncItem read GetItems; default;
property Name: string read GetName;
property OriginalName: string read GetOriginalName;
property ThunkData: PImageThunkData read FThunkData;
property TotalResolveCheck: TJclPeResolveCheck read FTotalResolveCheck;
end;
TJclPeImportList = class(TJclPeImageBaseList)
private
FAllItemsList: TList;
FFilterModuleName: string;
FLastAllSortType: TJclPeImportSort;
FLastAllSortDescending: Boolean;
FLinkerProducer: TJclPeLinkerProducer;
FParalelImportTable: array of Pointer;
FUniqueNamesList: TStringList;
function GetAllItemCount: Integer;
function GetAllItems(Index: Integer): TJclPeImportFuncItem;
function GetItems(Index: Integer): TJclPeImportLibItem;
function GetUniqueLibItemCount: Integer;
function GetUniqueLibItems(Index: Integer): TJclPeImportLibItem;
function GetUniqueLibNames(Index: Integer): string;
function GetUniqueLibItemFromName(const Name: string): TJclPeImportLibItem;
procedure SetFilterModuleName(const Value: string);
protected
procedure CreateList;
procedure RefreshAllItems;
public
constructor Create(AImage: TJclPeImage);
destructor Destroy; override;
procedure CheckImports(PeImageCache: TJclPeImagesCache = nil);
function MakeBorlandImportTableForMappedImage: Boolean;
function SmartFindName(const CompareName, LibName: string; Options: TJclSmartCompOptions = []): TJclPeImportFuncItem;
procedure SortAllItemsList(SortType: TJclPeImportSort; Descending: Boolean = False);
procedure SortList(SortType: TJclPeImportLibSort);
procedure TryGetNamesForOrdinalImports;
property AllItems[Index: Integer]: TJclPeImportFuncItem read GetAllItems;
property AllItemCount: Integer read GetAllItemCount;
property FilterModuleName: string read FFilterModuleName write SetFilterModuleName;
property Items[Index: Integer]: TJclPeImportLibItem read GetItems; default;
property LinkerProducer: TJclPeLinkerProducer read FLinkerProducer;
property UniqueLibItemCount: Integer read GetUniqueLibItemCount;
property UniqueLibItemFromName[const Name: string]: TJclPeImportLibItem read GetUniqueLibItemFromName;
property UniqueLibItems[Index: Integer]: TJclPeImportLibItem read GetUniqueLibItems;
property UniqueLibNames[Index: Integer]: string read GetUniqueLibNames;
end;
// Export section related classes
TJclPeExportSort = (esName, esOrdinal, esHint, esAddress, esForwarded, esAddrOrFwd, esSection);
TJclPeExportFuncList = class;
TJclPeExportFuncItem = class(TObject)
private
FAddress: DWORD;
FExportList: TJclPeExportFuncList;
FForwardedName: PChar;
FForwardedDotPos: PChar;
FHint: Word;
FName: PChar;
FOrdinal: Word;
FResolveCheck: TJclPeResolveCheck;
function GetAddressOrForwardStr: string;
function GetForwardedFuncName: string;
function GetForwardedLibName: string;
function GetForwardedFuncOrdinal: DWORD;
function GetForwardedName: string;
function GetIsExportedVariable: Boolean;
function GetIsForwarded: Boolean;
function GetName: string;
function GetSectionName: string;
function GetMappedAddress: Pointer;
protected
procedure FindForwardedDotPos;
public
property Address: DWORD read FAddress;
property AddressOrForwardStr: string read GetAddressOrForwardStr;
property IsExportedVariable: Boolean read GetIsExportedVariable;
property IsForwarded: Boolean read GetIsForwarded;
property ForwardedName: string read GetForwardedName;
property ForwardedLibName: string read GetForwardedLibName;
property ForwardedFuncOrdinal: DWORD read GetForwardedFuncOrdinal;
property ForwardedFuncName: string read GetForwardedFuncName;
property Hint: Word read FHint;
property MappedAddress: Pointer read GetMappedAddress;
property Name: string read GetName;
property Ordinal: Word read FOrdinal;
property ResolveCheck: TJclPeResolveCheck read FResolveCheck;
property SectionName: string read GetSectionName;
end;
TJclPeExportFuncList = class(TJclPeImageBaseList)
private
FAnyForwards: Boolean;
FBase: DWORD;
FExportDir: PImageExportDirectory;
FForwardedLibsList: TStringList;
FFunctionCount: DWORD;
FLastSortType: TJclPeExportSort;
FLastSortDescending: Boolean;
FSorted: Boolean;
FTotalResolveCheck: TJclPeResolveCheck;
function GetForwardedLibsList: TStrings;
function GetItems(Index: Integer): TJclPeExportFuncItem;
function GetItemFromAddress(Address: DWORD): TJclPeExportFuncItem;
function GetItemFromOrdinal(Ordinal: DWORD): TJclPeExportFuncItem;
function GetItemFromName(const Name: string): TJclPeExportFuncItem;
function GetName: string;
protected
function CanPerformFastNameSearch: Boolean;
procedure CreateList;
property LastSortType: TJclPeExportSort read FLastSortType;
property LastSortDescending: Boolean read FLastSortDescending;
property Sorted: Boolean read FSorted;
public
constructor Create(AImage: TJclPeImage);
destructor Destroy; override;
procedure CheckForwards(PeImageCache: TJclPeImagesCache = nil);
class function ItemName(Item: TJclPeExportFuncItem): string;
function OrdinalValid(Ordinal: DWORD): Boolean;
procedure PrepareForFastNameSearch;
function SmartFindName(const CompareName: string; Options: TJclSmartCompOptions = []): TJclPeExportFuncItem;
procedure SortList(SortType: TJclPeExportSort; Descending: Boolean = False);
property AnyForwards: Boolean read FAnyForwards;
property Base: DWORD read FBase;
property ExportDir: PImageExportDirectory read FExportDir;
property ForwardedLibsList: TStrings read GetForwardedLibsList;
property FunctionCount: DWORD read FFunctionCount;
property Items[Index: Integer]: TJclPeExportFuncItem read GetItems; default;
property ItemFromAddress[Address: DWORD]: TJclPeExportFuncItem read GetItemFromAddress;
property ItemFromName[const Name: string]: TJclPeExportFuncItem read GetItemFromName;
property ItemFromOrdinal[Ordinal: DWORD]: TJclPeExportFuncItem read GetItemFromOrdinal;
property Name: string read GetName;
property TotalResolveCheck: TJclPeResolveCheck read FTotalResolveCheck;
end;
// Resource section related classes
TJclPeResourceKind = (
rtUnknown0,
rtCursorEntry,
rtBitmap,
rtIconEntry,
rtMenu,
rtDialog,
rtString,
rtFontDir,
rtFont,
rtAccelerators,
rtRCData,
rtMessageTable,
rtCursor,
rtUnknown13,
rtIcon,
rtUnknown15,
rtVersion,
rtDlgInclude,
rtUnknown18,
rtPlugPlay,
rtVxd,
rtAniCursor,
rtAniIcon,
rtHmtl,
rtManifest,
rtUserDefined);
TJclPeResourceList = class;
TJclPeResourceItem = class;
TJclPeResourceRawStream = class(TCustomMemoryStream)
public
constructor Create(AResourceItem: TJclPeResourceItem);
function Write(const Buffer; Count: Longint): Longint; override;
end;
TJclPeResourceItem = class(TObject)
private
FEntry: PImageResourceDirectoryEntry;
FImage: TJclPeImage;
FList: TJclPeResourceList;
FLevel: Byte;
FParentItem: TJclPeResourceItem;
FNameCache: string;
function GetDataEntry: PImageResourceDataEntry;
function GetIsDirectory: Boolean;
function GetIsName: Boolean;
function GetLangID: LANGID;
function GetList: TJclPeResourceList;
function GetName: string;
function GetParameterName: string;
function GetRawEntryData: Pointer;
function GetRawEntryDataSize: Integer;
function GetResourceType: TJclPeResourceKind;
function GetResourceTypeStr: string;
protected
function OffsetToRawData(Ofs: DWORD): DWORD;
function Level1Item: TJclPeResourceItem;
function SubDirData: PImageResourceDirectory;
public
constructor Create(AImage: TJclPeImage; AParentItem: TJclPeResourceItem;
AEntry: PImageResourceDirectoryEntry);
destructor Destroy; override;
function CompareName(AName: PChar): Boolean;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -