怎样读取PE文件的引入函数表?不是读内存映像的方式。我找到引入块,就是不能定位到函数名。(100分)

  • 主题发起人 主题发起人 jrycl
  • 开始时间 开始时间
J

jrycl

Unregistered / Unconfirmed
GUEST, unregistred user!
我找的资料上都是先将PE文件映像到内存,然后再用RVA定位到引入表,读取所有引入函数。
我想直接用FILEREAD的方式读磁盘的PE文件,定位到.idata节,用PointerToRawData偏移量来定位到引入函数的位置,可是总是读不到正确位置。卡在这里,哪位高手指点一下!
下面是源程序
pefile:=fileopen('c:/cpinfo.exe',fmOpenRead or fmShareDenyNone);
if pefile<0 then begin
FileClose(pefile);
showmessage('读文件出错!');
exit;
end;
fileread(pefile,dosheader,sizeof(dosheader));
fileseek(pefile,dosheader._lfanew ,soFromBeginning);
fileread(pefile,ntheader,sizeof(ntheader));
SetLength(PESectionheader, NTHeader.FileHeader.NumberOfSections); {块表数}
for i := 0 to NTHeader.FileHeader.NumberOfSections - 1 do begin
if FileRead(pefile, PESectionHeader, SizeOf(PESectionHeader))<>SizeOf(PESectionHeader) then
raise exception.Create('');
s:=pchar(@pesectionheader.Name);
memo1.Lines.add(s);
if s='.idata' then begin //如果是函数引入节
FILESEEK(PEFILE,pesectionheader.PointerToRawData,0);
fileread(pefile,imdll,sizeof(TImageImportDescriptor));
//这里imdll.DLLName是不是就应该是DLL模块的名称了,怎么老是不正确?
//请高手指点一下!!谢谢!
END;
end;
fileclose(pefile);
 
首先按照内存镜像使结果正确,然后按照步骤检查采用直接读取文件方式得到的数据是否正确,调试起来应该不是很复杂。
建立一个可用的东西然后逐步调整,这是在遇到自己不熟悉领域问题时候的比较好的选择,个人以为。
 
介绍PE文件格式的文档已经很多,要读取EXE的引入表,先要了解PE结构。
直接从硬盘读PE文件取引入表有些不可能,最起码你计算不出来RVA地址,从内存映射读取是个方法。具体方法你还得查看相关PE资料。
1.创建文件句柄 CreateFile
2.内存映射 CreateFileMapping
3.查看内存映射 MapViewOfFile
4.校验DOS 头,PE格式
Nt := PImageDosHeader(Dos)^._lfanew;
PImageNtHeaders(NT)^.Signature
5.读取文件节表
6.计算RVA地址
7.读取Import table(引入表)
大致是以上步,就是在6就很难定位计算RVA了。
 
映射进内存我也知道怎么取引入表,这方面的资料也很多...
我就是想以读文件的方式直接取磁盘上.
按照资料上说的节中的PointerToRawData参数就是指节数据在磁盘上的偏移量.为什么取不到呢...
 
请楼主注意
都是指针
有的地方是指针的指针
如果读不出名称
你试试,把读出的4个字节做为指针,再读一次
 
其实不用内存印象也没什么,用TMemoryStream.LoadfromFile(),将文件读入到内存以后,直接使用TMemoryStream.Memory 指针作为内存映像的基地址来用就可以了
 
关注一下
呵呵............
 
记得先在form上放个RichEdit。
==================
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
procedure WithDropFiles(var Msg: TMessage); message WM_DROPFILES;
procedure ShowMsgAlign(s: string; Indent: integer = 0; Align: integer= 34);
procedure ShowMsg(s: string; Indent: integer = 0);
procedure DoDump;
procedure DumpImportTable;
procedure DumpExportTable;
procedure DumpRelocationTable;
procedure DumpDelayImportTable;
procedure DumpBoundImportTable;
procedure DumpCOMTable;
procedure DumpCopyrightTable;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

uses StrUtils, ShellAPI, JwaWinNt;

type
PImageDelayImportDirectory = ^TImageDelayImportDirectory;
TImageDelayImportDirectory = record
Attr: DWORD;
DLLName: DWORD;
Hmod: DWORD;
IAT: DWORD;
INT: DWORD;
BoundIAT: DWORD;
UnloadIAT: DWORD;
TimeDateStamp: DWORD;
end;

type
TImageDirectoryArray = record
RVA: DWORD;
Size: DWORD;
end;

type
TDWORDArray= Array of DWORD;
TWORDArray= Array of WORD;

const
TableArray: Array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1] of string =
('ExportTable', 'ImportTable', 'Resource', 'Exception', 'Security',
'Relocation', 'Debug' ,'Copyright', 'GlobalPtr', 'TLSTable', 'LoadConfig',
'BoundImport' ,'IAT', 'DelayImport', 'COM', 'Reserved');

var
fn: String;
MStream: TMemoryStream;
PPE: Pointer;
PFileHeader: PImageFileHeader;
POptionalHeader32: PImageOptionalHeader32;
PDataDirectory: JwaWinNt.PImageDataDirectory;
PSectionHeader: PImageSectionHeader;
DirectoryArray: Array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1] of TImageDirectoryArray;
PImportDecriptor: PImageImportDecriptor;
PExportDirectory: PImageExportDirectory;
PBaseRelocation: PImageBaseRelocation;
DelayImportDirectory: PImageDelayImportDirectory;
PBoundImportDescriptor: PImageBoundImportDescriptor;
PCor20Header: PImageCor20Header;

procedure TForm1.WithDropFiles(var Msg: TMessage);
Var
Buffer: PChar;
i: integer;
begin
i := DragQueryFile( Msg.WParam, 0, nil, 0) + 1;
GetMem(Buffer, i);
try
DragQueryFile(Msg.WParam, 0, Buffer, i);
MStream.Clear;
RichEdit1.Clear;
fn := Buffer;
MStream.LoadFromFile(fn);
DoDump;
SendMessage(Richedit1.Handle, WM_VSCROLL, SB_BOTTOM, 0);
DragFinish(Msg.WParam);
SetForegroundWindow(Handle);
Richedit1.SetFocus;
finally
FreeMem(Buffer);
end;
end;

procedure TForm1.ShowMsg(s: string; Indent: integer = 0);
begin
RichEdit1.Lines.Add(DupeString(' ', Indent) + s);
end;

procedure TForm1.ShowMsgAlign(s: string; Indent: integer = 0; Align: integer= 34);
var
j: integer;
s1: string;
begin
j := pos(';', s);
s1 := LeftStr(s, j - 1) + DupeString(' ', Align - Indent - j) + RightStr(s, length(s) - j);
RichEdit1.Lines.Add(DupeString(' ', Indent) + s1);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
fn := 'explorer.exe';
DragAcceptFiles(Handle, true);
MStream := TMemoryStream.Create;
MStream.LoadFromFile(fn);
DoDump;
SendMessage(Richedit1.Handle, WM_VSCROLL, SB_BOTTOM, 0);
end;

function RVAtoOffset(RVA: Integer): DWORD;
var
i: integer;
PTmpSectionHeader: PImageSectionHeader;
begin
i := 0;
PTmpSectionHeader := PImageSectionHeader(DWORD(POptionalHeader32) + PFileHeader^.SizeOfOptionalHeader);
result := RVA;
while i < PFileHeader^.NumberOfSections do
begin
inc(i);
if (RVA >= PTmpSectionHeader.VirtualAddress) and
(RVA - PTmpSectionHeader.VirtualAddress < PTmpSectionHeader^.Misc.VirtualSize) then
begin
result := RVA - PTmpSectionHeader.VirtualAddress + PTmpSectionHeader.PointerToRawData;
break;
end;
inc(DWORD(PTmpSectionHeader), IMAGE_SIZEOF_SECTION_HEADER);
end;
end;

procedure TForm1.DumpImportTable;
var
i, j: integer;
PFuncName: PImageImportByName;
begin
ShowMsg(DupeString('=', 21) + 'Import Section' + DupeString('=', 21));
if DirectoryArray[IMAGE_DIRECTORY_ENTRY_IMPORT].RVA = 0 then
begin
ShowMsg('No import function found!');
exit;
end;
PImportDecriptor := PImageImportDecriptor(DWORD(PPE) + RVAtoOffset(DirectoryArray[IMAGE_DIRECTORY_ENTRY_IMPORT].RVA));
i := 1;
while (PImportDecriptor^.Union.OriginalFirstThunk <> 0) or (PImportDecriptor^.TimeDateStamp <> 0) or
(PImportDecriptor^.ForwarderChain <> 0) or (PImportDecriptor^.Name <> 0) or (PImportDecriptor^.FirstThunk <> 0) do
begin
ShowMsg(inttostr(i) + '. ImageImportDescriptor:');
ShowMsgAlign('OriginalFirstThunk;' + inttohex(PImportDecriptor^.Union.OriginalFirstThunk, 8), 3);
if PImportDecriptor^.TimeDateStamp = 0 then
ShowMsgAlign('TimeDateStamp;' + inttohex(PImportDecriptor^.TimeDateStamp, 8), 3)
else
ShowMsgAlign('TimeDateStamp;' + inttohex(PImportDecriptor^.TimeDateStamp, 8) + ' (Bound)', 3);
if (PImportDecriptor^.ForwarderChain = 0) or (PImportDecriptor^.ForwarderChain = $FFFFFFFF) then
ShowMsgAlign('ForwarderChain;' + inttohex(PImportDecriptor^.ForwarderChain, 8), 3)
else
ShowMsgAlign('ForwarderChain;' + inttohex(PImportDecriptor^.ForwarderChain, 8) + ' (Forwarder)', 3);
ShowMsgAlign('Dll name;' + inttohex(PImportDecriptor^.Name, 8) + ' ("'+
PChar(DWORD(PPE) + RVAtoOffset(PImportDecriptor^.Name)) +
'")', 3);
ShowMsgAlign('FirstThunk;' + inttohex(PImportDecriptor^.FirstThunk, 8), 3);
//Loader 会依OriginalFirstThunk(或FirstThunk)指向的函数的顺序填充FirstThunk指向的DWORD,以全零结束。
//即,load后,FirstThunk不再是指向函数名的指针,而是指向函数的地址序列。
ShowMsg('');
ShowMsg('Ordinal/Hint API name', 3);
ShowMsg('------------ ' + DupeString('-', 20), 3);
if PImportDecriptor^.Union.OriginalFirstThunk <> 0 then
j := DWORD(PPE) + RVAtoOffset(PImportDecriptor^.Union.OriginalFirstThunk)
else
j := DWORD(PPE) + RVAtoOffset(PImportDecriptor^.FirstThunk);
while PDWORD(j)^ <> 0 do
begin
if PDWORD(j)^ and IMAGE_ORDINAL_FLAG32 = 0 then
begin
PFuncName := PImageImportByName(DWORD(PPE) + RVAtoOffset(PDWORD(j)^));
ShowMsgAlign('0x' + inttohex(PFuncName^.Hint, 4) + ';"' + PChar(@PFuncName^.Name) + '"', 3, 13);
end
else
begin
ShowMsgAlign('0x' + inttohex(PDWORD(j)^ and $7FFFFFFF, 4) + ';(Ordinal only)', 3, 13);
end;
inc(j, 4);
end;
ShowMsg('');
inc(i);
inc(PImportDecriptor);
end;
end;

procedure TForm1.DumpExportTable;
var
i, j: Cardinal;
ExpFuncAddr: TDWORDArray;
ExpFuncName: TDWORDArray;
ExpFuncOrdinal: TWORDArray;
TmpPchar: string;
ExpNameFound: Boolean;
begin
ShowMsg('');
ShowMsg(DupeString('=', 21) + 'Export Section' + DupeString('=', 21));
if DirectoryArray[IMAGE_DIRECTORY_ENTRY_EXPORT].RVA = 0 then
begin
ShowMsg('No export function found!');
exit;
end;
PExportDirectory := PImageExportDirectory(DWORD(PPE) + RVAtoOffset(DirectoryArray[IMAGE_DIRECTORY_ENTRY_EXPORT].RVA));
ShowMsgAlign('Characteristics;0x' + inttohex(PExportDirectory^.Characteristics, 8), 3);
ShowMsgAlign('TimeDateStamp;0x' + inttohex(PExportDirectory^.TimeDateStamp, 8), 3);
ShowMsgAlign('MajorVersion;0x' + inttohex(PExportDirectory^.MajorVersion, 8), 3);
ShowMsgAlign('MinorVersion;0x' + inttohex(PExportDirectory^.MinorVersion, 8), 3);
ShowMsgAlign('Name;0x' + inttohex(PExportDirectory^.Name, 8) + '"(' +
PChar(DWORD(PPE) + RVAtoOffset(PExportDirectory^.Name)) + '")', 3);
ShowMsgAlign('Base;0x' + inttohex(PExportDirectory^.Base, 8), 3);
ShowMsgAlign('NumberOfFunctions;0x' + inttohex(PExportDirectory^.NumberOfFunctions, 8), 3);
ShowMsgAlign('NumberOfNames;0x' + inttohex(PExportDirectory^.NumberOfNames, 8), 3);
ShowMsgAlign('AddressOfFunctions;0x' + inttohex(PExportDirectory^.AddressOfFunctions, 8), 3);
ShowMsgAlign('AddressOfNames;0x' + inttohex(PExportDirectory^.AddressOfNames, 8), 3);
ShowMsgAlign('AddressOfNameOrdinals;0x' + inttohex(PExportDirectory^.AddressOfNameOrdinals, 8), 3);
ShowMsg('');
ShowMsg('Ordinal' + DupeString(' ', 2) + 'RVA' + DupeString(' ', 8) + 'Symbol Name', 3);
ShowMsg('--------' + DupeString(' ', 1) + '----------' + DupeString(' ', 1) + DupeString('-', 15), 3);
DWORD(ExpFuncAddr) := DWORD(PPE) + RVAtoOffset(PExportDirectory^.AddressOfFunctions);
DWORD(ExpFuncName) := DWORD(PPE) + RVAtoOffset(PExportDirectory^.AddressOfNames);
DWORD(ExpFuncOrdinal) := DWORD(PPE) + RVAtoOffset(PExportDirectory^.AddressOfNameOrdinals);
for i := 0 to PExportDirectory^.NumberOfFunctions - 1 do
begin
if (ExpFuncAddr <> 0) then
begin
TmpPchar := 'n/a';
ExpNameFound := false;
for j := 0 to PExportDirectory^.NumberOfNames - 1 do
if ExpFuncOrdinal[j] = i then
begin
TmpPchar := PChar(DWORD(PPE) + RVAtoOffset(ExpFuncName[j]));
ExpNameFound := true;
break;
end;
if (ExpFuncAddr >= DirectoryArray[0].RVA) and
(ExpFuncAddr < DirectoryArray[0].RVA + DirectoryArray[0].Size) then
begin
TmpPchar := TmpPchar + ' (Forward)';
end; // Forward ?
if ExpNameFound then
ShowMsg('0x' + inttohex(ExpFuncOrdinal[j] + PExportDirectory^.Base, 4) + ' 0x' +
inttohex(ExpFuncAddr, 8) + ' "' + TmpPchar + '"', 3)
else
ShowMsg('0x' + inttohex(i + PExportDirectory^.Base, 4) + ' 0x' +
inttohex(ExpFuncAddr, 8) + ' "' + TmpPchar + '"', 3);
end;
end;
end;

procedure TForm1.DumpRelocationTable;
var
i, j, k: integer;
RelArray: TWORDArray;
begin
ShowMsg('');
ShowMsg(DupeString('=', 21) + 'Reloction Section' + DupeString('=', 21));
if DirectoryArray[IMAGE_DIRECTORY_ENTRY_BASERELOC ].RVA = 0 then
begin
ShowMsg('Reloction table not found!');
exit;
end;

ShowMsg('to display relocation table will take too much time! SKIPPED!');
exit;

Richedit1.Lines.BeginUpdate;
PBaseRelocation := PImageBaseRelocation(DWORD(PPE) + RVAtoOffset(DirectoryArray[IMAGE_DIRECTORY_ENTRY_BASERELOC].RVA));
j := 1;
k := DirectoryArray[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
while k > 0 do
begin
DWORD(RelArray) := DWORD(PBaseRelocation) + 2 * SizeOf(DWORD);
ShowMsgAlign(inttostr(j) + '. Relocation block:;');
ShowMsgAlign('RVA;' + inttohex(PBaseRelocation^.VirtualAddress, 8), 3);
ShowMsgAlign('Size;' + inttohex(PBaseRelocation^.SizeOfBlock, 8), 3);
ShowMsg('Offset TYPE', 3);
ShowMsg('------------ ' + DupeString('-', 20), 3);
for i := 0 to (PBaseRelocation^.SizeOfBlock - 2 * SizeOf(DWORD)) div 2 - 1 do
begin
if (RelArray shr 12) = IMAGE_REL_BASED_HIGHLOW then
begin
ShowMsgAlign('0x' + inttohex(RelArray and $0FFF, 4) + ';HIGHLOW', 3, 17);
end;
end;
dec(k, PBaseRelocation^.SizeOfBlock);
inc(j);
inc(DWORD(PBaseRelocation), PBaseRelocation^.SizeOfBlock);
end;
Richedit1.Lines.EndUpdate;
end;

procedure TForm1.DumpDelayImportTable;
var
i, j: integer;
PFuncName: PImageImportByName;
begin
ShowMsg('');
ShowMsg(DupeString('=', 21) + 'DelayImport Table' + DupeString('=', 21));
if DirectoryArray[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT ].RVA = 0 then
begin
ShowMsg('DelayImport table not found!');
exit;
end;
DelayImportDirectory := PImageDelayImportDirectory(DWORD(PPE) + RVAtoOffset(DirectoryArray[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].RVA));
i := 1;
while DelayImportDirectory^.DLLName <> 0 do
begin
ShowMsgAlign(inttostr(i) + '. DelayImportDescriptor:;');
ShowMsgAlign('Attributes;' + inttohex(DelayImportDirectory^.Attr, 8), 3);
ShowMsgAlign('Dll name;' + inttohex(DelayImportDirectory^.DLLName, 8) + ' "' +
PChar(DWORD(PPE) + RVAtoOffset(DelayImportDirectory^.DLLName - POptionalHeader32^.ImageBase)) + '"', 3);
ShowMsgAlign('hMod;' + inttohex(DelayImportDirectory^.Hmod, 8), 3);
ShowMsgAlign('IAT;' + inttohex(DelayImportDirectory^.IAT, 8), 3);
ShowMsgAlign('INT;' + inttohex(DelayImportDirectory^.INT, 8), 3);
ShowMsgAlign('BoundIAT;' + inttohex(DelayImportDirectory^.BoundIAT, 8), 3);
ShowMsgAlign('UnloadIAT;' + inttohex(DelayImportDirectory^.UnloadIAT, 8), 3);
ShowMsgAlign('TimeDateStamp;' + inttohex(DelayImportDirectory^.TimeDateStamp, 8), 3);

ShowMsg('');
ShowMsg('Ordinal/Hint API name', 3);
ShowMsg('------------ ' + DupeString('-', 20), 3);
j := DWORD(PPE) + RVAtoOffset(DelayImportDirectory^.INT - POptionalHeader32^.ImageBase);
while PDWORD(j)^ <> 0 do
begin
PFuncName := PImageImportByName(DWORD(PPE) + RVAtoOffset(PDWORD(j)^ - POptionalHeader32^.ImageBase));
if PDWORD(j)^ and IMAGE_ORDINAL_FLAG32 = 0 then
begin
ShowMsgAlign('0x' + inttohex(PFuncName^.Hint, 4) + ';"' + PChar(@PFuncName^.Name) + '"', 3, 13);
end
else
begin
ShowMsgAlign('0x' + inttohex(PDWORD(j)^ and $7FFFFFFF, 4) + ';(Ordinal only)', 3, 13);
end;
inc(j, 4);
end;
ShowMsg('');
inc(i);
inc(DelayImportDirectory);
end;
end;

procedure TForm1.DumpBoundImportTable;
var
i, j: integer;
bid: DWORD;
begin
ShowMsg('');
ShowMsg(DupeString('=', 21) + 'BoundImport Table' + DupeString('=', 21));
if DirectoryArray[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ].RVA = 0 then
begin
ShowMsg('BoundImport table not found!');
exit;
end;
PBoundImportDescriptor := PImageBoundImportDescriptor(DWORD(PPE) + RVAtoOffset(DirectoryArray[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].RVA));
bid := DWORD(PBoundImportDescriptor);
j := 1;
while PBoundImportDescriptor^.TimeDateStamp <> 0 do
begin
ShowMsgAlign(inttostr(j) + '. Bound Import Descriptor:;');
ShowMsgAlign('TimeDateStamp;' + inttohex(PBoundImportDescriptor^.TimeDateStamp, 8), 3);
ShowMsgAlign('Dll name;' + inttohex(PBoundImportDescriptor^.OffsetModuleName, 8) + ' "' +
PChar(bid + PBoundImportDescriptor^.OffsetModuleName) + '"', 3);
ShowMsgAlign('NumberOfModuleForwarderRefs;' + inttohex(PBoundImportDescriptor^.NumberOfModuleForwarderRefs, 8), 3);
for i := 0 to PBoundImportDescriptor^.NumberOfModuleForwarderRefs - 1 do
begin
inc(PBoundImportDescriptor);
ShowMsgAlign(inttostr(i) + '. TimeDateStamp;' + inttohex(PBoundImportDescriptor^.TimeDateStamp, 8),3);
ShowMsgAlign('Dll name;' + inttohex(PBoundImportDescriptor^.OffsetModuleName, 8) + ' "' +
PChar(DWORD(bid) + PBoundImportDescriptor^.OffsetModuleName) + '"', 6);
ShowMsgAlign('Resversed;' + inttohex(PBoundImportDescriptor^.NumberOfModuleForwarderRefs, 8), 6);
end;
ShowMsg('');
inc(j);
inc(PBoundImportDescriptor);
end;
end;

procedure TForm1.DumpCOMTable;
begin
ShowMsg('');
ShowMsg(DupeString('=', 21) + 'COM Table' + DupeString('=', 21));
if DirectoryArray[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR ].RVA = 0 then
begin
ShowMsg('COM table not found!');
exit;
end;
PCor20Header := PImageCor20Header(DWORD(PPE) + RVAtoOffset(DirectoryArray[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].RVA));
ShowMsgAlign('COM table Descriptor:;');
ShowMsgAlign('cb;' + inttohex(PCor20Header^.cb, 8), 3);
ShowMsgAlign('MajorRuntimeVersion;' + inttohex(PCor20Header^.MajorRuntimeVersion, 8), 3);
ShowMsgAlign('MinorRuntimeVersion;' + inttohex(PCor20Header^.MinorRuntimeVersion, 8), 3);
ShowMsgAlign('MetaData.VirtualAddress;' + inttohex(PCor20Header^.MetaData.VirtualAddress, 8), 3);
ShowMsgAlign('MetaData.Size;' + inttohex(PCor20Header^.MetaData.Size, 8), 3);
ShowMsgAlign('Flags;' + inttohex(PCor20Header^.Flags, 8), 3);
ShowMsgAlign('EntryPointToken;' + inttohex(PCor20Header^.EntryPointToken, 8), 3);
ShowMsg('');
ShowMsgAlign('Resources.VirtualAddress;' + inttohex(PCor20Header^.Resources.VirtualAddress, 8), 3);
ShowMsgAlign('Resources.Size;' + inttohex(PCor20Header^.Resources.Size, 8), 3);
ShowMsgAlign('StrongNameSignature.VirtualAddress;' + inttohex(PCor20Header^.StrongNameSignature.VirtualAddress, 8), 3);
ShowMsgAlign('StrongNameSignature.Size;' + inttohex(PCor20Header^.StrongNameSignature.Size, 8), 3);
ShowMsgAlign('CodeManagerTable.VirtualAddress;' + inttohex(PCor20Header^.CodeManagerTable.VirtualAddress, 8), 3);
ShowMsgAlign('CodeManagerTable.Size;' + inttohex(PCor20Header^.CodeManagerTable.Size, 8), 3);
ShowMsgAlign('VTableFixups.VirtualAddress;' + inttohex(PCor20Header^.VTableFixups.VirtualAddress, 8), 3);
ShowMsgAlign('VTableFixups.Size;' + inttohex(PCor20Header^.VTableFixups.Size, 8), 3);
ShowMsgAlign('ExportAddressTableJumps.VirtualAddress;' + inttohex(PCor20Header^.ExportAddressTableJumps.VirtualAddress, 8), 3);
ShowMsgAlign('ExportAddressTableJumps.Size;' + inttohex(PCor20Header^.ExportAddressTableJumps.Size, 8), 3);
ShowMsgAlign('ManagedNativeHeader.VirtualAddress;' + inttohex(PCor20Header^.ManagedNativeHeader.VirtualAddress, 8), 3);
ShowMsgAlign('ManagedNativeHeader.Size;' + inttohex(PCor20Header^.ManagedNativeHeader.Size, 8), 3);
end;

procedure TForm1.DumpCopyrightTable;
var
ptr: Pointer;
s: string;
begin
ShowMsg('');
ShowMsg(DupeString('=', 21) + 'Copyright Table' + DupeString('=', 21));
if DirectoryArray[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE ].RVA = 0 then
begin
ShowMsg('Copyright table not found!');
exit;
end;
ptr := Pointer(DWORD(PPE) + RVAtoOffset(DirectoryArray[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].RVA));
s := copy(PChar(ptr), 0, DirectoryArray[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].Size);
ShowMsg('Copyright info:');
ShowMsg(s, 3);
end;

procedure TForm1.DoDump;
var
i: integer;
ScetionName: String[8];
begin
Caption := fn;
PPE := MStream.Memory;
if MStream.Size = 0 then
begin
Showmessage('0 file!');
exit;
end;
if (PImageDosHeader(PPE)^.e_magic <> $5A4D) then
begin
Showmessage('Invalid PE file!');
exit;
end;
if (PDWORD(Longint(PPE) + PImageDosHeader(PPE)^.e_lfanew)^ <> $4550) then
begin
Showmessage('Invalid PE file!');
exit;
end;
ShowMsgAlign('DosHeader e-magic;0x' + inttohex(PImageDosHeader(PPE)^.e_magic, 4));
ShowMsg(DupeString('-', 56));
PFileHeader := PImageFileHeader(Longint(PPE) + PImageDosHeader(PPE)^.e_lfanew + 4);
ShowMsgAlign('PE Signature;0x' + inttohex(PDWORD(Longint(PPE) + PImageDosHeader(PPE)^.e_lfanew)^, 4));
ShowMsgAlign('NumberOfSections;0x' + inttohex(PFileHeader^.NumberOfSections, 4));
ShowMsg(DupeString('-', 56));
POptionalHeader32 := PImageOptionalHeader32(DWORD(PFileHeader) + IMAGE_SIZEOF_FILE_HEADER);
ShowMsgAlign('OptionalHeader magic;0x' + inttohex(POptionalHeader32^.Magic, 4));
ShowMsgAlign('SectionAlignment;0x' + inttohex(POptionalHeader32^.SectionAlignment, 4));
ShowMsgAlign('FileAlignment;0x' + inttohex(POptionalHeader32^.FileAlignment, 4));
ShowMsgAlign('NUMBEROF_DIRECTORY_ENTRIES;0x' + inttohex(POptionalHeader32^.NumberOfRvaAndSizes, 4));
ShowMsg('');
PDataDirectory := PImageDataDirectory(@POptionalHeader32^.DataDirectory[0]);
ShowMsg('DataDirectory (0x10)' + DupeString(' ', 16) + 'RVA' + DupeString(' ', 9) + 'Size');
ShowMsg('------------------' + DupeString(' ', 16) + '----------' + DupeString(' ', 2) + '----------');
for i := 0 to IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 do
begin
ShowMsgAlign(TableArray + ';0x' + inttohex(PDataDirectory^.VirtualAddress, 8) +
' 0x' + inttohex(PDataDirectory^.Size, 8));
DirectoryArray.RVA := PDataDirectory^.VirtualAddress;
DirectoryArray.Size := PDataDirectory^.Size;
inc(DWORD(PDataDirectory), SizeOf(TImageDataDirectory));
end;
ShowMsg(DupeString('-', 56));
PSectionHeader := PImageSectionHeader(DWORD(POptionalHeader32) + PFileHeader^.SizeOfOptionalHeader);
for i := 0 to PFileHeader^.NumberOfSections - 1 do
begin
ScetionName := Copy(PChar(@PSectionHeader^.Name), 1, 8);
ShowMsgAlign('Section Name;' + ScetionName);
ShowMsgAlign('VOffset;' + inttohex(PSectionHeader^.VirtualAddress, 8), 2);
ShowMsgAlign('VSize;' + inttohex(PSectionHeader^.Misc.VirtualSize, 8), 2);
ShowMsgAlign('ROffset(in file);' + inttohex(PSectionHeader^.PointerToRawData, 8), 2);
ShowMsgAlign('RSize (in file);' + inttohex(PSectionHeader^.SizeOfRawData, 8), 2);
ShowMsgAlign('Characteristics;' + inttohex(PSectionHeader^.Characteristics, 8), 2);
ShowMsg('');
inc(DWORD(PSectionHeader), IMAGE_SIZEOF_SECTION_HEADER);
end;
//--------------------------------------------------------------------------------
DumpImportTable;
//--------------------------------------------------------------------------------
DumpExportTable;
//--------------------------------------------------------------------------------
DumpRelocationTable;
//--------------------------------------------------------------------------------
DumpDelayImportTable;
//--------------------------------------------------------------------------------
DumpBoundImportTable;
//--------------------------------------------------------------------------------
DumpCOMTable;
//--------------------------------------------------------------------------------
DumpCopyrightTable;

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
MStream.Free;
end;

end.
 
后退
顶部