pe文件格式

xmyth

贡献于2015-09-20

字数:19846 关键词:

1. 2. MS-DOS头,IMAGE_DOS_HEADER结构体 typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_crlc; // Relocations WORD e_cparhdr; // Size of header in paragraphs WORD e_minalloc; // Minimum extra paragraphs needed WORD e_maxalloc; // Maximum extra paragraphs needed WORD e_ss; // Initial (relative) SS value WORD e_sp; // Initial SP value WORD e_csum; // Checksum WORD e_ip; // Initial IP value WORD e_cs; // Initial (relative) CS value WORD e_lfarlc; // File address of relocation table WORD e_ovno; // Overlay number WORD e_res[4]; // Reserved words WORD e_oemid; // OEM identifier (for e_oeminfo) WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words LONG e_lfanew; // File address of new exe header } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; 3. DOS Stub 4. PE文件头,位于DOS Stub后面,IMAGE_NT_HEADERS typedef struct _IMAGE_NT_HEADERS{ DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; }IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; ①  Signature字段 PE标识,其值始终为0x50450000,ASCII码为”PE/0/0” ②  FileHeader映像文件头 包含文件的基本信息,指出了文件的区段数量与扩展头的大小 typedef struct _IMAGE_FILE_HEADER{ WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; }IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; 结构说明: 1) Machine:2字节的值,用以指明此文件可以运行于哪种CPU上 2) NumberOfSections:节的数量 3) TimeDateStamp:表明此文件是何时创建的,自1970年1月1日以来的秒数 4) PointerToSymbolTable:指向COFF符号表的偏移指针,已经被Debug格式代替,较少应用(如果符号表不存在,则字段值为0) 5) NumberOfSymbols:符号表中符号的数量 6) SizeOfOptionalHeader:映像扩展头的大小,一般情况下,这个结构的大小在32位的系统中为0x00E0,在64位系统下为0x00F0 7) Characteristics:表示PE文件的属性 ③  映像扩展头 typedef stuct _IMAGE_OPTIONAL_HEADER{ // 标准域 WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; // NT附加域 DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[0x10]; }IMAGE_OPTIONAL_HEADERER32, *PIMAGE_OPTIONAL_HEADER32; 1) Magic:文件类型标识(普通可执行映像0x010B、ROM镜像0x0170) 2) MajorLinkerVersion:链接器的主版本号 3) MinorLinkerVersion:链接器的子版本号 4) SizeOfCode:所有IMAGE_SCN_CNT_CODE属性的区段的总大小(可执行代码),此大小在计算时按照磁盘扇区字节数的整数倍计算 5) SizeOfInitializedData:已初始化的数据块大小 6) SizeOfUninitializedData:未初始化的数据块大小,装载程序需要在虚拟地址空间中为这些数据保留空间,但是这些块在磁盘中并不占用任何空间,未初始化的数据通常位于名为.bbs的区段中 7) AddressOfEntryPoint:程序执行入口的RVA,这个入口点在DLL文件中可以被置为0 8) BaseOfCode:代码段的起始RVA(代码段通常位于PE文件头与数据块之间) 9) BaseOfData:数据段的起始RVA(数据段通常位于PE文件头与代码段之后) 10) ImageBase:文件在内存中的首选装入地址,默认为0x00400000,如果载入成功,则装载器将跳过应用基址重定位的步骤 11) SectionAlignment:映像文件在被装入内存时的区段对齐大小,通常为0x00001000 12) FileAlignment:映像文件在磁盘上的区段对齐大小,通常为0x00000200 13) MajorOperatingSystemVersion:要求操作系统最低版本的主版本号 14) MinorOperatingSystemVersion:要求操作系统最低版本的子版本号 15) MajorImageVersion:此可执行文件的主版本号 16) MinorImageVersion:此可执行文件的子版本号 17) MajorSubsystemVersion:要求最低子系统的主版本号 18) MinorSubsystemVersion:要求最低子系统的子版本号 19) Win32VersionValue:保留值,必须为0 20) SizeOfImage:映像文件装入内存后的总大小(从Image Base到最后一个区段的总大小),每个节单独需要的数量和,按照内存对齐大小对齐 21) SizeOfHeaders:文件头部的大小,按照文件对齐大小对齐 22) CheckSum:映像文件的校验和 23) Subsystem:可执行文件所期望的子系统值 24) DllCharacteristics:DLL 文件属性。它是一个标志集,不是针对 DLL 文件的,而是针对所有 PE 文件的,默认为0 25) SizeOfStackReserve:在EXE文件中,初始化线程时保留栈的大小,该字段表示为初始线程的栈而保留的虚拟内存数量,然而并不是保留的所有虚拟内存都做栈(真正的栈大小由下一个字段 SizeOfStackCommit 决定) 26) SizeOfStackCommit:在EXE文件中,初始化线程时实际提交的栈大小 27) SizeOfHeapReserve:在EXE文件中,初始化进程时保留的堆大小 28) SizeOfHeapCommit:在EXE文件中,初始化进程时实际提交的堆大小 29) LoaderFlags:与调试相关,默认为0 30) NumberOfRvaAndSizes:数据目录成员的数量,一般为16个 31) 映像扩展头的末尾定位了PE文件中重要信息的地址簿——数据目录 typedef struct _IMAGE_DATA_DIRECTORY{ DWORD VritualAddress; // 数据块的相对虚拟地址(载入内存后) DWORD Size; // 数据块的长度 } 依次为: ①  Export Directory:导出表目录 ②  Import Directory:导入表目录 ③  Resource Directory:资源目录 ④  Exception Directory:异常目录 ⑤  Security Directory:安全目录 ⑥  Base Relocation Table:基址重定位表 ⑦  Debug Directory:调试目录 ⑧  Architecture Specific Data:版权(特殊)数据,保留字段,必须为0 ⑨  RVA of GP:全局指针偏移目录 ⑩  TLS Directory:TLS(线程局部存储器)目录,其本质上属于一个局部变量,单独存在于每个线程中 ⑪  Load Configuration Directory:载入配置目录 ⑫  Bound Import Directory in headers:绑定输入目录 ⑬  Import Address Table:导入地址表,保存导入函数的真正地址 ⑭  Delay Load Import Descriptors:延迟导入描述符 ⑮  COM Runtime Descriptor:COM运行时描述符目录 如何定位数据目录在文件中的地址? 5. 节头 PE头的数据目录表后是就是区段表(节头),区段表用来描述位于其后各个区段的各种属性 节头是由数个首尾相连的IMAGE_SECTION_HEADER结构体数组构成的 typedef struct _IMAGE_SECTION_HEADER{ BYTE Name[0x8]; union{ DWORD PhysicalAddress; DWORD VirtualSize; }Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; }IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 1) Name:区段名,一般是以 ’\0’ 结尾的 ASCII 码字符串 2) Misc:共用体,VirtualSize表示实际被使用的区段大小(即区段在未做对齐处理前的大小)待验证?,该值不准确 3) VirtualAddress:此区段的RVA,这个地址是按照内存页对齐的。通过使用此域中的值并加上可选头结构中的ImageBase中的虚拟地址就可以得到实际的地址 4) SizeOfRawData:此区段在磁盘中的体积,这个大小是按照文件页对齐的 5) PointerToRawData:此区段在文件中的偏移 6) PointerToRelocations:此区段重定位表的偏移地址 7) PointerToLinenumbers:行号表在文件中的偏移 8) NumberOfRelocations:此区段重定位表项的数量 9) NumberOfLinenumbers:行号表项的数量 10) Characteristics:区段属性 6. 节 ①  可执行代码节:.text ②  数据节:.bss,.rdata,.data .bss节代表的是应用程序的未初始化的数据,包括一个函数或者源模块中所有声明为静态的变量 .rdata节代表的是只读数据,比如:字符串、常量以及调试目录信息等 所有其它的变量(除了自动变量,它只出现在栈中)都存储在.data节中,基本上是应用程序和模块的全局变量 ③  资源节:.rsrc 数据目录中的IMAGE_DIRECTORY_ENTRY_RESOURCE项指向此结构 一般目录分为3层结构,从根目录开始分别为资源类型、目录资源ID与资源代码页。 这三层目录结构都是由一个IMAGE_RESOURCE_DIRECTORY结构为头部,后面跟着一个IMAGE_RESOURCE_DIRECTORY_ENTRY结构数组。 typedef struct _IMAGE_RESOURCE_DIRECTORY{ DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; WORD NumberOfNamedEntries; WORD NumberOfIdEntries; }IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY; 1) Characteristics:资源属性,一般为0 2) TimeDateStamp:资源建立的时间 3) MajorVersion:资源的主版本,一般为0x0004 4) MinorVersion:资源的子版本,一般为0x0000 5) NumberOfNamedEntries:用字符串作为资源标识的条目个数 6) NumberOfIdEntries:用数字ID作为资源标识的条目个数 通过NumberOfNamedEntries和NumberOfIdEntries的值指出其后IMAGE_RESOURCE_DIRECTORY_ENTRY结构数组的成员个数。 typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY{ union{ struct{ DWORD NameOffset:32; DWORD NameIsString:1; }; DWORD Name; WORD Id; }; union{ DWORD OffsetToData; struct{ DWORD OffsetToDirectory:31; DWORD DataIsDirectory:1; }; }; }IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY; 1) NameOffset:当字段NameIsString为1 时,此字段的值为资源名字符串的偏移(相对资源目录起始地址的偏移) 2) NameIsString:资源名为字符串,当此值为1时,NameOffset会指向一个IMAGE_RESOURCE_DIR_STRING_U结构体,此结构体保存着资源名称,其数据结构如下: typedef struct _IMAGE_RESOURCE_DIR_STRING_U{ WORD Length; // 长度 WCHAR NameString[1]; // 字符串数组首地址 }IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U; 3) Name:此结构位于第一层时,字段表示资源类型;第二层时,表示资源标识;第三层时,表示语言类型 4) Id:资源的数字ID 5) OffsetToData:指向数据偏移(相对资源目录起始地址的偏移) 6) OffsetToDirectory:当字段DataIsDirectory为1时,此字段的值指向下一层子目录的偏移(相对资源目录起始地址的偏移) 7) DataIsDirectory:与上个字段搭配使用,为1表示目录 第一个联合体内的字段是根据当前结构体所处的目录层次来决定的,位于第一层目录时字段Name有效,保存的信息是资源类型;位于第二层目录时字段ID或结构体有效,取决于资源的索引方式;位于第三层目录时字段Name有效,保存的信息是资源语言区域类型。 ①  第一个联合体 (1) 当字段最高位为 1 当结构用于第一层目录时,表示这是一个非标准的类型。由该字段的低 31 位组成一个偏移值,该偏移是相对于资源基地址的特殊偏移地址。该地址指向一个 IMAGE_RESOURCE_DIR_STRING_U 结构表示的 Unicode 字符串,字符串为非标准的类型的名字 当结构用于第二层目录时,表示这是一个非标准的命名。由该字段的低 31 位组成一个偏移值,该偏移是相对于资源基地址的特殊偏移地址。 当结构用于第三层目录时,表示这是一个非标准的语言(没有预定义的代码页)。由该字段低31位组成一个偏移值,该偏移是相对于资源基地址的特殊偏移地址 (2) 字段最高位为 0 当结构用于第一层目录时,表示这是标准的类型(预定义的类型),由该字段的低16位组成整数标识符ID 当结构用于第二层目录时,表示这是标准的命名(预定义的类型),由该字段的低16位组成整数标识符ID来定义名字 当结构用于第三层目录时,表示这是标准的语言代码(预定义的类型),由该字段的低16位组成整数标识符ID,可以通过该标识符获取预先定义的语言的名称 ②  第二个联合体 (1) 字段最高位为 1 当结构用于第一目录时,由该字段低31位组成一个整数偏移地址,该地址是相对于资源起始地址的偏移,该偏移指向下一层目录 当结构用于第二目录时,由该字段低31位组成一个整数偏移地址,该地址是相对于资源起始地址的偏移,该偏移指向下一层目录 第三层目录的该值第31位不为1 (2) 字段最高位为 0 第一层目录的该值第31位不为 0 第二层目录的该值第31位不为 0 当结构用于第三层目录时,表示该字段指向一个数据项 IMAGE_RESOURCE_DATA_ENTRY,相对于资源起始地址的偏移???? 第二个联合体内的字段是根据具体情况而定的,如果下一级是一个子目录的话,那么就是结构体生效,如果下一级是资源数据则是字段OffsetToData生效。 在经过三层目录的索引后,最后会到达一个IMAGE_RESOURCE_DATA_ENTRY结构中,这个结构将指引我们找到资源数据 typedef struct _IMAGE_RESOURCE_DATA_ENTRY{ DWORD OffsetToData; DWORD Size; DWORD CodePage; DWORD Reserved; }IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY; 1) OffsetToData:资源数据RVA,基于ImageBase 2) Size:资源数据的大小 3) CodePage:此资源的代码页信息 4) Reserved:保留字段,恒为0 .rsrc结构图 ④  导出表 导出表是PE文件为其他应用程序提供API的一种函数示例导出方式。 IMAGE_EXPORT_DIRECTORY(导出表)结构如下: typedef struct _IMAGE_EXPORT_DIRECTORY{ DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; DWORD AddressOfFunctions; DWORD AddressOfNames; DWORD AddressOfNameOrdinals; }IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; 1) Characteristics:保留,恒为0 2) TimeDateStamp:导出表创建的时间(GMT时间) 3) MajorVersion:导出表的主版本号 4) MinorVersion:导出表的子版本号 5) Name:此导出表所在模块名称的ASCII字符的RVA 6) Base:导出表用于输出API函数索引值的基数(文件中保存的序号(原始序号) = 调用序号 - 基数) 7) NumberOfFunctions:导出地址表(EAT)中的条目数量 8) NumberOfNames:导出名称表(ENT)中的条目数量 9) AddressOfFunctions:导出地址表(EAT)的RVA,EAT中的每一个非0的项都对应一个被导出的函数名称或序号 10) AddressOfNames:导出名称表(ENT)的RVA,ENT和EAT中的每一个非0的项都对应一个被导出的函数地址或序号 11) AddressOfNameOrdinals:导出序号表的RVA 导出表由3部分构成,分别是名称表、函数表与序号表,其中函数表与序号表是必须要有的,而名称表是可选的。序号表与名称表的作用就是索引,函数表保存的就是这个被导出的函数地址信息。 导出名称表里存放的是存放函数名称字符串地址的RVA,需要再进行一个地址的转换才能找到真正存放函数名称字符串的地址 导出序列号表里序号是用WORD类型存放 导出地址表里函数地址是用DWORD类型存放,用RVA存放 导出名称表里存放函数名称字符串地址是用 DWORD类型存放 导出的序号表并不代表其本身在内存或PE文件中的排列顺序,真正的存储顺序是完全被打乱的 调用序号 = 原始序号(文件中保存的序号) + 序号基数 导出地址表、导出序号表、导出名称表的对应关系: 函数地址在导出地址表中的位置就是原始序号,比如导出地址表中第一个成员的地址是0x00001005,那么它的原始序号就为0。如何根据原始序号得到导出函数名呢?这要遍历导出序号表,如果导出序号表中有成员的值等于导出函数的原始序号,说明它也同时以函数名的方式导出,此成员的索引就是它在导出序号表和导出名称表中的位置。导出序号表与导出名称表是一一对应的,导出序号表中是第一个成员,那么对应导出函数名称表也是第一个成员。 ⑤  导入表 导入表机制是PE文件从其他第三方程序中导入API,以供本程序调用的机制。 IMAGE_IMPORT_DESCRIPTOR(导入表)负责引导系统找到真正保存有导入信息的其它两个结构。IMAGE_IMPORT_DESCRIPTOR结构的个数是由导入映像文件的个数决定的,需要从多少个映像文件中导入函数,就要有多个IMAGE_IMPORT_DESCRIPTOR结构,最后会以一个空的IMAGE_IMPORT_DESCRIPTOR结构来结束。 typedef struct _IMAGE_IMPORT_DESCRIPTOR{ union{ DWORD Characteristcis; DWORD OriginalFirstThunk; }; DWORD TimeDateStamp; DWORD ForwarderChain; DWORD Name; DWORD FirstThunk; }IMAGE_IMPORT_DESCRIPTOR; 1) OriginalFirstThunk:包含指向输入名称表(INT)的RVA,INT是一个IMAGE_THUNK_DATA结构的数组,在大多数情况下,数组中的每个IMAGE_THUNK_DATA结构会再指向IMAGE_IMPORT_BY_NAME结构,结尾处则以一个全0x00的IMAGE_THUNK_DATA结构结束 2) TimeDateStamp:32位的时间标识,与下一个转发链字段合并工作,否则可以为空 3) ForwarderChain:控制导入表转发器forwarders的索引值,映像文件可以输出一个没有在本文件内定义的符号,并且这个符号可以是从另一个映像文件引入的,这样的符号称为转发符号。此值为-1时,说明到此文件转发已经结束。当值为0时,证明此文件未启用此机制 4) Name:指向存储导入映像文件名称 5) FirstThunk:指向导入地址表(IAT)的RVA 导入表主要关注OriginalFirstThunk和FirstThunk字段,分别指向了保存导入名称与导入地址的IMAGE_THUNK_DATA结构数组,这个数组以一个空的IMAGE_THUNK_DATA结构结尾。 typedef struct _IMAGE_THUNK_DATA32{ union{ PBYTE ForwarderString; PDWORD Function; DWORD Ordinal; PIMAGE_IMPORT_BY_NAME AddressOfData; }u1; }IMAGE_THUNK_DATA32; 1) ForwarderString:负责与导入表转发器协同工作的一个字段。当导入表的ForwarderChain不为0时,此值有效,并指向包含有转发函数与导出这个函数的映像文件名的字符串RVA 2) Function:导入表导入函数的实际内存地址,此字段仅在此映像被加载,且此结构为IAT的前提下有效 3) Ordinal:导入表导入函数的导出序号,当IMAGE_THUNK_DATA的最高位为1时,此值有效 4) AddressOfData:指向IMAGE_IMPORT_BY_NAME结构,当以上3个值都未生效时,此值有效 Function字段是一个由操作系统使用的字段,PE文件被加载之前,输入表的INT与IAT都是使用AddressOfData字段指向一个IMAGE_IMPORTBY_NAME结构的,但当我们的PE文件被加载时,操作系统首先会逐个遍历INT中的内容,并逐一取出已导入函数的内存地址,然后将这些动态获取的地址逐一填入对应的IAT中 typedef struct _IMAGE_IMPORT_BY_NAME{ WORD Hint; BYTE Name[1]; }IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; 1) Hint:保存本映像导入表需导入的函数序号(原始序号) 2) Name:保存本映像导入表需导入的函数名称 Windows 加载器将与进程相关的 DLL 加载到虚拟地址空间以后,会根据导入表中登记的该动态链接库相关的由 INT 指向的名称或编号来遍历 DLL 所在虚拟地址空间,通过函数名或编号查找导出表结构,从而确定该导出函数在虚拟地址空间中的起始地址 VA,并将该 VA 覆盖导入表的 IAT 相关项 ⑥  重定位表 全局变量的地址(绝对地址)包含在机器码中,而操作数为局部变量或函数参数的指令中均不包含绝对地址。 访问全局变量的时候全部需要重定位,重定位的方法: 第一步:获取当前加载的基址 第二步:减去初始的基址 第三步:加上初始绝对地址 相当于先算出的偏移量,再加上新的基址,得到新的绝对地址 dwVari dd ? call @F @@: pop ebx sub ebx, offset @B mov eax, [ebx + offset dwVari] , 重定位结构是由多个 IMAGE_BASE_RELOCATION 子结构组成的,数组和数组之间并不是相邻的。每个子结构只负责描述一个 4KB 大小的分页内重定位信息,换句话就是 PE 文件中需要重定位的部分每隔 0x1000 字节大小的区域就要有一个 IMAGE_BASE_RELOCATION 结构与之对应。 typedef struct _IMAGE_BASE_RELOCATION{ DWORD VirtualAddress; // 需要重定位数据的起始 RVA DWORD SizeOfBlock; // 本结构与 TypeOffset 总大小 // WORD TypeOffset[1]; // 原则上不属于本结构 } IMAGE_BASE)RELOCATION; 1) VirtualAddress:指向 PE 文件中需要重定位数据的起始RVA,由于每个重定位结构体只负责描述 0x1000 字节大小区域的重定位信息,因此此字段的值总是0x1000 的倍数 2) SizeOfBlock:描述 IMAGE_BASE_RELOCATION 结构体与重定位数组 TypeOffset 的体积总大小 (IMAGE_SIZEOF_BASE_RELOCATION + 2*n) 3) TypeOffset:一个不定长的 WORD 型数组,其本身并不属于 IMAGE_BASE_RELOCATION 结构体。负责与 IMAGE_BASE_RELOCATION 结构体配合描述需要进行重定位的数据的具体偏移,结构如下: struct { WORD Offset:12 // 大小为 12Bit 的重定位偏移 WORD Type:4 // 大小为 4Bit 的重定位信息的类型值 }TypeOffset; 1) Offset:记录位于 VirtualAddress 字段所指分页中的需要重定位的地址 2) Type:重定位信息类型值,如下表所示 重定位信息类型 值 信息 Win 32 SDK 中的宏定义名 0x0 无重定位操作 IMAGE_REL_BASED_ABSOLUTE 0x1 重定位偏移指向位置的高2 字节需要被修正 IMAGE_REL_BASED_HIGH 0x2 重定位偏移指向位置的低 2字节需要被修正 IMAGE_REL_BASED_LOW 0x3 重定位偏移指向的整个 4 字节大小都需要被修正 IMAGE_REL_BASED_HIGHLOW 0x4 ................... IMAGE_REL_BASED_HIGHADJ 0x5 基址重定位应用于 MIPS jump 指令 IMAGE_REL_BASED_MIPS_JMPADDR 0x6 保留 IMAGE_REL_BASED_SECTION 0x9 基址重定位应用于 MIPS 16 jump 指令 IMAGE_REL_BASED_MIPS_JMPADDR16 0x10 重定位偏移指向位置的 8 字节(64 位)地址需要被修正 IMAGE_REL_BASED_DIR64 0x11 未知 IMAGE_REL_BASED_HIGH3ADJ 所有的重定位块最终以一个 VirtualAddress 字段为 0 的 IMAGE_BASE_RELOCATION 结构作为结束 ⑦  延迟导入表 延迟加载导入的概念:系统开始运行程序时被指定的延迟加载的 DLL 是不被载入的,只有等到程序调用了该动态链接库的函数时,系统才将该链接库载入内存空间,并执行相关函数代码 延迟加载导入数据目录指向的位置为延迟加载导入描述结构 IMAGE_DELAY_IMPORT_DESCRIPTOR typedef struct _IMAGE_DELAY_IMPORT_DESCRIPTOR { DWORD Attributes; // 属性,必须为 0 DWORD Name; // 指向 DLL 名称的 VA DWORD ModuleHandle; // DLL 模块句柄的 VA DWORD DelayIAT; // 延迟加载导入 IAT 的 VA DWORD DelayINT; // 延迟加载导入 INT 的 VA DWORD BoundDelayIT; // 绑定延迟加载导入地址表的 VA DWORD UnloadDelayIT; // 卸载延迟加载导入地址表的 VA DWORD TimeStamp; // 此映像绑定到 DLL 的时间戳 } IMAGE_DELAY_IMPORT_DESCRIPTOR; 1) Attirbutes:属性,暂时未用,为 0 2) Name:指向延迟加载导入的动态链接库的名字字符串的地址,该地址是一个 VA 3) ModuleHandle:被延迟加载的 DLL 模块句柄的 VA。该 VA 位于 PE 映像的数据节中,延迟加载辅助函数使用这个位置存储要被延迟加载的 DLL 的模块句柄 4) DelayIAT:延迟加载导入地址表的 VA 5) DelayINT:延迟加载导入名称表,包含了可能需要被加载的导入符号的名称,指向一个 IMAGE_THUNK_DATA 结构数组,这个数组以一个空的 IMAGE_THUNK_DATA 结构结尾 6) BoundDelayIT:延迟绑定导入地址表(BIAT)是由 IMAGE_THUNK_DATA结构组成的数组,它是可选的。与延迟加载目录表中的 TimeStamp 字段一起被用于后处理绑定阶段 7) UnloadDelayIT:延迟卸载导入地址表(UIAT)是由IMAGE_THUNK_DATA结构组成的数组,可选的。它由只读节中已初始化的数据组成,这些数据是原始 IAT 的精确副本。在处理卸载请求时,可以释放这个 DLL,同时将 IMAGE_DELAY_IMPORT_DESCRIPTOR.ModuleHandle 清零,并用 UIAT 覆盖 IAT,以便将一切还原到预加载时的状态 8) TimeStamp:应用程序绑定到 DLL 的时间戳 ⑧  TLS 线程局部存储 线程局部存储数据以数据结构 IMAGE_TLS_DIRECTORY32 开始 typedef struct _IMAGE_TLS_DIRECTORY32 { DWORD StartAddressOfRawData // 0000h - TLS 模板的起始地址 DWORD EndAddressOfRawData // 0004h - TLS 模板的结束地址 DWORD AddressOfIndex // 0008h - TLS 索引的位置 DWORD AddressOfCallBacks // 000Ch - TLS 回调函数数组指针 DWORD SizeOfZeroFill // 0010h - 填充 0 的个数 DWORD Characteristics // 0014h - 保留 } IMAGE_TLS_DIRECTORY32; 1) StartAddressOfRawData:表示TLS模板的起始地址,这个模板是一块数据,用于对TLS数据进行初始化。每当创建线程时,系统都要复制所有这些数据 2) EndAddressOfRawData:表示TLS模板的结束地址。TLS的最后一个字节的地址,不包括用于填充的0 3) AddressOfIndex:用于保存TLS索引的位置 4) AddressOfCallBacks:指向由回调函数组成的数组,这个数组以0结尾 5) SizeOfZeroFill:TLS模板中除了由StartAddressOfRawData和EndAddressOfRawData字段组成的已初始化数据界限之外的大小(以字节计) 6) Characteristics:保留 IMAGE_TLS_DIRECTORY32结构体成员中的地址全部为VA,而非RVA TLS回调函数: typedef VOID (NTAPI *PIMAGE_TLS_CALLBACK) ( PVOID DllHandle; DWORD Reason; PVOID Reserved ); 1) Reserved:预留,为0 2) Reason:调用该回调函数的时机 3) DllHandle:DLL的句柄 TLS 回调函数参数Reason常用值 DLL_PROCESS_DETACH 0 进程将要被终止,包括第一个线程 DLL_PROCESS_ATTACH 1 启动了一个新进程,包括第一个线程 DLL_THREAD_ATTACH 2 创建了一个新线程。创建所有线程时都会发送这个通知,除第一个线程外 DLL_THREAD_DETACH 3 线程将要被终止。终止所有线程时都会发送这个通知,除第一个线程外 ⑨  加载配置信息 数据结构IMAGE_LOAD_CONFIG_DIRECTORY typedef sturct _IMAGE_LOAD_CONFIG_DIRECTORY { DWORD Characteristics; // 加载配置属性,一般为 48h DWORD TimeDateStamp; // 时间戳 WORD MajorVersion; // 主版本号 WORD MinorVersion; // 子版本号 DWORD GlobalFlagsClear; // 标志1 DWORD GlobalFlagsSet; // 标志2 DWORD CriticalSectionDefaultTimeout; // 超时 DWORD DeCommitFreeBlockThreshold; // 释放内存数量 DWORD DeCommitTotalFreeThreshold; // 空闲内存总量 DWORD LockPrefixTable; // 使用Lock前缀的指令地址 DWORD MaximumAllocationSize; // 最大的分配粒度 DWORD VirtualMemoryThreshild; // 最大的虚拟内存大小 DWORD ProcessAffinityMask; // 进程堆标志 DWORD ProcessHeapFlags; // SetProcessAffinityMask 函数参数 WORD CSDVersion; // Service Pack 版本标识 WORD Reserved1; // 预留 DWORD EditList; // Cookies 指针 DWORD SecurityCookie; // 指向 safe Handler 处理程序列表 VA DWORD SEHandlerTable; // safe Handler个数 DWORD SEHandlerCount; } IMAGE_LOAD_CONFIG_DIRECTORY; 1) Characteristics:用来显示文件的属性,通常为0,如果存在加载配置信息,一般设为48h 2) TimeDateStamp:时间戳,秒数 3) MajorVersion:主版本号 4) MinorVersion:次版本号 5) GlobalFlagsClear:当PE加载器加载该映像时需要清除的全局标志 6) GlobalFlagsSet:PE加载器加载该映像时需要设置的全局标志 7) CriticalSectionDefaultTimeout:用于这个进程处于无约束状态的临界区的默认超时值 8) DeCommitFreeBlockThreshold:返回到系统之前必须释放的内存数量(以字节计) 9) DeCommitTotalFreeThreshold:空闲内存总量(以字节计) 10) LockPrefixTable:该值是一个VA,它指向一个地址列表,这个地址列表中保存的是使用lock前缀的指令的地址 11) MaximumAllocationSize:最大的分配粒度(以字节计) 12) VirtualMemoryThreshold:最大的虚拟内存大小(以字节计) 13) ProcessAffinityMask:如果将该字段设置为非零值,则等效于在进程启动时将这个设定的值作为参数去调用函数SetProcessAffinityMask 14) ProcessHeapFlags:进程堆的标志,相当于函数HeapCreate的第一个参数 15) CSDVersion:Service Pack版本标识 16) Reserved1:保留 17) EditList:保留 18) SecurityCookie:指向cookie的指针 19) SEHandlerTable:该值为一个VA。这个地址列表中保存的是映像中每个合法的、独一无二的、基于SEH框架的异常处理程序的RVA,并且它们已经按RVA从小到大的顺序排过序,最后以一个双字的0结尾 20) SEHandlerCount:指向列表SEHandlerTable中双字的个数,最后一个0除外 参考资料: 数组编号 英文描述 中文描述 0(IMAGE_DIRECTORY_ENTRY_EXPORT) Export table address and size 导出表地址和大小 1(IMAGE_DIRECTORY_ENTRY_IMPORT) Import table address and size 导入表地址和大小 2(IMAGE_DIRECTORY_ENTRY_RESOURCE) Resource table address and size 资源表地址和大小 3(IMAGE_DIRECTORY_ENTRY_EXCEPTION) Exception table address and size 异常表地址和大小 4(IMAGE_DIRECTORY_ENTRY_SECURITY) Certificate table address and size 属性证书数据地址和大小(该数据并不映射到内存,因此存放的是文件偏移,而不是RVA) 5(IMAGE_DIRECTORY_ENTRY_BASERELOC) Base relocation table address and size 基地址重定位表地址和大小 6(IMAGE_DIRECTORY_ENTRY_DEBUG) Debugging information starting address and size 调试信息地址和大小 7(IMAGE_DIRECTORY_ENTRY_ARCHITECTURE) Architecture-specific data 预留为0 8(IMAGE_DIRECTORY_ENTRY_GLOBALPTR) Global pointer register relative virtual address 指向全局指针寄存器的值 9(IMAGE_DIRECTORY_ENTRY_TLS) Thread local storage(TLS) table address and size 线程局部存储地址和大小 10(IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG) Load configuration table address and size 加载配置表地址和大小 11(IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT) Bound import table address and size 绑定导入表地址和大小 12(IMAGE_DIRECTORY_ENTRY_IAT) Import address descriptor address and size 导入函数地址表地址和大小 13(IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT) Delay import descriptor address and size 延迟导入表地址和大小 14(IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR) CLR Runtime Header address and size CLR 运行时头部数据地址和大小 15 Reserved 系统保留 数据目录表项描述 IMAGE_FILE_HEADER.Machine 的常见值 取值 常量符号 含义 0x0 IMAGE_FILE_MACHINE_UNKNOWN 适应于任何处理器 0x1d3 IMAGE_FILE_MACHINE_AM33 Matsushita AM33 处理器 0x8664 IMAGE_FILE_MACHINE_AMD64 X64 处理器 0x1c0 IMAGE_FILE_MACHINE_ARM ARM 小尾处理器 0x1c4 IMAGE_FILE_MACHINE_ARMV7 ARMv7(或更高) 0xebc IMAGE_FILE_MACHINE_EBC EFI 字节码处理器 0x14c IMAGE_FILE_MACHINE_I386 Intel 386 处理器或后续兼容处理器 0x200 IMAGE_FILE_MACHINE_IA64 Inter Itanium 处理器系列 0x9041 IMAGE_FILE_MACHINE_M32R Mitsubishi M32R 小尾处理器 0x266 IMAGE_FILE_MACHINE_MIPS16 MIPS16 处理器 0x366 IMAGE_FILE_MACHINE_MIPSFPU 带 FPU 的 MIPS 处理器 0x466 IMAGE_FILE_MACHINE_MIPSFPU16 带 FPU 的 MIPS16处理器 0x1f0 IMAGE_FILE_MACHINE_POWERPC Power PC 小尾处理器 0x1f1 IMAGE_FILE_MACHINE_POWERPCFP 带浮点支持的 Power PC 处理器 0x166 IMAGE_FILE_MACHINE_R4000 MIPS 小尾处理器 0x1a2 IMAGE_FILE_MACHINE_SH3 Hitachi SH3 处理器 0x1a3 IMAGE_FILE_MACHINE_SH3DSP Hitachi SH3 DSP 处理器 0x1a6 IMAGE_FILE_MACHINE_SH4 Hitachi SH4 处理器 0x1a8 IMAGE_FILE_MACHINE_SH5 Hitachi SH5 处理器 0x1c2 IMAGE_FILE_MACHINE_THUMB ARM 或 Thumb 处理器 0x169 IMAGE_FILE_MACHINE_WCEMIPSV2 MIPS 小尾 WCE v2 处理器 IMAGE_FILE_HEADER.Characteristics 属性位的含义 数据位 常量符号 为 1 时的含义 0 IMAGE_FILE_RELOCS_STRIPPED 文件中不存在重定位信息 1 IMAGE_FILE_EXECUTABLE_IMAGE 文件是可执行的 2 IMAGE_FILE_LINE_NUMS_STRIPPED 不存在行信息 3 IMAGE_FILE_LOCAL_SYMS_STRIPPED 不存在符号信息 4 IMAGE_FILE_AGGRESSIVE_WS_TRIM 调整工作集 5 IMAGE_FILE_LARGE_ADDRESS_AWARE 应用程序可处理大于 2GB 的地址 6 此标志保留 7 IMAGE_FILE_BYTES_REVERSED_LO 小尾方式 8 IMAGE_FILE_32BIT_MACHINE 只在32位平台上运行 9 IMAGE_FILE_DEBUG_STRIPPED 不包含调试信息 10 IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 不能从可移动盘运行 11 IMAGE_FILE_NET_RUN_FROM_SWAP 不能从网络运行 12 IMAGE_FILE_SYSTEM 系统文件(如驱动程序),不能直接运行 13 IMAGE_FILE_DLL 这是一个 DLL 文件 14 IMAGE_FILE_UP_SYSTEM_ONLY 文件不能在多处理器计算机上运行 15 IMAGE_FILE_BYTES_REVERSED_HI 大尾方式 IMAGE_OPTIONAL_HEADER32.DllCharacteristics 属性位含义 数据位 常量符号 为1 时的含义 0 保留,必须为 0 1 保留,必须为 0 2 保留,必须为 0 3 保留,必须为 0 6 IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE DLL 可以在加载时被重定位 7 IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 强制代码实施完整性验证 8 IMAGE_DLLCHARACTERISTICS_NX_COMPAT 该映像兼容 DEP 9 IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 可以隔离,但并不隔离此映像 10 IMAGE_DLLCHARACTERISTICS_NO_SEH 映像不使用 SEH 11 IMAGE_DLLCHARACTERISTICS_NO_BIND 不绑定映像 12 保留,必须为 0 13 IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 该映像为一个 WDM driver 14 保留,必须为 0 15 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 可用于终端服务器 IMAGE_OPTIONAL_HEADER.Subsystem 的取值 取值 常量符号 含义 0 IMAGE_SUBSYSTEM_UNKNOWN 未知的子系统 1 IMAGE_SUBSYSTEM_NATIVE 设备驱动程序和 Native Windows 进程 2 IMAGE_SUBSYSTEM_WINDOWS_GUI Windows 图形用户界面 3 IMAGE_SUBSYSTEM_WINDOWS_CUI Windows 字符模式(控制台) 7 IMAGE_SUBSYSTEM_POSIX_CUI POSIX 字符模式(控制台) 9 IMAGE_SUBSYSTEM_WINDOWS_CE_GUI Windows CE 图形界面 10 IMAGE_SUBSYSTEM_EFI_APPLICATION 可扩展固件接口 (EFI) 应用程序 11 IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 带引导服务的 EFI 驱动程序 12 IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIEVER 带运行时服务的 EFI 驱动程序 13 IMAGE_SUBSYSTEM_EFI_ROM EFI ROM 映像 14 IMAGE_SUBSYSTEM_XBOX XBOX IMAGE_SECTION_HEADER.Characteristics(节的属性) 数据位的含义 数据位 常量符号 位为 1 时的含义 5 IMAGE_SCN_CNT_CODE 或 00000020h 节中包含代码 6 IMAGE_SCN_CNT_INITIALIZED_DATA 或 00000040h 节中包含已初始化数据 7 IMAGE_SCN_CNT_UNINITIALIZED_DATA 或 00000080h 节中包含未初始化数据 8 IMAGE_SCN_LNK_OTHER 或 00000100h 保留供将来使用 25 IMAGE_SCN_MEM_DISCARDABLE 或 02000000h 节中的数据在进程开始以后将丢弃,如 .reloc 26 IMAGE_SCN_MEM_NOT_CACHED 或 04000000h 节中的数据不会经过缓存 27 IMAGE_SCN_MEM_NOT_PAGED 或 08000000h 节中的数据不会被交换到磁盘 28 IMAGE_SCN_MEM_SHARED 或10000000h 表示节中的数据将被不同的进程所共享 29 IMAGE_SCN_MEM_EXECUTE 或 20000000h 映射到内存后的页面包含可执行属性 30 IMAGE_SCN_MEM_READ 或 40000000h 映射到内存后的页面包含可读属性 31 IMAGE_SCN_MEM_WRITE 或 80000000h 映射到内存后的页面包含可写属性 预定义的资源类型 数值 常量符号 含义 1 RT_CURSOR 光标 2 RT_BITMAP 位置 3 RT_ICON 图标 4 RT_MENU 菜单 5 RT_DIALOG 对话框 6 RT_STRING 字符串 7 RT_FONTDIR 字体目录 8 RT_FONT 字体 9 RT_ACCELERATOR 加速键 10 RT_RCDATA 未格式化资源 11 RT_MESSAGETABLE 消息表 12 RT_GROUP_CURSOR 光标组 14 RT_GROUP_ICON 图标组 16 RT_VERSION 版本

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 6 金币 [ 分享文档获得金币 ]
0 人已下载

下载文档

相关文档