PE文件格式分析心得

来源:互联网 发布:c语言项目实战 编辑:程序博客网 时间:2024/04/30 01:44

PE文件格式分析心得

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. 
  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); 

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

原创粉丝点击