⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frmmain.pas

📁 你用过ExeScope吗?它是能够将Exe文件中的资源进行查看并修改的工具
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  //
  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 + -