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

📄 unit1.pas

📁 知道大家有没有用过PEDUMP
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  { 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 + -