发新话题
打印

[转载]PE文件格式分析心得

[转载]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);  

  至于资源目录的读取,至少需要两重循环来定位,具体实现就要靠你的算法功力了:)
人情如冰六月寒,花做一份艳,为谁笑人间? 如果任何人发现我转载的有图像的文章中图像失效或者文章有问题,请及时短消息通知我。先谢谢。::)) coup de foudre

TOP

发新话题