📄 unit1.pas
字号:
{ begin datadirectory }
Caption:=Format('%s 正在分析数据目录...',[Application.Title]);
ProgressBar1.Position:=5;
for i:=0 to IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1 do
begin
case i of
0: TmpStr:='Export Directory ';
1: TmpStr:='Import Directory ';
2: TmpStr:='Resource Directory ';
3: TmpStr:='Exception Directory ';
4: TmpStr:='Security Directory ';
5: TmpStr:='Base Relocation Table ';
6: TmpStr:='Debug Directory ';
7: TmpStr:='Description String ';
8: TmpStr:='Machine Value (MIPS GP) ';
9: TmpStr:='TLS Directory ';
10:TmpStr:='Load Configuration Directory ';
11:TmpStr:='Bound Import Directory In Headers';
12:TmpStr:='Import Address Table) ';
else
TmpStr:='UnUsed(保留) ';
end;
AddInfoToListView(lv_Directory,
TmpStr,
IntToHex(PENTHead.OptionalHeader.DataDirectory[i].VirtualAddress,8),
IntToStr(PENTHead.OptionalHeader.DataDirectory[i].VirtualAddress),
IntToHex(PENTHead.OptionalHeader.DataDirectory[i].Size,8),
IntToStr(PENTHead.OptionalHeader.DataDirectory[i].Size));
end;
{ begin section table }
Caption:=Format('%s [正在分析节表...]',[Application.Title]);
Have_PEResourceDirectory:=False; { 初始化资源变量 }
PEResourceDirectoryVirtualAddress:=0;
PEResourceDirectoryPointerToRawData:=0;
for i:=0 to PENTHead.FileHeader.NumberOfSections-1 do
begin
Application.ProcessMessages;
{ section name }
TmpStr:=Chr(PESectionHead[i].Name[0])
+Chr(PESectionHead[i].Name[1])
+Chr(PESectionHead[i].Name[2])
+Chr(PESectionHead[i].Name[3])
+Chr(PESectionHead[i].Name[4])
+Chr(PESectionHead[i].Name[5])
+Chr(PESectionHead[i].Name[6])
+Chr(PESectionHead[i].Name[7]);
{ check resource directory }
if TmpStr='.rsrc'+#0+#0+#0 then
begin
PEResourceDirectoryVirtualAddress:=PESectionHead[i].VirtualAddress;
PEResourceDirectoryPointerToRawData:=PESectionHead[i].PointerToRawData;
Have_PEResourceDirectory:=True;
end;
{ add info }
CreateSectionTabSheet(i,TmpStr,
PESectionHead[i].Misc.PhysicalAddress,
PESectionHead[i].Misc.VirtualSize,
PESectionHead[i].VirtualAddress,
PESectionHead[i].SizeOfRawData,
PESectionHead[i].PointerToRawData,
PESectionHead[i].PointerToRelocations,
PESectionHead[i].PointerToLinenumbers,
PESectionHead[i].NumberOfRelocations,
PESectionHead[i].NumberOfLinenumbers,
PESectionHead[i].Characteristics);
end;
{ end section table }
{ 开始读取资源信息 }
Caption:=Format('%s [正在分析资源目录...]',[Application.Title]);
if Have_PEResourceDirectory then
begin
iFile:=FileOpen(FileName,fmOpenRead or fmShareDenyNone);
try
FileSeek(iFile,PEResourceDirectoryPointerToRawData,0);
FileRead(iFile,PEResourceDirectory,SizeOf(PEResourceDirectory));
{ begin RootResourceDirectory infomation }
{ Resource Section PointerToRawData }
Edit_36.Text:=AddValue(8,PEResourceDirectoryPointerToRawData);
Edit_36.Hint:='资源目录根目录切入地址';
{ Characteristics }
Edit_39.Text:=AddValue(8,PEResourceDirectory.Characteristics);
Edit_39.Hint:='几乎总为0';
{ TimeDateStamp }
Edit_40.Text:=AddValue(8,PEResourceDirectory.TimeDateStamp);
Edit_40.Hint:='文件产生时间,资源目录此值可能为零'+#13
+'格式为1969年12月31日4:00P.M.后的总秒数';
{ Version }
Edit_41.Text:=Format(' %.*x%.*x [%u%u]',
[2,PEResourceDirectory.MajorVersion,
2,PEResourceDirectory.MinorVersion,
PEResourceDirectory.MajorVersion,
PEResourceDirectory.MinorVersion]);
Edit_41.Hint:=Format('资源目录版本为%u.%u版',
[PEResourceDirectory.MajorVersion,
PEResourceDirectory.MinorVersion]);
{ NumberOfNamedEntries }
Edit_37.Text:=AddValue(4,PEResourceDirectory.NumberOfNamedEntries);
Edit_37.Hint:=Format('有%u使用名称的元素',[PEResourceDirectory.NumberOfNamedEntries]);
{ NumberOfIdEntries }
Edit_38.Text:=AddValue(4,PEResourceDirectory.NumberOfIdEntries);
Edit_38.Hint:=Format('有%u个使用ID的元素',[PEResourceDirectory.NumberOfIdEntries]);
{ end TreeRoot }
iNum:=PEResourceDirectory.NumberOfNamedEntries+
PEResourceDirectory.NumberOfIdEntries;
if iNum<>0 then
begin
SetLength(ResDir_1,iNum);
SetLength(ResDirEnt_1,iNum);
for i:=0 to iNum-1 do
begin
FileRead(iFile,ResDirEnt_1[i],SizeOf(ResDirEnt_1[i]));
end;
ProgressBar1.Position:=10;
TmpStep:=90 div iNum; { 算出临时步长 }
with TreeView1.Items do
begin
for i:=0 to iNum-1 do
begin
Application.ProcessMessages;
Caption:=Format('%s [正在分析资源目录%u...]',[Application.Title,i]);
ProgressBar1.Position:=ProgressBar1.Position+TmpStep;
FileRead(iFile,ResDir_1[i],SizeOf(ResDir_1[i]));
if (ResDirEnt_1[i].Name and IMAGE_RESOURCE_NAME_IS_STRING)=0 then
begin { 最高位为 0 ,剩余的 31 位为一个整数ID }
TmpStr:=Format('ID[%u](%s) ByName[%u] ByID[%u] TimeDate[$%s] Ver[%u.%u] Char[$%s]',
[ResDirEnt_1[i].Name,
CheckResourceType(ResDirEnt_1[i].Name),
ResDir_1[i].NumberOfNamedEntries,
ResDir_1[i].NumberOfIdEntries,
IntToHex(ResDir_1[i].TimeDateStamp,8),
ResDir_1[i].MajorVersion,
ResDir_1[i].MinorVersion,
IntToHex(ResDir_1[i].Characteristics,8)]);
tn_ResDir1:=AddChild(nil,TmpStr);
end else { 最高位为 1 ,剩下 31 位为 IMAGE_RESOURCE_DIR_STRING_U 结构的偏移位置 从 Resource Section 开始 }
begin
TmpPos:=FileSeek(iFile,0,1); { 记忆文件位置 }
FileSeek(iFile,
ResDirEnt_1[i].Name and IMAGE_OFFSET_STRIP_HIGH
+PEResourceDirectoryPointerToRawData,
soFromBeginning);
FileRead(iFile,PEResourceDirStringU,SizeOf(PEResourceDirStringU));
FileRead(iFile,ResWName,(PEResourceDirStringU.Length-1)*2);
ResSName:=PEResourceDirStringU.NameString;
for iName:=0 to PEResourceDirStringU.Length-2 do
ResSName:=ResSName+ResWName[iName];
TmpStr:=Format('%s ByName[%u] ByID[%u] TimeDate[$%s] Ver[%u.%u] Char[$%s]',
[ResSName,
ResDir_1[i].NumberOfNamedEntries,
ResDir_1[i].NumberOfIdEntries,
IntToHex(ResDir_1[i].TimeDateStamp,8),
ResDir_1[i].MajorVersion,
ResDir_1[i].MinorVersion,
IntToHex(ResDir_1[i].Characteristics,8)]);
tn_ResDir1:=AddChild(nil,TmpStr);
FileSeek(iFile,TmpPos,0); { 恢复文件位置 i 位置 }
end;
jNum:=ResDir_1[i].NumberOfNamedEntries+ResDir_1[i].NumberOfIdEntries;
SetLength(ResDirEnt_2,jNum);
for j:=0 to jNum-1 do
begin
Application.ProcessMessages;
Caption:=Format('%s [正在分析资源目录%u-%u-%u...]',[Application.Title,iNum,i,j]);
FileRead(iFile,ResDirEnt_2[j],SizeOf(ResDirEnt_2[j]));
TmpPos:=FileSeek(iFile,0,1); { 保存地址 }
FileSeek(iFile,PEResourceDirectoryPointerToRawData+ResDirEnt_2[j].OffsetToData-IMAGE_RESOURCE_DATA_IS_DIRECTORY,0);
FileRead(iFile,ResDir_2,SizeOf(ResDir_2));
FileRead(iFile,ResDirEnt_3,SizeOf(ResDirEnt_3));
if (ResDirEnt_2[j].Name and IMAGE_RESOURCE_NAME_IS_STRING)=0 then
begin { 最高位为 0 ,剩余的 31 位为一个整数ID }
TmpStr:=Format('ID[%u] ByName[%u] ByID[%u] TimeDate[$%s] Ver[%u.%u] Char[$%s]',
[ResDirEnt_2[j].Name,
ResDir_2.NumberOfNamedEntries,
ResDir_2.NumberOfIdEntries,
IntToHex(ResDir_2.TimeDateStamp,8),
ResDir_2.MajorVersion,
ResDir_2.MinorVersion,
IntToHex(ResDir_2.Characteristics,8)]);
tn_ResDir2:=AddChild(tn_ResDir1,TmpStr);
end else { 最高位为 1 ,剩下 31 位为 IMAGE_RESOURCE_DIR_STRING_U 结构的偏移位置 从 Resource Section 开始 }
begin
FileSeek(iFile,
ResDirEnt_2[j].Name and IMAGE_OFFSET_STRIP_HIGH
+PEResourceDirectoryPointerToRawData,
soFromBeginning);
FileRead(iFile,PEResourceDirStringU,SizeOf(PEResourceDirStringU));
FileRead(iFile,ResWName,(PEResourceDirStringU.Length-1)*2);
ResSName:=PEResourceDirStringU.NameString;
for iName:=0 to PEResourceDirStringU.Length-2 do
ResSName:=ResSName+ResWName[iName];
TmpStr:=Format('%s ByName[%u] ByID[%u] TimeDate[$%s] Ver[%u.%u] Char[$%s]',
[ResSName,
ResDir_2.NumberOfNamedEntries,
ResDir_2.NumberOfIdEntries,
IntToHex(ResDir_2.TimeDateStamp,8),
ResDir_2.MajorVersion,
ResDir_2.MinorVersion,
IntToHex(ResDir_2.Characteristics,8)]);
tn_ResDir2:=AddChild(tn_ResDir1,TmpStr);
end;
{ 最终的资源显示 }
TmpStr:=Format('ID[%u] OffSetToData[$%s]',
[ResDirEnt_3.Name,
IntToHex(ResDirEnt_3.OffsetToData,8)]);
tn_ResDir3:=AddChild(tn_ResDir2,TmpStr);
FileSeek(iFile,ResDirEnt_3.OffsetToData+PEResourceDirectoryPointerToRawData,0);
FileRead(iFile,PEResDataEnt,SizeOf(PEResDataEnt));
TmpStr:=Format('OffsetToData[$%s] Size[$%s] AddressInFile[$%s]',
[IntToHex(PEResDataEnt.OffsetToData,8),
IntToHex(PEResDataEnt.Size,8),
{ 计算出在文件中的实际地址 }
IntToHex(PEResourceDirectoryPointerToRawData
+PEResDataEnt.OffsetToData
-PEResourceDirectoryVirtualAddress,8)]);
AddChild(tn_ResDir3,TmpStr);
FileSeek(iFile,TmpPos,0); { 恢复地址 j 循环 }
end;
end;
ProgressBar1.Position:=100;
end;
end else
begin
MessageBox(Handle,'无有效资源,跳过!','信息',MB_OK);
end;
finally
FileClose(iFile);
end;
end else
begin
MessageBox(Handle,'无法定位资源目录,跳过!','信息',MB_OK);
end;
Caption:=Format('%s [%s]',[Application.Title,FileName]);
ProgressBar1.Position:=0;
Dumped:=True;
end;
procedure TForm1.btn_DumpFileClick(Sender: TObject);
begin
if not FileExists(Edit_FileName.Text) then
begin
MessageBox(Handle,PChar(Format('所选文件[%s]不存在或位置已改变',[Edit_FileName.Text])),'错误',MB_OK);
Exit;
end;
ResetForm;
{ 开始分析分件 }
DoPEDump(Edit_FileName.Text);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
{ enable dragfile }
DragAcceptFiles(Handle, True);
{*_^}
Dumped:=False;
Caption:=Application.Title;
Application.HintHidePause:=60000;
Application.HintColor:=$00D2C8D2;
Constraints.MinHeight:=Height;
Constraints.MinWidth:=Width;
{8*)}
TabSheet0.Free;
{...}
AssocExeDllFile(True);
{ paramstr }
if ParamStr(1)<>'' then
Edit_FileName.Text:=ParamStr(1);
end;
function TForm1.GetShortcutTarget(ShortcutFilename:String):String;
var
Psl:IShellLink;
Ppf:IPersistFile;
WideName:Array [0..MAX_PATH] of WideChar;
pResult:Array [0..MAX_PATH-1] Of Char;
Data:TWin32FindData;
const
IID_IPersistFile:TGUID=(D1:$0000010B; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
begin
CoCreateInstance(CLSID_ShellLink,nil,CLSCTX_INPROC_SERVER, IID_IShellLinkA ,psl);
psl.QueryInterface(IID_IPersistFile,ppf);
MultiByteToWideChar(CP_ACP, 0, pChar(ShortcutFilename), -1, WideName, Max_Path);
ppf.Load(WideName,STGM_READ);
psl.Resolve(0,SLR_ANY_MATCH);
psl.GetPath(@pResult,MAX_PATH,Data,SLGP_UNCPRIORITY);
Result:=StrPas(@pResult);
end;
procedure TForm1.WMDropFiles(var Msg: TWMDropFiles);
var
CFileName:array[0..MAX_PATH-1] of Char;
begin
try
if DragQueryFile(Msg.Drop,0,CFileName,MAX_PATH)>0 then
begin
Edit_FileName.Text:=CFileName;
if UpperCase(ExtractFileExt(Edit_FileName.Text))='.LNK' then
Edit_FileName.Text:=GetShortcutTarget(Edit_FileName.Text);
ResetForm;
end;
finally
DragFinish(Msg.Drop);
end;
end;
procedure TForm1.btn_OpenFileClick(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
Edit_FileName.Text:=OpenDialog1.FileName;
ResetForm;
end;
end;
procedure TForm1.btn_OutTextClick(Sender: TObject);
const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -