与大家分享PE文件格式分析心得(100分)

  • 主题发起人 主题发起人 mantousoft
  • 开始时间 开始时间
M

mantousoft

Unregistered / Unconfirmed
GUEST, unregistred user!
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);
至于资源目录的读取,至少需要两重循环来定位,具体实现就要靠你的算法功力了:)
好了,差不多了,再具体一点我也说不上了,我做了一个PEDump的程序,
在我的主页http://mantousoft.51.net可以下载,程序中有更详细的说明,相信能帮助想了解这方面的东西的朋友。
以上是我的个人小心得,欢迎转载,转载请保持完整,谢谢!
 
csdn上的是不是你写的?
 
对,也是我贴的,不过贴错地方了,贴到VC分类了,我已经通知版主了:)
 
接受答案了.
 
后退
顶部