📄 jclpeimage.pas
字号:
if PeImageCache <> nil then
ExportPeImage := PeImageCache[Items[I].FileName]
else
ExportPeImage.FileName := Items[I].FileName;
ExportPeImage.ExportList.PrepareForFastNameSearch;
Items[I].CheckImports(ExportPeImage);
end;
finally
if PeImageCache = nil then
ExportPeImage.Free;
end;
end;
procedure TJclPeImportList.CreateList;
var
ImportDesc: PImageImportDescriptor;
LibItem: TJclPeImportLibItem;
DelayImportDesc: PImgDelayDescr;
BoundImports, BoundImport: PImageBoundImportDescriptor;
S: string;
I: Integer;
begin
SetCapacity(100);
with Image do
begin
if not StatusOK then
Exit;
ImportDesc := DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_IMPORT);
if ImportDesc <> nil then
while ImportDesc^.Name <> 0 do
begin
LibItem := TJclPeImportLibItem.Create(Image);
LibItem.FImportDescriptor := ImportDesc;
LibItem.FName := RvaToVa(ImportDesc^.Name);
LibItem.FImportKind := ikImport;
if ImportDesc^.Union.Characteristics = 0 then
begin
if FAttachedImage then // Borland images doesn't have two paralel arrays
LibItem.FThunk := nil // see MakeBorlandImportTableForMappedImage method
else
LibItem.FThunk := PImageThunkData(RvaToVa(ImportDesc^.FirstThunk));
FLinkerProducer := lrBorland;
end
else
begin
LibItem.FThunk := PImageThunkData(RvaToVa(ImportDesc^.Union.Characteristics));
FLinkerProducer := lrMicrosoft;
end;
LibItem.FThunkData := LibItem.FThunk;
Add(LibItem);
FUniqueNamesList.AddObject(AnsiLowerCase(LibItem.Name), LibItem);
Inc(ImportDesc);
end;
DelayImportDesc := DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
if DelayImportDesc <> nil then
begin
while DelayImportDesc^.szName <> 0 do
begin
LibItem := TJclPeImportLibItem.Create(Image);
LibItem.FImportKind := ikDelayImport;
LibItem.FImportDescriptor := DelayImportDesc;
LibItem.FName := RvaToVaEx(DelayImportDesc^.szName);
LibItem.FThunk := PImageThunkData(RvaToVaEx(DelayImportDesc^.pINT.AddressOfData));
Add(LibItem);
FUniqueNamesList.AddObject(AnsiLowerCase(LibItem.Name), LibItem);
Inc(DelayImportDesc);
end;
end;
BoundImports := DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT);
if BoundImports <> nil then
begin
BoundImport := BoundImports;
while BoundImport^.OffsetModuleName <> 0 do
begin
S := AnsiLowerCase(PChar(DWORD(BoundImports) + BoundImport^.OffsetModuleName));
I := FUniqueNamesList.IndexOf(S);
if I >= 0 then
TJclPeImportLibItem(FUniqueNamesList.Objects[I]).FImportKind := ikBoundImport;
for I := 1 to BoundImport^.NumberOfModuleForwarderRefs do
Inc(PImageBoundForwarderRef(BoundImport)); // skip forward information
Inc(BoundImport);
end;
end;
end;
for I := 0 to Count - 1 do
Items[I].FImportDirectoryIndex := I;
end;
function TJclPeImportList.GetAllItemCount: Integer;
begin
Result := FAllItemsList.Count;
if Result = 0 then // we haven't created the list yet -> create unsorted list
begin
RefreshAllItems;
Result := FAllItemsList.Count;
end;
end;
function TJclPeImportList.GetAllItems(Index: Integer): TJclPeImportFuncItem;
begin
Result := TJclPeImportFuncItem(FAllItemsList[Index]);
end;
function TJclPeImportList.GetItems(Index: Integer): TJclPeImportLibItem;
begin
Result := TJclPeImportLibItem(Get(Index));
end;
function TJclPeImportList.GetUniqueLibItemCount: Integer;
begin
Result := FUniqueNamesList.Count;
end;
function TJclPeImportList.GetUniqueLibItemFromName(const Name: string): TJclPeImportLibItem;
var
I: Integer;
begin
I := FUniqueNamesList.IndexOf(Name);
if I = -1 then
Result := nil
else
Result := TJclPeImportLibItem(FUniqueNamesList.Objects[I]);
end;
function TJclPeImportList.GetUniqueLibItems(Index: Integer): TJclPeImportLibItem;
begin
Result := TJclPeImportLibItem(FUniqueNamesList.Objects[Index]);
end;
function TJclPeImportList.GetUniqueLibNames(Index: Integer): string;
begin
Result := FUniqueNamesList[Index];
end;
function TJclPeImportList.MakeBorlandImportTableForMappedImage: Boolean;
var
FileImage: TJclPeImage;
I, TableSize: Integer;
begin
if FImage.FAttachedImage and (FLinkerProducer = lrBorland) and
(Length(FParalelImportTable) = 0) then
begin
FileImage := TJclPeImage.Create(True);
try
FileImage.FileName := FImage.FileName;
Result := FileImage.StatusOK;
if Result then
begin
SetLength(FParalelImportTable, FileImage.ImportList.Count);
for I := 0 to FileImage.ImportList.Count - 1 do
begin
Assert(Items[I].ImportKind = ikImport); // Borland doesn't have Delay load or Bound imports
TableSize := (FileImage.ImportList[I].Count + 1) * SizeOf(TImageThunkData);
GetMem(FParalelImportTable[I], TableSize);
System.Move(FileImage.ImportList[I].ThunkData^, FParalelImportTable[I]^, TableSize);
Items[I].FThunk := FParalelImportTable[I];
end;
end;
finally
FileImage.Free;
end;
end
else
Result := True;
end;
procedure TJclPeImportList.RefreshAllItems;
var
L, I: Integer;
LibItem: TJclPeImportLibItem;
begin
FAllItemsList.Clear;
for L := 0 to Count - 1 do
begin
LibItem := Items[L];
if (Length(FFilterModuleName) = 0) or (AnsiCompareText(LibItem.Name, FFilterModuleName) = 0) then
for I := 0 to LibItem.Count - 1 do
FAllItemsList.Add(LibItem[I]);
end;
end;
procedure TJclPeImportList.SetFilterModuleName(const Value: string);
begin
if (FFilterModuleName <> Value) or (FAllItemsList.Count = 0) then
begin
FFilterModuleName := Value;
RefreshAllItems;
FAllItemsList.Sort(GetImportSortFunction(FLastAllSortType, FLastAllSortDescending));
end;
end;
function TJclPeImportList.SmartFindName(const CompareName, LibName: string;
Options: TJclSmartCompOptions): TJclPeImportFuncItem;
var
L, I: Integer;
LibItem: TJclPeImportLibItem;
begin
Result := nil;
for L := 0 to Count - 1 do
begin
LibItem := Items[L];
if (Length(LibName) = 0) or (AnsiCompareText(LibItem.Name, LibName) = 0) then
for I := 0 to LibItem.Count - 1 do
if PeSmartFunctionNameSame(CompareName, LibItem[I].Name, Options) then
begin
Result := LibItem[I];
Break;
end;
end;
end;
procedure TJclPeImportList.SortAllItemsList(SortType: TJclPeImportSort; Descending: Boolean);
begin
GetAllItemCount; // create list if it wasn't created
FAllItemsList.Sort(GetImportSortFunction(SortType, Descending));
FLastAllSortType := SortType;
FLastAllSortDescending := Descending;
end;
procedure TJclPeImportList.SortList(SortType: TJclPeImportLibSort);
begin
Sort(GetImportLibSortFunction(SortType));
end;
procedure TJclPeImportList.TryGetNamesForOrdinalImports;
var
LibNamesList: TStringList;
L, I: Integer;
LibPeDump: TJclPeImage;
procedure TryGetNames(const ModuleName: string);
var
Item: TJclPeImportFuncItem;
I, L: Integer;
ImportLibItem: TJclPeImportLibItem;
ExportItem: TJclPeExportFuncItem;
ExportList: TJclPeExportFuncList;
begin
if FImage.FAttachedImage then
LibPeDump.AttachLoadedModule(GetModuleHandle(PChar(ModuleName)))
else
LibPeDump.FileName := FImage.ExpandModuleName(ModuleName);
if not LibPeDump.StatusOK then
Exit;
ExportList := LibPeDump.ExportList;
for L := 0 to Count - 1 do
begin
ImportLibItem := Items[L];
if AnsiCompareText(ImportLibItem.Name, ModuleName) = 0 then
begin
for I := 0 to ImportLibItem.Count - 1 do
begin
Item := ImportLibItem[I];
if Item.IsByOrdinal then
begin
ExportItem := ExportList.ItemFromOrdinal[Item.Ordinal];
if (ExportItem <> nil) and (ExportItem.FName <> nil) then
Item.SetIndirectImportName(ExportItem.FName);
end;
end;
ImportLibItem.FSorted := False;
end;
end;
end;
begin
LibNamesList := TStringList.Create;
try
LibNamesList.Sorted := True;
LibNamesList.Duplicates := dupIgnore;
for L := 0 to Count - 1 do
with Items[L] do
for I := 0 to Count - 1 do
if Items[I].IsByOrdinal then
LibNamesList.Add(AnsiUpperCase(Name));
LibPeDump := TJclPeImage.Create(True);
try
for I := 0 to LibNamesList.Count - 1 do
TryGetNames(LibNamesList[I]);
finally
LibPeDump.Free;
end;
SortAllItemsList(FLastAllSortType, FLastAllSortDescending);
finally
LibNamesList.Free;
end;
end;
//=== { TJclPeExportFuncItem } ===============================================
procedure TJclPeExportFuncItem.FindForwardedDotPos;
begin
if (FForwardedName <> nil) and (FForwardedDotPos = nil) then
FForwardedDotPos := StrPos(FForwardedName, '.');
end;
function TJclPeExportFuncItem.GetAddressOrForwardStr: string;
begin
if IsForwarded then
Result := ForwardedName
else
FmtStr(Result, '%.8x', [Address]);
end;
function TJclPeExportFuncItem.GetForwardedFuncName: string;
begin
FindForwardedDotPos;
if (FForwardedDotPos <> nil) and (FForwardedDotPos + 1 <> '#') then
Result := PChar(FForwardedDotPos + 1)
else
Result := '';
end;
function TJclPeExportFuncItem.GetForwardedFuncOrdinal: DWORD;
begin
FindForwardedDotPos;
if (FForwardedDotPos <> nil) and (FForwardedDotPos + 1 = '#') then
Result := StrToIntDef(FForwardedDotPos + 2, 0)
else
Result := 0;
end;
function TJclPeExportFuncItem.GetForwardedLibName: string;
begin
FindForwardedDotPos;
if FForwardedDotPos = nil then
Result := ''
else
begin
SetString(Result, FForwardedName, FForwardedDotPos - FForwardedName);
Result := AnsiLowerCase(Result) + '.dll';
end;
end;
function TJclPeExportFuncItem.GetForwardedName: string;
begin
Result := FForwardedName;
end;
function TJclPeExportFuncItem.GetIsExportedVariable: Boolean;
begin
Result := (Address >= FExportList.FImage.OptionalHeader.BaseOfData);
end;
function TJclPeExportFuncItem.GetIsForwarded: Boolean;
begin
Result := FForwardedName <> nil;
end;
function TJclPeExportFuncItem.GetMappedAddress: Pointer;
begin
Result := FExportList.FImage.RvaToVa(FAddress);
end;
function TJclPeExportFuncItem.GetName: string;
begin
Result := FName;
end;
function TJclPeExportFuncItem.GetSectionName: string;
begin
if IsForwarded then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -