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

📄 exeimage.pas

📁 你用过ExeScope吗?它是能够将Exe文件中的资源进行查看并修改的工具
💻 PAS
📖 第 1 页 / 共 5 页
字号:
{***********************************************************************

  Copyright @2002-2003
  Author:  OuChengSong
  Create Date: 2002-12-31

  Descript: Exe文件映像的封装

    提供Exe文件资源的读取与更改.


***********************************************************************}

unit ExeImage;

interface

uses
   Windows,SysUtils,Classes,Variants,
   { 手工加入的 }
   peTypes,FPSet;

type

  EExeError = class(Exception);

  TExeImage = class
  private

   FFileName:String;  //文件名,为保存更改后的内存流输入到指定文件定名.
   FPENTHeaderOffSet: Integer; //指向新的NT文件头的偏移值.
   FExeStream: TMemoryStream; //内存流

    { PE文件结构的实例 }
   FPEDosHead:TImageDosHeader;     //DOS头
   FPENTHead:TImageNTHeaders;      //NT头
   FPESectionHead:array of TImageSectionHeader;  { 块表头的大小由NT头的NumberOfSections确定 }

    { 头部记录个数,由程序设计时定义 }
   FPEDosHeadRecSize:Word;
   FPECoffHeadRecSize:Word;
   FPEOptionHeadRecSize:Word;
   FPESectionHeadRecSize:Word;

    { 数据目录的一些项的存在性 }
   FExportDirExists : Boolean;
   FImportDirExists : Boolean;
   FResourceDirExists: Boolean;

    { }
   FSectionNum: Word; //节表的个数
   FResDataNum: Word; //资源数据的个数
   FResourceInSectionIndex: Word; //资源节表在节表目录的索引.
   FGroupVarCount: Integer;  //图标光标组中返回的变体长度
   function IsResourceExists:Boolean;
   function GetResDataNum:  Word;

    { 判断文件运行所需的机器及文件与块表特性 }
   function CheckFileMachine(Value: Cardinal): String;
   function CheckFileCharacteristics(Value: Cardinal):String;
   function CheckSectionCharacteristics(Value:Cardinal):String;

  public
    constructor CreateImage(AFileName:String);//创建映像

     { 私有变量以属性方式提供出去(只读) }
    property  ExportDirExists : Boolean read FExportDirExists;
    property  ImportDirExists : Boolean read FImportDirExists;
    property  ResourceDirExists: Boolean read FResourceDirExists;

    property  PENTHeaderOffSet:Integer read FPENTHeaderOffSet;
    property  PEDosHeadRecSize: Word read FPEDosHeadRecSize;
    property  PECoffHeadRecSize:Word read FPECoffHeadRecSize;
    property  PEOptionHeadRecSize:Word read FPEOptionHeadRecSize;
    property  PESectionHeadRecSize: Word read FPESectionHeadRecSize;
    property  FileName: String read FFileName;
    property  SectionNum:Word read FSectionNum;
    property  ResDataNum:Word read FResDataNum;
    property  GroupVarCount: Integer read FGroupVarCount;

     { 获取信息,返回较多内容 }
     {
       实际上以变体返回对于封装性不是很好,如果必要可以再将
       其换为一个结构型的实例,但此实例是个数组,其长度需要
       由一个属性值提供出去以告知。[是否可取变体的维度来确定?]
     }
    function  GetSegStream(AOffset:Integer;ACount:Word): TMemoryStream;
    function  GetBitmapStream(AOffset:Integer;ACount:Word): TMemoryStream;
    function  GetCursorStream(AOffset, ACount, HeaderOffset,NameID: Integer): TMemoryStream;
    function  GetIconStream(AOffset, ACount, HeaderOffset,NameID: Integer): TMemoryStream;

    function  AnalysisDosHeader: Variant;
    function  AnalysisCoffHeader: Variant;
    function  AnalysisOptionHeader: Variant;
    function  AnalysisSectionHeader(AIndex:Word): Variant;
    function  AnalysisSectionDescript:Variant;
    function  GetResourceDataDir:Variant;
    function  AnalysisIconOrCursorGroupInfo(AOffset:Integer):Variant;

     { 获取简单信息 }
     {
         ICON -> ICON_ENTRY
         CURSOR -> CURSOR_ENTRY
         以后修改成不要传递参数的.
     }
    function GetIconResInfo(AOffset:Integer):TStringList;
    function GetCursorResInfo(AOffset:Integer):TStringList;
    function GetStringTable(AOffset,ASize:Integer):TStringList;
    function GetAccelerator(AOffset,ASize:Integer):TStringList;
    function GetExportInfo:TStringList;
    //获得版本信息;
    function GetVSFixedFileInfo(AOffset:Integer):TStringList;
    function GetVSStringFileInfo(AOffset:Integer):TStringList;
    function GetVSVerFileInfo(AOffset:Integer):TStringList;
    function GetVSLanguageID(AOffset,ASize:Integer):DWORD;

    { 获取数据目录相应的大小及地址 }
    function ImportDirAddr: Integer;
    function ImportDirSize: Integer;
    function ExportDirAddr: Integer;
    function ExportDirSize: Integer;
    function ExportName: String;
    function GetImportName:TStringList;
    function GetImportFunction(AIndexOfName:WORD):TStringList;

  end;

implementation


{ Exceptions of EExeError }

procedure ExeError(const ErrMsg: string);
begin
  raise EExeError.Create(ErrMsg);
end;

{ TExeImage }

{ 返回文件运行所需要CPU标记的机器名 }
function TExeImage.CheckFileMachine(Value:Cardinal):String;
begin
  case Value of
    IMAGE_FILE_MACHINE_I386     :Result:='Intel 386';
    $160                        :Result:='MIPS big-endian';
    IMAGE_FILE_MACHINE_R3000    :Result:='MIPS little-endian';
    IMAGE_FILE_MACHINE_R4000    :Result:='MIPS little-endian';
    IMAGE_FILE_MACHINE_R10000   :Result:='MIPS little-endian';
    IMAGE_FILE_MACHINE_WCEMIPSV2:Result:='MIPS little-endian WCE v2';
    IMAGE_FILE_MACHINE_ALPHA    :Result:='Alpha_AXP';
    IMAGE_FILE_MACHINE_SH3      :Result:='SH3 little-endian';
    IMAGE_FILE_MACHINE_SH3E     :Result:='SH3E little-endian';
    IMAGE_FILE_MACHINE_SH4      :Result:='SH4 little-endian';
    IMAGE_FILE_MACHINE_SH5      :Result:='SH5';
    IMAGE_FILE_MACHINE_ARM      :Result:='ARM Little-Endian';
    IMAGE_FILE_MACHINE_THUMB    :Result:='THUMB';
    IMAGE_FILE_MACHINE_ARM33    :Result:='ARM33';
    IMAGE_FILE_MACHINE_POWERPC  :Result:='IBM PowerPC Little-Endian';
    IMAGE_FILE_MACHINE_IA64     :Result:='Intel 64';
    IMAGE_FILE_MACHINE_MIPS16   :Result:='MIPS';
    IMAGE_FILE_MACHINE_ALPHA64  :Result:='ALPHA64';
    IMAGE_FILE_MACHINE_MIPSFPU  :Result:='MIPS';
    IMAGE_FILE_MACHINE_MIPSFPU16:Result:='MIPS';
    IMAGE_FILE_MACHINE_AMD64    :Result:='AMD K8';
    IMAGE_FILE_MACHINE_TRICORE  :Result:='Infineon';
    IMAGE_FILE_MACHINE_CEF      :Result:='CEF';
    else Result:='未知';
  end;
end;

{ 返回文件特性值 }
function TExeImage.CheckFileCharacteristics(Value:Cardinal):String;
  function BeTrue(fg:Cardinal):Boolean;
  begin
    Result:=fg and not Value=0;
  end;
var
  tmpStr:String;
begin
  tmpStr:='';
  if BeTrue(IMAGE_FILE_RELOCS_STRIPPED) then
     tmpStr:='不含重定位信息';
  if BeTrue(IMAGE_FILE_EXECUTABLE_IMAGE) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'可执行文件';
  end;
  if BeTrue(IMAGE_FILE_LINE_NUMS_STRIPPED) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'不含行号';
  end;
  if BeTrue(IMAGE_FILE_LOCAL_SYMS_STRIPPED) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'不含局部符号';
  end;
  if BeTrue(IMAGE_FILE_AGGRESIVE_WS_TRIM) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'安全工作集';
  end;
  if BeTrue(IMAGE_FILE_LARGE_ADDRESS_AWARE) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'句柄大于2G';
  end;
  if BeTrue(IMAGE_FILE_BYTES_REVERSED_LO) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'保留低位字节';
  end;
  if BeTrue(IMAGE_FILE_32BIT_MACHINE) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'32位机文件';
  end;
  if BeTrue(IMAGE_FILE_DEBUG_STRIPPED) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'不含调试信息';
  end;
  if BeTrue(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'可移动映像执行文件';
  end;
  if BeTrue(IMAGE_FILE_NET_RUN_FROM_SWAP) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'网络映像执行文件';
  end;
  if BeTrue(IMAGE_FILE_SYSTEM) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'系统文件';
  end;
  if BeTrue(IMAGE_FILE_DLL) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'DLL文件';
  end;
  if BeTrue(IMAGE_FILE_UP_SYSTEM_ONLY) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'仅是系统文件';
  end;
  if BeTrue(IMAGE_FILE_BYTES_REVERSED_HI) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'保留高位字节';
  end;

  result:=tmpStr;
end;

{ 返回块表特性值 }
function TExeImage.CheckSectionCharacteristics(Value:Cardinal):String;
  function BeTrue(fg:Cardinal):Boolean;
  begin
    Result:=fg and not Value=0;
  end;
var
  tmpStr:String;
begin
  tmpStr:='';
  if BeTrue(IMAGE_SCN_CNT_CODE) then
     tmpStr:='含代码';
  if BeTrue(IMAGE_SCN_CNT_INITIALIZED_DATA) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'含初始数据';
  end;
  if BeTrue(IMAGE_SCN_CNT_UNINITIALIZED_DATA) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'含未初始数据';
  end;
  if BeTrue(IMAGE_SCN_LNK_INFO) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'含文字说明或其他信息';
  end;
  if BeTrue(IMAGE_SCN_LNK_REMOVE) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'此节不被放入最终EXE文件中';
  end;
  if BeTrue(IMAGE_SCN_LNK_COMDAT) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'含COMDAT';
  end;
  if BeTrue(IMAGE_SCN_LNK_NRELOC_OVFL) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'含扩展重定位信息';
  end;
  if BeTrue(IMAGE_SCN_MEM_DISCARDABLE) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'可丢弃';
  end;
  if BeTrue(IMAGE_SCN_MEM_NOT_CACHED) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'不可隐藏';
  end;
  if BeTrue(IMAGE_SCN_MEM_NOT_PAGED) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'不可分页';
  end;
  if BeTrue(IMAGE_SCN_MEM_SHARED) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'可共享';
  end;
  if BeTrue(IMAGE_SCN_MEM_EXECUTE) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'可执行';
  end;
  if BeTrue(IMAGE_SCN_MEM_READ) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'可读';
  end;
  if BeTrue(IMAGE_SCN_MEM_WRITE) then
  begin
     if tmpStr<>'' then tmpStr:=tmpStr+',';
     tmpStr:=tmpStr+'可写';
  end;

  result:=tmpStr;

end;

{ 返回分析的Coff头信息 }
function TExeImage.AnalysisCoffHeader: Variant;
var
  V: Variant;
  tmpStr:String;
  tmpExeOffSet: Integer;
  tmpDt: TDateTime;
  tmpFt: TFileTime;
  tmpSt: TSystemTime;
begin
  v:=VarArrayCreate([0,7],varVariant);
  tmpExeOffSet:=FPEDosHead._lfanew;
  with FPENTHead.FileHeader do
  begin
    v[0]:=VarArrayOf([tmpExeOffSet+0,Format('%.8x',[FPENTHead.Signature]),'PE文件头标志']);

    tmpStr:=CheckFileMachine(Machine);
    v[1]:=VarArrayOf([tmpExeOffSet+4,Format('%.4x',[Machine]),Format('运行所需要的CPU: %s',[tmpStr])]);
    v[2]:=VarArrayOf([tmpExeOffSet+6,Format('%.4x',[NumberOfSections]),'文件的块表数']);

{
    tmpSt.wYear:=1980;
    tmpSt.wMonth:=7;
    tmpSt.wDay:=6;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -