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); 至于资源目录的读取,至少需要两重循环来定位,具体实现就要靠你的算法功力了:) |
PE文件格式分析心得
最新推荐文章于 2021-09-29 22:15:04 发布