📄 frmmain.pas
字号:
try
Picture.LoadFromFile(tmpFileName);
finally
deleteFile(tmpFileName);
end;
ScrollBoxImgResize(nil);
Bevel1.Width := bWidth+4;
Bevel1.Height:= bHeight+4;
Visible:=True;
end;
finally
tmpStream.Free;
end;
end;
{ 显示图标 }
procedure TMainForm.ShowIcon(AOffset,ASize,HeaderOffset,NameID:Integer);
var
tmpStream: TMemoryStream;
tmpFileName: String;
bWidth,bHeight:Byte;
begin
nbExeRes.ActivePage:='ImagePage';
{
var tmpIcon: TICON;
//这部分运行还会出错
tmpIcon := TICON.Create;
try
tmpStream := TMemoryStream.Create;
try
tmpStream := CurExeImg.GetIconStream(AOffset,ASize,HeaderOffset,NameID);
tmpStream.Seek(6,0);
tmpStream.Read(bWidth,SizeOf(bWidth));
tmpStream.Read(bHeight,SizeOf(bHeight));
tmpIcon.LoadFromStream(tmpStream);
finally
tmpStream.Free;
end;
ImgPICRes.Picture.Assign(tmpIcon);
ScrollBoxImgResize(nil);
Bevel1.Width := bWidth+4;
Bevel1.Height:= bHeight+4;
finally
tmpIcon.Free;
end;
}
tmpFileName := 'c:\tmp.ico'; //ExtractFilePath(Application.ExeName)+'tmp.ico';
tmpStream := CurExeImg.GetIconStream(AOffset,ASize,HeaderOffset,NameID);
try
tmpStream.Seek(6,0);
tmpStream.Read(bWidth,SizeOf(bWidth));
tmpStream.Read(bHeight,SizeOf(bHeight));
tmpStream.SaveToFile(tmpFileName);
// 显示图标并调整位置到居中
with ImgPICRes do
begin
Visible:=False;
try
Picture.LoadFromFile(tmpFileName);
finally
deleteFile(tmpFileName);
end;
ScrollBoxImgResize(nil);
Bevel1.Width := bWidth+4;
Bevel1.Height:= bHeight+4;
Visible:=True;
end;
finally
tmpStream.Free;
end;
end;
{ 显示字串表 }
procedure TMainForm.ShowString(AOffset,ASize:Integer;ResName:String);
var
i,ID: Integer;
tmpStrList: TStringList;
begin
nbExeRes.ActivePage := 'StringPage';
lvStringRes.Clear;
lvStringRes.Columns[0].Caption := ' ID';
lvStringRes.Columns[1].Caption := ' 值';
tmpStrList := TStringList.Create;
try
tmpStrList := CurExeImg.GetStringTable(AOffset,ASize);
ID := (StrToInt(ResName)-1) shl 4;
for i:=0 to tmpStrList.Count-1 do
with lvStringRes.Items.Add do
begin
Caption := Format('%6d',[ID+i]);
SubItems.Add(tmpStrList.Strings[i]);
end;
finally
tmpStrList.Free;
end;
end;
{ 读取加速键列表 }
procedure TMainForm.ShowAccelerator(AOffset,ASize:Integer);
var
i: Integer;
tmpStr: String;
tmpStrList: TStringList;
begin
// nbExeRes.ActivePage := 'StringPage';
nbExeRes.ActivePage := 'DetailListPage';
with lvDetailRes do
begin
Clear;
Columns[0].Caption := ' ID';
Columns[1].Caption := ' 类型';
Columns[2].Caption := ' 快捷键';
end;
tmpStrList := TStringList.Create;
try
tmpStrList := CurExeImg.GetAccelerator(AOffset,ASize);
for i:=0 to tmpStrList.Count-1 do
with lvDetailRes.Items.Add do
begin
tmpStr := tmpStrList.Strings[i];
Caption := Copy(tmpStr,0,Pos(',',tmpStr)-1);
tmpStr := Copy(tmpStr,Pos(',',tmpStr)+1,Length(tmpStr));
SubItems.Add(Copy(tmpStr,0,Pos(',',tmpStr)-1));
tmpStr := Copy(tmpStr,Pos(',',tmpStr)+1,Length(tmpStr));
SubItems.Add(tmpStr);
end;
finally
tmpStrList.Free;
end;
end;
{ 读取版本信息 }
procedure TMainForm.ShowVersionInfo(AOffset,ASize:Integer);
var
i: Integer;
tmpStrList: TStringList;
LanguageID:DWORD;
FileFlags: DWORD;
begin
nbExeRes.ActivePage:='VersionPage';
for i:=vleVersion.RowCount-1 downto 1 do //第一行不能删除
vleVersion.DeleteRow(i);
//
Application.ProcessMessages;
tmpStrList := TStringList.Create;
try
//标准版本信息
tmpStrList := CurExeImg.GetVSFixedFileInfo(AOffset);
edFileVersion.Text := tmpStrList.Strings[0];
edProductVersion.Text := tmpStrList.Strings[1];
FileFlags := StrtoInt(tmpStrList.Strings[2]);
chkDebug.Checked := IsFileFlags(FileFlags,VS_FF_DEBUG);
chkPrerelease.Checked := IsFileFlags(FileFlags,VS_FF_PRERELEASE);
chkPatched.Checked := IsFileFlags(FileFlags,VS_FF_PATCHED);
chkPrivateBuild.Checked := IsFileFlags(FileFlags,VS_FF_PRIVATEBUILD);
chkInfoInferred.Checked := IsFileFlags(FileFlags,VS_FF_INFOINFERRED);
chkSpecialBuild.Checked := IsFileFlags(FileFlags,VS_FF_SPECIALBUILD);
edOS.Text := tmpStrList.Strings[3];
edFileType.Text := tmpStrList.Strings[4];
//语言标记
LanguageID := CurExeImg.GetVSLanguageID(AOffset,ASize);
edTrans.Text := Format('$%.8x',[LanguageID]);
cbLanguage.Text := TransLanguage(HIWORD(LanguageID)); //高位
cbCodePage.Text := TransCodePage(LOWORD(LanguageID)); //低位
//版本描述信息
tmpStrList := CurExeImg.GetVSStringFileInfo(AOffset);
i:=0;
while i<tmpStrList.Count do
begin
if i+1 < tmpStrList.Count then
vleVersion.InsertRow(tmpStrList.Strings[i],tmpStrList.Strings[i+1],true)
else
vleVersion.InsertRow(tmpStrList.Strings[i],'',true);
i := i + 2;
end;
//版本其它信息
tmpStrList := CurExeImg.GetVSVerFileInfo(AOffset);
i:=0;
while i<tmpStrList.Count do
begin
if i+1 < tmpStrList.Count then
vleVersion.InsertRow(tmpStrList.Strings[i],tmpStrList.Strings[i+1],true)
else
vleVersion.InsertRow(tmpStrList.Strings[i],'',true);
i := i + 2;
end;
finally
tmpStrList.Free;
end;
end;
{ 选择头部非叶子节点(称为Root)将显示的信息 }
procedure TMainForm.LoadRootInfoForHeader(ANode:TTreeNode);
var
i: Word;
tmpLeng: Integer;
tmpVar: Variant;
begin
lvDetailRes.Column[0].Caption:=' 名称';
lvDetailRes.Column[1].Caption:=' 偏移值(Hex)';
lvDetailRes.Column[2].Caption:=' 大小';
if ANode.Text = '头部' then
begin
with lvDetailRes.Items.Add do
begin
Caption:= 'DOS头部';
SubItems.Add(Format('%.8x',[0]));
tmpLeng:=SizeOf(TImageDosHeader);
SubItems.Add(Format('%6xH [ %4d ]',[tmpLeng,tmpLeng]));
end;
with lvDetailRes.Items.Add do
begin
Caption:= 'NT头部';
SubItems.Add(Format('%.8x',[CurExeImg.PENTHeaderOffSet]));
SubItems.Add(Format('%6xH [ %4d ]',[SizeOf(TImageNTHeaders),SizeOf(TImageNTHeaders)]));
end;
with lvDetailRes.Items.Add do
begin
Caption:= '块表头部';
tmpLeng:=CurExeImg.PENTHeaderOffSet+SizeOf(TImageNTHeaders);
SubItems.Add(Format('%.8x',[tmpLeng]));
tmpLeng:=CurExeImg.SectionNum*SizeOf(TImageSectionHeader);
SubItems.add(Format('%6xH [ %4d ]',[tmpLeng,tmpLeng]));
end;
end
else if ANode.Text = 'NT头部' then
begin
with lvDetailRes.Items.Add do
begin
Caption:= 'Coff头部';
SubItems.Add(Format('%.8x',[CurExeImg.PENTHeaderOffSet]));
tmpLeng:=SizeOf(TImageNTHeaders)-SizeOf(TImageOptionalHeader);
SubItems.Add(Format('%6xH [ %5d ]',[tmpLeng,tmpLeng]));
end;
with lvDetailRes.Items.Add do
begin
Caption:= '可选头部';
SubItems.Add(Format('%.8x',[CurExeImg.PENTHeaderOffSet+tmpLeng]));
tmpLeng:=SizeOf(TImageOptionalHeader);
SubItems.Add(Format('%6xH [ %5d ]',[tmpLeng,tmpLeng]));
end;
end
else if ANode.Text = '块表头部' then
begin
tmpVar:=CurExeImg.AnalySisSectionDescript;
for i:=0 to CurExeImg.SectionNum-1 do
with lvDetailRes.Items.Add do
begin
Caption := VartoStr(tmpVar[i][0]);
tmpLeng:=tmpVar[i][1];
SubItems.Add(Format('%.8x',[tmpLeng]));
tmpLeng:=tmpVar[i][2];
SubItems.Add(Format('%8xH [ %8d ]',[tmpLeng,tmpLeng]));
end;
end;
end;
{ 选择头部叶节点要显示的信息 }
procedure TMainForm.LoadLeafInfoForHeader(ANode:TTreeNode);
begin
lvDetailRes.Column[0].Caption:=' 地址';
lvDetailRes.Column[1].Caption:=' 值';
lvDetailRes.Column[2].Caption:=' 含义';
if ANode.Text = 'DOS头部' then
LoadDosHeadInfo
else if ANode.Text = 'Coff头部' then
LoadCoffHeadInfo
else if ANode.Text = '可选头部' then
LoadOptionHeadInfo
else if ANode.Parent<>nil then
begin
if ANode.Parent.Text='块表头部' then
LoadSectionHeadInfo(ANode.Parent.IndexOf(ANode))
end
else exit;
end;
{ 装载DOS头部信息 }
procedure TMainForm.LoadDosHeadInfo;
var
tmpVar: Variant;
i: Word;
begin
tmpVar:= CurExeImg.AnalysisDosHeader;
lvDetailRes.Items.BeginUpdate;
for i:=0 to CurExeImg.PEDosHeadRecSize-1 do
With lvDetailRes.Items.Add do
begin
Caption:=Format(' %.8xH',[StrtoInt(VartoStr(tmpVar[i][0]))]);
SubItems.Add(vartoStr(tmpVar[i][1]));
SubItems.Add(vartoStr(tmpVar[i][2]));
end;
lvDetailRes.Items.EndUpdate;
LoadBinaryInfo(0,SizeOf(TImageDosHeader));
end;
{ 装载Coff头部信息 }
procedure TMainForm.LoadCoffHeadInfo;
var
tmpOffSet:Integer;
tmpCount: Word;
tmpVar: Variant;
i: Word;
begin
tmpVar:= CurExeImg.AnalysisCoffHeader;
lvDetailRes.Items.BeginUpdate;
for i:=0 to CurExeImg.PECoffHeadRecSize-1 do
With lvDetailRes.Items.Add do
begin
Caption:=Format(' %.8xH',[StrtoInt(VartoStr(tmpVar[i][0]))]);
SubItems.Add(vartoStr(tmpVar[i][1]));
SubItems.Add(vartoStr(tmpVar[i][2]));
end;
lvDetailRes.Items.EndUpdate;
tmpOffSet:=CurExeImg.PENTHeaderOffSet;
tmpCount :=SizeOf(TImageNTHeaders)-SizeOf(TImageOptionalheader);
LoadBinaryInfo(tmpOffSet,tmpCount);
end;
{ 装载可选头部信息 }
procedure TMainForm.LoadOptionHeadInfo;
var
tmpVar: Variant;
i: Word;
tmpOffSet:Integer;
tmpCount: Word;
begin
tmpVar:= CurExeImg.AnalysisOptionHeader;
lvDetailRes.Items.BeginUpdate;
for i:=0 to CurExeImg.PEOptionHeadRecSize-1 do
With lvDetailRes.Items.Add do
begin
Caption:=Format(' %.8xH',[StrtoInt(VartoStr(tmpVar[i][0]))]);
SubItems.Add(vartoStr(tmpVar[i][1]));
SubItems.Add(vartoStr(tmpVar[i][2]));
end;
lvDetailRes.Items.EndUpdate;
tmpOffSet:=CurExeImg.PENTHeaderOffSet+SizeOf(TImageNTHeaders)-SizeOf(TImageOptionalHeader);
tmpCount :=SizeOf(TImageOptionalHeader);
LoadBinaryInfo(tmpOffSet,tmpCount);
end;
{ 装载块表的头部信息 }
procedure TMainForm.LoadSectionHeadInfo(AIndex:Word);
var
tmpOffSet: Integer;
tmpCount: Word;
i:Word;
tmpVar: Variant;
begin
tmpVar:=CurExeImg.AnalySisSectionHeader(AIndex);
lvDetailRes.Items.BeginUpdate;
for i:=0 to CurExeImg.PESectionHeadRecSize-1 do
With lvDetailRes.Items.Add do
begin
Caption:=Format(' %.8xH',[StrtoInt(VartoStr(tmpVar[i][0]))]);
SubItems.Add(vartoStr(tmpVar[i][1]));
SubItems.Add(vartoStr(tmpVar[i][2]));
end;
lvDetailRes.Items.EndUpdate;
tmpOffSet:= CurExeImg.PENTHeaderOffSet+SizeOf(TImageNTHeaders)+AIndex*SizeOf(TImageSectionHeader);
tmpCount := SizeOf(TImageSectionHeader);
LoadBinaryInfo(tmpOffSet,tmpCount);
end;
{ 加载二进制数据 }
// 在这里ACount必须为Integer,原来是WORD时有问题.
procedure TMainForm.LoadBinaryInfo(AOffset,ACount:Integer);
const
Max_Buf=1024;
Col_Num=16;
var
i,j,iPos,tmpNewOffSet,tmpSpace:Integer;
ResBuffer:array[0..Max_Buf-1] of Byte;
StrLine:String;
tmpSegStream: TMemoryStream; //指定段的内存流;
begin
////缺点:在加入一块比较大的内存块时处理很慢
Application.ProcessMessages;
Screen.Cursor:=crHourGlass;
lvBinaryRes.Clear;
tmpSegStream := TMemoryStream.Create;
try
tmpSegStream.LoadFromStream(CurExeImg.GetSegStream(AOffSet,ACount));
with pbLoadBinary do
begin
Max := ACount;
Position:=0;
if ACount>4096 then Visible:=True
end;
with tmpSegStream do
begin
tmpNewOffSet:=Col_Num*(AOffSet div Col_Num);
tmpSpace:=AOffSet-tmpNewOffSet;
//为地址对齐预读出多余部分以做显示的调整
Seek(0,soFromBeginning);
if tmpSpace>0 then
begin
Read(ResBuffer,Col_Num-tmpSpace);
with pbLoadBinary do
Position:=Position + Col_Num - tmpSpace;
with lvBinaryRes.Items.Add do
begin
Caption:=Format('%.8xH: ',[tmpNewOffSet]);
strLine:='';
for i:=0 to tmpSpace-1 do
begin
SubItems.Add(' ');
StrLine:=StrLine+' ';
end;
for i:=tmpSpace to Col_Num-1 do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -