📄 frmmain.pas
字号:
//
Application.CreateForm(TAboutForm,AboutForm);
try
AboutForm.ShowModal;
finally
AboutForm.Free;
end;
end;
procedure TMainForm.FileSaveExecute(Sender: TObject);
begin
//
end;
procedure TMainForm.ActionInitState;
begin
//灰显大部分Action
EditCut.Enabled := false;
EditCopy.Enabled := false;
EditPaste.Enabled:= false;
EditSelectAll.Enabled := false;
EditDelete.Enabled := false;
SearchFind.Enabled := false;
SearchFindNext.Enabled := false;
SearchReplace.Enabled := false;
FileClose.Enabled := false;
ProjOptions.Enabled := true;
ProjTestRun.Enabled := false;
ProjDialogPreview.Enabled := false;
ProjCompiler.Enabled := false;
ProjAnalyReport.Enabled := false;
FileSave.Enabled := false;
FileImport.Enabled := false;
FileExport.Enabled := false;
end;
procedure TMainForm.ActionOpenState;
begin
//打开之后有些动作是允许的.
FileClose.Enabled := true;
ProjTestRun.Enabled := true;
ProjCompiler.Enabled := true;
ProjAnalyReport.Enabled := true;
FileSave.Enabled := true;
FileImport.Enabled := true;
FileExport.Enabled := true;
end;
procedure TMainForm.trvPEStructureChange(Sender: TObject; Node: TTreeNode);
var
tmpNode:TTreeNode;
begin
{ ResIndex在导入导入,导出,保存资源时要用到 }
ResIndex := -1;
nbExeRes.Visible:=False; //为了防止切换的闪烁,先关闭显示,最后再打开显示
MenuForm.Hide;
DialogForm.Hide;
Application.ProcessMessages;
if nbExeRes.PageIndex<>0 then nbExeRes.PageIndex:=0;
lvDetailRes.Clear;
lvBinaryRes.Clear;
btnShowCtrl.Visible := False;
pnlRightTop.Caption := ' ' + Node.Text;
tmpNode := Node;
while tmpNode.Parent<>nil do tmpNode := tmpNode.Parent;
if tmpNode.Text='头部' then
begin
{ 是叶子节点,即可能显示下面的 }
if Node.HasChildren then
LoadRootInfoForHeader(Node)
else
LoadLeafInfoForHeader(Node);
end
else if tmpNode.Text='资源' then
begin
if Node.HasChildren then
LoadRootInfoForResource(Node)
else
LoadLeafInfoForResource(Node);
if ResIndex>-1 then
StatusBar.Panels[1].Text :=Format(' 偏移量: %.8xH 大小: %d字节',[StrtoInt(ResDataDir[ResIndex][2]),StrtoInt(ResDataDir[ResIndex][3])])
else
StatusBar.Panels[1].Text := '';
end
else if tmpNode.Text='导入' then
begin
if Node.Text<>'导入' then
LoadImportDirData(Node.Text,Node.Index)
else
LoadImportDirData(Node.Text,0); //这里的0记录不会用到
end
else if tmpNode.Text='导出' then
begin
LoadExportDirData(Node.Text);
end;
if ProjBinary.Checked then
ProjBinary.Checked := False;
// nbExeRes.ActivePage := 'BinaryPage';
nbExeRes.Visible:=True;
//Button1.Caption:= InttoStr(ResIndex);
end;
{ 装载导入表的数据 }
procedure TMainForm.LoadImportDirData(SelText:String;IndexOfName:WORD);
var
tmpStrList: TStringList;
i:integer;
begin
nbExeRes.ActivePage := 'StringPage';
lvStringRes.Clear;
tmpStrList := TStringList.Create;
try
if SelText = '导入' then
begin
lvStringRes.Columns[0].Caption := ' ';
lvStringRes.Columns[1].Caption := ' 名称';
with CurExeImg do
if ImportDirAddr<>0 then
begin
LoadBinaryInfo(ImportDirAddr,ImportDirSize);
tmpStrList := CurExeImg.GetImportName;
for i:=0 to tmpStrList.Count-1 do
with lvStringRes.Items.Add do
begin
Caption := '';
SubItems.Add(tmpStrList.Strings[i]);
end;
end;
end
else begin
lvStringRes.Columns[0].Caption := ' 序号';
lvStringRes.Columns[1].Caption := ' 函数名称';
//为防止重名时不能找出正确的函数名,用名称的索引号来处理.
tmpStrList := CurExeImg.GetImportFunction(IndexOfName);
for i:=0 to tmpStrList.Count-1 do
with lvStringRes.Items.Add do
begin
Caption := Copy(tmpStrList.Strings[i],0,Pos(',',tmpStrList.Strings[i])-1);
SubItems.Add(Copy(tmpStrList.Strings[i],Length(Caption)+2,Length(tmpStrList.Strings[i])));
end;
end;
finally
tmpStrList.Free;
end;
end;
{ 装载导出表的数据 }
procedure TMainForm.LoadExportDirData(SelText:String);
var
tmpStr: String;
tmpStrList: TStringList;
i: Integer;
begin
nbExeRes.ActivePage := 'DetailListPage';
lvDetailRes.Clear;
if SelText = '导出' then
begin
lvDetailRes.Column[0].Caption:=' 名称';
lvDetailRes.Column[1].Caption:=' 地址(Hex)';
lvDetailRes.Column[2].Caption:=' 大小';
with lvDetailRes.Items.Add,CurExeImg do
begin
Caption := CurExeImg.ExportName;
SubItems.Add(Format('%.8x',[ExportDirAddr]));
SubItems.Add(Format('%8xH [ %5d ]',[ExportDirSize,ExportDirSize]));
end;
end
else begin
lvDetailRes.Column[0].Caption:=' 序号';
lvDetailRes.Column[1].Caption:=' 地址';
lvDetailRes.Column[2].Caption:=' 名称';
tmpStrList := TStringList.Create;
try
tmpStrList := CurExeImg.GetExportInfo;
for i:=0 to tmpStrList.Count-1 do
with lvDetailRes.Items.Add do
begin
tmpStr := tmpStrList.Strings[i];
tmpStr := Copy(tmpStr,0,Pos(',',tmpStr)-1);
Caption := ' '+tmpStr;
tmpStr := tmpStrList.Strings[i];
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;
with CurExeImg do
if ExportDirAddr<>0 then
LoadBinaryInfo(ExportDirAddr,ExportDirSize);
end;
end;
{ 选择资源非叶子节点(称为Root)将显示的信息 }
procedure TMainForm.LoadRootInfoForResource(ANode:TTreeNode);
var
tmpNode: TTreeNode;
tmpStr: String;
i,tmpOffset,tmpSize:integer;
tmpVar: Variant;
begin
if ANode.Text ='资源' then //最顶级
begin
trvMenuRes.Items.Clear;
tmpNode:=ANode.GetFirstChild;
while tmpNode<>nil do
begin
trvMenuRes.Items.Add(nil,tmpNode.Text);
tmpNode:= ANode.GetNextChild(tmpNode);
end;
trvMenuRes.ShowLines := false;
nbExeRes.ActivePage:='MenuPage';
end
else if ANode.Parent.Text='资源' then //第二级
begin
lvDetailRes.Column[0].Caption:=' 名称';
lvDetailRes.Column[1].Caption:=' 偏移值(Hex)';
lvDetailRes.Column[2].Caption:=' 大小';
tmpStr := ANode.Text;
if (tmpStr='光标')or(tmpStr='图标') then
tmpStr := tmpStr+'索引';
for i:=0 to CurExeImg.ResDataNum-1 do
if VartoStr(ResDataDir[i][0])=tmpStr then
with lvDetailRes.Items.Add do
begin
Caption:= VartoStr(ResDataDir[i][1]);
tmpOffset := StrtoInt(VartoStr(ResDataDir[i][2]));
tmpSize := StrtoInt(VartoStr(ResDataDir[i][3]));
SubItems.Add(Format('%.8x',[tmpOffset]));
SubItems.Add(Format('%6xH [ %6d ]',[tmpSize,tmpSize]));
end;
end
else begin //第三级
lvDetailRes.Column[0].Caption:=' 地址';
lvDetailRes.Column[1].Caption:=' 值';
lvDetailRes.Column[2].Caption:=' 含义';
tmpStr := ANode.Parent.Text;
if (tmpStr='光标')or(tmpStr='图标') then
begin
i := GetResIndex(tmpStr+'索引',ANode.Text);
if i>-1 then //表示找到
begin
ResIndex := i;
tmpOffset := StrtoInt(VartoStr(ResDataDir[i][2]));
tmpSize := StrtoInt(VartoStr(ResDataDir[i][3]));
tmpVar := CurExeImg.AnalysisIconOrCursorGroupInfo(tmpOffset);
lvDetailRes.Items.BeginUpdate;
for i:=0 to CurExeImg.GroupVarCount-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(tmpOffset,tmpSize);
end;
end;
end;
end;
{ 选择头部叶节点要显示的信息 }
procedure TMainForm.LoadLeafInfoForResource(ANode:TTreeNode);
var
//tmpNode:TTreeNode;
tmpNodeText:String;
tmpSelNodeText,tmpSelNodeType:String;
tmpOffset,HeaderOffset,tmpSize,i:integer;
begin
if ANode.Parent.Parent=nil then exit;
tmpNodeText:=ANode.Parent.Parent.Text;
HeaderOffset := 0;
if (tmpNodeText='光标')or(tmpNodeText='图标') then
begin
//光标索引的偏移量
i := GetResIndex(tmpNodeText+'索引',ANode.Parent.Text);
if i > -1 then //表示找到
HeaderOffset := StrtoInt(VartoStr(ResDataDir[i][2]));
tmpSelNodeText := ANode.Text;
tmpSelNodeText := Copy(tmpSelNodeText,0,Pos(': ',tmpSelNodeText)-1);
tmpSelNodeType := tmpNodeText;
end
else begin
tmpSelNodeText := ANode.Text;
tmpSelNodeType := ANode.Parent.Text;
end;
i := GetResIndex(tmpSelNodeType,tmpSelNodeText);
if i > -1 then //表示找到
begin
ResIndex := i; //这句比较关键.
tmpOffset := StrtoInt(VartoStr(ResDataDir[i][2]));
tmpSize := StrtoInt(VartoStr(ResDataDir[i][3]));
LoadVisualInfoForResource(tmpOffset,tmpSize,HeaderOffset,tmpSelNodeType,tmpSelNodeText);
//if tmpSelNodeType<>'位图' then
LoadBinaryInfo(tmpOffset,tmpSize);
end;
end;
{ 将叶节点显示为可视化的控件 }
{
AOffset,当前节点记录内容的偏移量
ASize: 当前节点记录内容的大小
IndexOffset,光标,图标组的偏移量
ResType: 当前节点所属类型
ResName: 当前节点名称
}
procedure TMainForm.LoadVisualInfoForResource(AOffset,ASize,IndexOffset:Integer;ResType,ResName:String);
begin
if ResType='光标' then
ShowCursor(AOffset,ASize,IndexOffset,StrtoInt(ResName))
else if ResType='图标' then
ShowIcon(AOffset,ASize,IndexOffset,StrtoInt(ResName))
else if ResType='位图' then
ShowBitmap(AOffset,ASize)
else if ResType='字串表' then
ShowString(AOffset,ASize,ResName)
else if ResType='快捷键列表' then
ShowAccelerator(AOffset,ASize)
else if ResType='版本' then
ShowVersionInfo(AOffset,ASize)
else if ResType='对话框' then
ShowDialogBox(AOffset,ASize)
else if ResType='菜单' then
ShowMenuItem(AOffset,ASize,ResName)
else if ResType='工具栏' then
ShowToolItem(AOffset,ASize)
else if ResType='24' then
ShowTextContent(AOffset,ASize)
else if ResType='对话框数据' then
ShowDialogData(AOffset,ASize)
else if (ResType='RC数据')and(ResName='PACKAGEINFO') then
ShowPackageInfo(AOffset,ASize);
end;
{ 包信息 }
procedure TMainForm.ShowPackageInfo(AOffset,ASize:Integer);
var
tmpStream:TMemoryStream;
CurPosition: Integer;
tmpWord: WORD;
tmpChar: Char;
tmpStr: String;
i:integer;
begin
nbExeRes.ActivePage := 'StringPage';
lvStringRes.Clear;
lvStringRes.Columns[0].Caption := ' 编号';
lvStringRes.Columns[1].Caption := ' 引用的单元';
tmpStream := TMemoryStream.Create;
try
tmpStream := CurExeImg.GetSegStream(AOffset,ASize);
CurPosition := 12;
//前8Bytes不知有什么用,9-12 Bytes作为总单元的个数
tmpStream.Seek(12,0);
i:=0;
while CurPosition < ASize-2 do //最后两个字节是00,不知有什么用。
begin
tmpStream.Read(tmpWord,SizeOf(tmpWord));
CurPosition := CurPosition + SizeOf(tmpWord);
tmpStr := '';
repeat
tmpStream.Read(tmpChar,SizeOf(tmpChar));
CurPosition := CurPosition + SizeOf(tmpChar);
tmpStr := tmpStr + tmpChar;
until tmpChar=Chr(0);
with lvStringRes.Items.Add do
begin
Caption := Format('%.6d',[tmpWord]);
SubItems.Add(tmpStr);
i:=i+1;
end;
end;
finally
tmpStream.Free;
end;
pnlRightTop.Caption :=Format('%s,个数: %.4x[%.5d]',[pnlRightTop.Caption,i,i]);
end;
{ 显示对话框数据的内容 }
procedure TMainForm.ShowDialogData(AOffset,ASize:Integer);
var
dlgData: TDialogDataInfo;
tmpByte: Byte;
i,CurPosition:Integer;
tmpStr: String;
tmpStream: TMemoryStream;
begin
nbExeRes.ActivePage := 'StringPage';
lvStringRes.Clear;
lvStringRes.Columns[0].Caption := '';
lvStringRes.Columns[1].Caption := '';
tmpStream := TMemoryStream.Create;
try
tmpStream := CurExeImg.GetSegStream(AOffset,ASize);
CurPosition := 0;
tmpStream.Seek(0,0);
while CurPosition < ASize-2 do //最后两个字节是00,不知有什么用。
begin
tmpStream.Read(dlgData,SizeOf(dlgData));
CurPosition := CurPosition + SizeOf(dlgData);
tmpStr := '';
for i:=0 to dlgData.dlgCount-1 do
begin
tmpStream.Read(tmpByte,SizeOf(tmpByte));
CurPosition := CurPosition + SizeOf(tmpByte);
tmpStr := tmpStr + Chr(tmpByte);
end;
with lvStringRes.Items.Add do
begin
Caption := Format('%6d',[dlgData.dlgID]);
SubItems.Add(tmpStr);
end;
end;
finally
tmpStream.Free;
end;
end;
{ 以文本形式显示二进制代码表示的内容 }
procedure TMainForm.ShowTextContent(AOffset,ASize:Integer);
var
tmpStream: TMemoryStream;
tmpByte: BYTE;
CurPosition:Integer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -