zoukankan      html  css  js  c++  java
  • How to detect the types of executable files

    How to detect the types of executable files

    type
    
      {
      IMAGE_DOS_HEADER:
        DOS .EXE header.
      }
      IMAGE_DOS_HEADER = packed record
        e_magic   : Word;               // Magic number ("MZ")
        e_cblp    : Word;               // Bytes on last page of file
        e_cp      : Word;               // Pages in file
        e_crlc    : Word;               // Relocations
        e_cparhdr : Word;               // Size of header in paragraphs
        e_minalloc: Word;               // Minimum extra paragraphs needed
        e_maxalloc: Word;               // Maximum extra paragraphs needed
        e_ss      : Word;               // Initial (relative) SS value
        e_sp      : Word;               // Initial SP value
        e_csum    : Word;               // Checksum
        e_ip      : Word;               // Initial IP value
        e_cs      : Word;               // Initial (relative) CS value
        e_lfarlc  : Word;               // Address of relocation table
        e_ovno    : Word;               // Overlay number
        e_res     : packed array [0..3] of Word;  // Reserved words
        e_oemid   : Word;               // OEM identifier (for e_oeminfo)
        e_oeminfo : Word;               // OEM info; e_oemid specific
        e_res2    : packed array [0..9] of Word;  // Reserved words
        e_lfanew  : Longint;            // File address of new exe header
      end;
    
      {
      TExeFileKind:
        The kinds of files recognised.
      }
      TExeFileKind = (
        fkUnknown,  // unknown file kind: not an executable
        fkError,    // error file kind: used for files that don't exist
        fkDOS,      // DOS executable
        fkExe32,    // 32 bit executable
        fkExe16,    // 16 bit executable
        fkDLL32,    // 32 bit DLL
        fkDLL16,    // 16 bit DLL
        fkVXD       // virtual device driver
      );
        
    function ExeType(const FileName: string): TExeFileKind;
      {Examines given file and returns a code that indicates the type of
      executable file it is (or if it isn't an executable)}
    const
      cDOSRelocOffset = $18;  // offset of "pointer" to DOS relocation table
      cWinHeaderOffset = $3C; // offset of "pointer" to windows header in file
      cNEAppTypeOffset = $0D; // offset in NE windows header of app type field
      cDOSMagic = $5A4D;      // magic number for a DOS executable
      cNEMagic = $454E;       // magic number for a NE executable (Win 16)
      cPEMagic = $4550;       // magic nunber for a PE executable (Win 32)
      cLEMagic = $454C;       // magic number for a Virtual Device Driver
      cNEDLLFlag = $80        // flag in NE app type field indicating a DLL
    var
      FS: TFileStream;              // stream to executable file
      WinMagic: Word;               // word containing PE or NE magic numbers
      HdrOffset: LongInt;           // offset of windows header in exec file
      ImgHdrPE: IMAGE_FILE_HEADER;  // PE file header record
      DOSHeader: IMAGE_DOS_HEADER;  // DOS header
      AppFlagsNE: Byte;             // byte defining DLLs in NE format
      DOSFileSize: Integer;         // size of DOS file
    begin
      try
        // Open stream onto file: raises exception if can't be read
        FS := TFileStream.Create(FileName, fmOpenRead + fmShareDenyNone);
        try
          // Assume unkown file
          Result := fkUnknown;
          // Any exec file is at least size of DOS header long
          if FS.Size < SizeOf(DOSHeader) then
            Exit;
          FS.ReadBuffer(DOSHeader, SizeOf(DOSHeader));
          // DOS files begin with "MZ"
          if DOSHeader.e_magic <> cDOSMagic then
            Exit;
          // DOS files have length >= size indicated at offset $02 and $04
          // (offset $02 indicates length of file mod 512 and offset $04
          // indicates no. of 512 pages in file)
          if (DOSHeader.e_cblp = 0) then
            DOSFileSize := DOSHeader.e_cp * 512
          else
            DOSFileSize := (DOSHeader.e_cp - 1) * 512 + DOSHeader.e_cblp;
          if FS.Size <  DOSFileSize then
            Exit;
          // DOS file relocation offset must be within DOS file size.
          if DOSHeader.e_lfarlc > DOSFileSize then
            Exit;
          // We assume we have an executable file: assume its a DOS program
          Result := fkDOS;
          // Try to find offset of Windows program header
          if FS.Size <= cWinHeaderOffset + SizeOf(LongInt) then
            // file too small for windows header "pointer": it's a DOS file
            Exit;
          // read it
          FS.Position := cWinHeaderOffset;
          FS.ReadBuffer(HdrOffset, SizeOf(LongInt));
          // Now try to read first word of Windows program header
          if FS.Size <= HdrOffset + SizeOf(Word) then
            // file too small to contain header: it's a DOS file
            Exit;
          FS.Position := HdrOffset;
          // This word should be NE, PE or LE per file type: check which
          FS.ReadBuffer(WinMagic, SizeOf(Word));
          case WinMagic of
            cPEMagic:
            begin
              // 32 bit Windows application: now check whether app or DLL
              if FS.Size < HdrOffset + SizeOf(LongWord) + SizeOf(ImgHdrPE) then
                // file not large enough for image header: assume DOS
                Exit;
              // read Windows image header
              FS.Position := HdrOffset + SizeOf(LongWord);
              FS.ReadBuffer(ImgHdrPE, SizeOf(ImgHdrPE));
              if (ImgHdrPE.Characteristics and IMAGE_FILE_DLL)
                = IMAGE_FILE_DLL then
                // characteristics indicate a 32 bit DLL
                Result := fkDLL32
              else
                // characteristics indicate a 32 bit application
                Result := fkExe32;
            end;
            cNEMagic:
            begin
              // We have 16 bit Windows executable: check whether app or DLL
              if FS.Size <= HdrOffset + cNEAppTypeOffset
                + SizeOf(AppFlagsNE) then
                // app flags field would be beyond EOF: assume DOS
                Exit;
              // read app flags byte
              FS.Position := HdrOffset + cNEAppTypeOffset;
              FS.ReadBuffer(AppFlagsNE, SizeOf(AppFlagsNE));
              if (AppFlagsNE and cNEDLLFlag) = cNEDLLFlag then
                // app flags indicate DLL
                Result := fkDLL16
              else
                // app flags indicate program
                Result := fkExe16;
            end;
            cLEMagic:
              // We have a Virtual Device Driver
              Result := fkVXD;
            else
              // DOS application
              {Do nothing - DOS result already set};
          end;
        finally
          FS.Free;
        end;
      except
        // Exception raised in function => error result
        Result := fkError;
      end;
    end;
  • 相关阅读:
    冒泡排序改
    冒泡排序 (基本类型),(引用类型)
    关于随机数列,对给定数目的自0开始步长为1的数字序列进行乱序。(可用作洗牌)
    Java基础之 移位操作
    保留代码,狼羊过河的问题(暂未理解)
    非计算机专业学习计算机
    CompletableFuture 捕获异常方式:handle、whenComplete、exceptionally
    nio socket聊天室
    java socket server接收并返回数据
    java socket套接字编程入门
  • 原文地址:https://www.cnblogs.com/shangdawei/p/4787776.html
Copyright © 2011-2022 走看看