PE文件格式分析心得

    技术2022-05-11  112

      PE文件格式最近好像炒得沸沸扬扬,由于我正在做一个这样的程序,索性将自己的一点心得写出来与大家同享。   PE文件头分两大部分: 1:DOS ‘MZ’ HEADER 2:IMAGE_NT_HEADERS   其中IMAGE_NT_HEADERS中包含 PE signature IMAGE_FILE_HEADER IMAGE_OPTIONAL_HEADER(其中包含Data Direcotry)   文件头后紧跟着为 Section Table (array of IMAGE_SECTION_HEADERs)   在DELPHI的windows.pad中已经有定义的有: TImageDosHeader; TImageNtHeaders; TImageSectionHeader; { size of TIm..der is $28 }   定义变量后按住Ctrl可以察看具体的项目,这里我就不多说了,这方面的东西也很多。   而其他的如TImageResourceDirectory等,在DELPHI中却没有定义,察看其他资料,我在这里给出他们的结构和简单说明:   以下是我写的PEDump.exe的类型说明:

    type   PIMAGE_RESOURCE_DIRECTORY = ^TImageResourceDirectory;   _IMAGE_RESOURCE_DIRECTORY = packed record     Characteristics:DWORD;     TimeDateStamp:DWORD;     MajorVersion:WORD;     MinorVersion:WORD;     NumberOfNamedEntries:WORD;     NumberOfIdEntries:WORD;   end;   TImageResourceDirectory = _IMAGE_RESOURCE_DIRECTORY;   { 资源目录的格式说明 }

      PIMAGE_RESOURCE_DIRECTORY_ENTRY = ^TImageResourceDirectoryEntry;   _IMAGE_RESOURCE_DIRECTORY_ENTRY = packed record     Name:DWORD;         { NameOffset:31,NameIsString:1 } //    Id:WORD;     OffsetToData:DWORD; { OffsetToDirectory:31,DataIsDirectory:1 }   end;   TImageResourceDirectoryEntry = _IMAGE_RESOURCE_DIRECTORY_ENTRY;   { 资源目录进入点的格式说明 }

      PIMAGE_RESOURCE_DIRECTORY_STRING = ^TImageResourceDirectoryString;   _IMAGE_RESOURCE_DIRECTORY_STRING = packed record     Length:WORD;     NameString:CHAR;   end;   TImageResourceDirectoryString = _IMAGE_RESOURCE_DIRECTORY_STRING;   { 资源目录名的格式说明 }

      PIMAGE_RESOURCE_DIR_STRING_U = ^TImageResourceDirStringU;   _IMAGE_RESOURCE_DIR_STRING_U = packed record     Length:WORD;     NameString:WCHAR;   end;   TImageResourceDirStringU = _IMAGE_RESOURCE_DIR_STRING_U;   { unicode形式的资源目录名的格式说明 }

      PIMAGE_RESOURCE_DATA_ENTRY = ^TImageResourceDataEntry;   _IMAGE_RESOURCE_DATA_ENTRY = packed record     OffsetToData:DWORD;     Size:DWORD;     CodePage:DWORD;     Reserved:DWORD;   end;   TImageResourceDataEntry = _IMAGE_RESOURCE_DATA_ENTRY;   { 资源目录数据进入点的格式说明 }

    const   IMAGE_RESOURCE_NAME_IS_STRING = $80000000;   { 检测TImageResourceDirectoryEntry.Name的最高为是否设立,     是则说明剩下的31位指向IMAGE_RESOURCE_DIR_STRING_U的偏移,     否则说明剩下的31位为一个整数ID。 }   IMAGE_RESOURCE_DATA_IS_DIRECTORY = $80000000;   { 检测TImageResourceDirectoryEntry.OffsetToData的最高为是否设立,     是则说明剩下的31位指向另一个IMAGE_RESOURCE_DIRECTORY的偏移,     否则说明剩下的31位指向IMAGE_RESOURCE_DATA_ENTRY的偏移。 }

      { 以下是文件属性具体值常量说明 }   { File Characteristics }   IMAGE_FILE_RELOCS_STRIPPED           = $0001;  // Relocation info stripped from file.   IMAGE_FILE_EXECUTABLE_IMAGE          = $0002;  // File is executable  (i.e. no unresolved externel references).   IMAGE_FILE_LINE_NUMS_STRIPPED        = $0004;  // Line nunbers stripped from file.   IMAGE_FILE_LOCAL_SYMS_STRIPPED       = $0008;  // Local symbols stripped from file.   IMAGE_FILE_AGGRESIVE_WS_TRIM         = $0010;  // Agressively trim working set   IMAGE_FILE_LARGE_ADDRESS_AWARE       = $0020;  // App can handle >2gb addresses   IMAGE_FILE_BYTES_REVERSED_LO         = $0080;  // Bytes of machine word are reversed.   IMAGE_FILE_32BIT_MACHINE             = $0100;  // 32 bit word machine.   IMAGE_FILE_DEBUG_STRIPPED            = $0200;  // Debugging info stripped from file in .DBG file   IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   = $0400;  // If Image is on removable media, copy and run from the swap file.   IMAGE_FILE_NET_RUN_FROM_SWAP         = $0800;  // If Image is on Net, copy and run from the swap file.   IMAGE_FILE_SYSTEM                    = $1000;  // System File.   IMAGE_FILE_DLL                       = $2000;  // File is a DLL.   IMAGE_FILE_UP_SYSTEM_ONLY            = $4000;  // File should only be run on a UP machine   IMAGE_FILE_BYTES_REVERSED_HI         = $8000;  // Bytes of machine word are reversed.

      { 以下是文件头机器属性值的具体说明 }   { Machine }   IMAGE_FILE_MACHINE_UNKNOWN           = $0;   IMAGE_FILE_MACHINE_I386              = $014c;  // Intel 386.   IMAGE_FILE_MACHINE_R3000             = $0162;  // MIPS little-endian, $160 big-endian   IMAGE_FILE_MACHINE_R4000             = $0166;  // MIPS little-endian   IMAGE_FILE_MACHINE_R10000            = $0168;  // MIPS little-endian   IMAGE_FILE_MACHINE_WCEMIPSV2         = $0169;  // MIPS little-endian WCE v2   IMAGE_FILE_MACHINE_ALPHA             = $0184;  // Alpha_AXP   IMAGE_FILE_MACHINE_SH3               = $01a2;  // SH3 little-endian   IMAGE_FILE_MACHINE_SH3E              = $01a4;  // SH3E little-endian   IMAGE_FILE_MACHINE_SH4               = $01a6;  // SH4 little-endian   IMAGE_FILE_MACHINE_SH5               = $01a8;  // SH5   IMAGE_FILE_MACHINE_ARM               = $01c0;  // ARM Little-Endian   IMAGE_FILE_MACHINE_THUMB             = $01c2;   IMAGE_FILE_MACHINE_ARM33             = $01d3;   IMAGE_FILE_MACHINE_POWERPC           = $01F0;  // IBM PowerPC Little-Endian   IMAGE_FILE_MACHINE_IA64              = $0200;  // Intel 64   IMAGE_FILE_MACHINE_MIPS16            = $0266;  // MIPS   IMAGE_FILE_MACHINE_ALPHA64           = $0284;  // ALPHA64   IMAGE_FILE_MACHINE_MIPSFPU           = $0366;  // MIPS   IMAGE_FILE_MACHINE_MIPSFPU16         = $0466;  // MIPS //  IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64   IMAGE_FILE_MACHINE_AMD64             = $0500;  // AMD K8   IMAGE_FILE_MACHINE_TRICORE           = $0520;  // Infineon   IMAGE_FILE_MACHINE_CEF               = $0CEF;

      { 以下是SECTION的属性值具体说明 }   { Section characteristics } //  IMAGE_SCN_TYPE_REG                   = $00000000;  // Reserved. //  IMAGE_SCN_TYPE_DSECT                 = $00000001;  // Reserved. //  IMAGE_SCN_TYPE_NOLOAD                = $00000002;  // Reserved. //  IMAGE_SCN_TYPE_GROUP                 = $00000004;  // Reserved.   IMAGE_SCN_TYPE_NO_PAD                = $00000008;  // Reserved. //  IMAGE_SCN_TYPE_COPY                  = $00000010;  // Reserved.

      IMAGE_SCN_CNT_CODE                   = $00000020;  // Section contains code.   IMAGE_SCN_CNT_INITIALIZED_DATA       = $00000040;  // Section contains initialized data.   IMAGE_SCN_CNT_UNINITIALIZED_DATA     = $00000080;  // Section contains uninitialized data.

      IMAGE_SCN_LNK_OTHER                  = $00000100;  // Reserved.   IMAGE_SCN_LNK_INFO                   = $00000200;  // Section contains comments or some other type of information. //  IMAGE_SCN_TYPE_OVER                  = $00000400;  // Reserved.   IMAGE_SCN_LNK_REMOVE                 = $00000800;  // Section contents will not become part of image.   IMAGE_SCN_LNK_COMDAT                 = $00001000;  // Section contents comdat. //                                       = $00002000;  // Reserved. //  IMAGE_SCN_MEM_PROTECTED - Obsolete   = $00004000;   IMAGE_SCN_NO_DEFER_SPEC_EXC          = $00004000;  // Reset speculative exceptions handling bits in the TLB entries for this section.   IMAGE_SCN_GPREL                      = $00008000;  // Section content can be accessed relative to GP   IMAGE_SCN_MEM_FARDATA                = $00008000; //  IMAGE_SCN_MEM_SYSHEAP  - Obsolete    = $00010000;   IMAGE_SCN_MEM_PURGEABLE              = $00020000;   IMAGE_SCN_MEM_16BIT                  = $00020000;   IMAGE_SCN_MEM_LOCKED                 = $00040000;   IMAGE_SCN_MEM_PRELOAD                = $00080000;

      IMAGE_SCN_ALIGN_1BYTES               = $00100000;  //   IMAGE_SCN_ALIGN_2BYTES               = $00200000;  //   IMAGE_SCN_ALIGN_4BYTES               = $00300000;  //   IMAGE_SCN_ALIGN_8BYTES               = $00400000;  //   IMAGE_SCN_ALIGN_16BYTES              = $00500000;  // Default alignment if no others are specified.   IMAGE_SCN_ALIGN_32BYTES              = $00600000;  //   IMAGE_SCN_ALIGN_64BYTES              = $00700000;  //   IMAGE_SCN_ALIGN_128BYTES             = $00800000;  //   IMAGE_SCN_ALIGN_256BYTES             = $00900000;  //   IMAGE_SCN_ALIGN_512BYTES             = $00A00000;  //   IMAGE_SCN_ALIGN_1024BYTES            = $00B00000;  //   IMAGE_SCN_ALIGN_2048BYTES            = $00C00000;  //   IMAGE_SCN_ALIGN_4096BYTES            = $00D00000;  //   IMAGE_SCN_ALIGN_8192BYTES            = $00E00000;  // // Unused                                = $00F00000;   IMAGE_SCN_ALIGN_MASK                 = $00F00000;

      IMAGE_SCN_LNK_NRELOC_OVFL            = $01000000;  // Section contains extended relocations.   IMAGE_SCN_MEM_DISCARDABLE            = $02000000;  // Section can be discarded.   IMAGE_SCN_MEM_NOT_CACHED             = $04000000;  // Section is not cachable.   IMAGE_SCN_MEM_NOT_PAGED              = $08000000;  // Section is not pageable.   IMAGE_SCN_MEM_SHARED                 = $10000000;  // Section is shareable.   IMAGE_SCN_MEM_EXECUTE                = $20000000;  // Section is executable.   IMAGE_SCN_MEM_READ                   = $40000000;  // Section is readable.   IMAGE_SCN_MEM_WRITE                  = $80000000;  // Section is writeable.

      我写了检测是否包含此属性的函数   function BeTrue(fg:Cardinal,Value):Boolean;   begin     Result:=fg and not Value=0;   end;   如果fg的属性值在Value中,则为True,否则为False;   例如  BeTrue(IMAGE_FILE_RELOCS_STRIPPED,PENTHead.FileHeader.Characteristics);

      至于资源目录的读取,至少需要两重循环来定位,具体实现就要靠你的算法功力了:)

      2001年04月26日 西安


    最新回复(0)