菜单

[PE结构解析] 伍.IMAGE_OPTIONAL_HEADE途胜

2019年4月12日 - 皇家赌场系统
typedef struct _IMAGE_OPTIONAL_HEADER 
{
    //
    // Standard fields.  
    //
+18h    WORD    Magic;                   // 标志字, ROM 映像(0107h),普通可执行文件(010Bh)
+1Ah    BYTE    MajorLinkerVersion;      // 链接程序的主版本号
+1Bh    BYTE    MinorLinkerVersion;      // 链接程序的次版本号
+1Ch    DWORD   SizeOfCode;              // 所有含代码的节的总大小
+20h    DWORD   SizeOfInitializedData;   // 所有含已初始化数据的节的总大小
+24h    DWORD   SizeOfUninitializedData; // 所有含未初始化数据的节的大小
+28h    DWORD   AddressOfEntryPoint;     // 程序执行入口RVA ***(必须了解)***
+2Ch    DWORD   BaseOfCode;              // 代码的区块的起始RVA
+30h    DWORD   BaseOfData;              // 数据的区块的起始RVA
    //
    // NT additional fields.    以下是属于NT结构增加的领域。
    //
+34h    DWORD   ImageBase;               // 程序的首选装载地址 ***(必须了解)***
+38h    DWORD   SectionAlignment;        // 内存中的区块的对齐大小 ***(必须了解)***
+3Ch    DWORD   FileAlignment;           // 文件中的区块的对齐大小 ***(必须了解)***
+40h    WORD    MajorOperatingSystemVersion;  // 要求操作系统最低版本号的主版本号
+42h    WORD    MinorOperatingSystemVersion;  // 要求操作系统最低版本号的副版本号
+44h    WORD    MajorImageVersion;       // 可运行于操作系统的主版本号
+46h    WORD    MinorImageVersion;       // 可运行于操作系统的次版本号
+48h    WORD    MajorSubsystemVersion;   // 要求最低子系统版本的主版本号
+4Ah    WORD    MinorSubsystemVersion;   // 要求最低子系统版本的次版本号
+4Ch    DWORD   Win32VersionValue;       // 莫须有字段,不被病毒利用的话一般为0
+50h    DWORD   SizeOfImage;             // 映像装入内存后的总尺寸
+54h    DWORD   SizeOfHeaders;           // 所有头 + 区块表的尺寸大小
+58h    DWORD   CheckSum;                // 映像的校检和
+5Ch    WORD    Subsystem;               // 可执行文件期望的子系统 ***(必须了解)***
+5Eh    WORD    DllCharacteristics;      // DllMain()函数何时被调用,默认为 0
+60h    DWORD   SizeOfStackReserve;      // 初始化时的栈大小
+64h    DWORD   SizeOfStackCommit;       // 初始化时实际提交的栈大小
+68h    DWORD   SizeOfHeapReserve;       // 初始化时保留的堆大小
+6Ch    DWORD   SizeOfHeapCommit;        // 初始化时实际提交的堆大小
+70h    DWORD   LoaderFlags;             // 与调试有关,默认为 0 
+74h    DWORD   NumberOfRvaAndSizes;     // 下边数据目录的项数,这个字段自Windows NT 发布以来一直是16
+78h    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];   
// 数据目录表 ***(必须了解,重点)*** winNT发布到win10,IMAGE_NUMBEROF_DIRECTORY_ENTRIES一直都是16
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

现实资料见:www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
中的pecoff.docx文档

[PE结构分析] 5.IMAGE_OPTIONAL_HEADER,imageoptionalheader

结构体源代码如下:

typedef struct _IMAGE_OPTIONAL_HEADER 
{
    //
    // Standard fields.  
    //
+18h    WORD    Magic;                   // 标志字, ROM 映像(0107h),普通可执行文件(010Bh)
+1Ah    BYTE    MajorLinkerVersion;      // 链接程序的主版本号
+1Bh    BYTE    MinorLinkerVersion;      // 链接程序的次版本号
+1Ch    DWORD   SizeOfCode;              // 所有含代码的节的总大小
+20h    DWORD   SizeOfInitializedData;   // 所有含已初始化数据的节的总大小
+24h    DWORD   SizeOfUninitializedData; // 所有含未初始化数据的节的大小
+28h    DWORD   AddressOfEntryPoint;     // 程序执行入口RVA ***(必须了解)***
+2Ch    DWORD   BaseOfCode;              // 代码的区块的起始RVA
+30h    DWORD   BaseOfData;              // 数据的区块的起始RVA
    //
    // NT additional fields.    以下是属于NT结构增加的领域。
    //
+34h    DWORD   ImageBase;               // 程序的首选装载地址 ***(必须了解)***
+38h    DWORD   SectionAlignment;        // 内存中的区块的对齐大小 ***(必须了解)***
+3Ch    DWORD   FileAlignment;           // 文件中的区块的对齐大小 ***(必须了解)***
+40h    WORD    MajorOperatingSystemVersion;  // 要求操作系统最低版本号的主版本号
+42h    WORD    MinorOperatingSystemVersion;  // 要求操作系统最低版本号的副版本号
+44h    WORD    MajorImageVersion;       // 可运行于操作系统的主版本号
+46h    WORD    MinorImageVersion;       // 可运行于操作系统的次版本号
+48h    WORD    MajorSubsystemVersion;   // 要求最低子系统版本的主版本号
+4Ah    WORD    MinorSubsystemVersion;   // 要求最低子系统版本的次版本号
+4Ch    DWORD   Win32VersionValue;       // 莫须有字段,不被病毒利用的话一般为0
+50h    DWORD   SizeOfImage;             // 映像装入内存后的总尺寸
+54h    DWORD   SizeOfHeaders;           // 所有头 + 区块表的尺寸大小
+58h    DWORD   CheckSum;                // 映像的校检和
+5Ch    WORD    Subsystem;               // 可执行文件期望的子系统 ***(必须了解)***
+5Eh    WORD    DllCharacteristics;      // DllMain()函数何时被调用,默认为 0
+60h    DWORD   SizeOfStackReserve;      // 初始化时的栈大小
+64h    DWORD   SizeOfStackCommit;       // 初始化时实际提交的栈大小
+68h    DWORD   SizeOfHeapReserve;       // 初始化时保留的堆大小
+6Ch    DWORD   SizeOfHeapCommit;        // 初始化时实际提交的堆大小
+70h    DWORD   LoaderFlags;             // 与调试有关,默认为 0 
+74h    DWORD   NumberOfRvaAndSizes;     // 下边数据目录的项数,这个字段自Windows NT 发布以来一直是16
+78h    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];   
// 数据目录表 ***(必须了解,重点)*** winNT发布到win10,IMAGE_NUMBEROF_DIRECTORY_ENTRIES一直都是16
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

AddressOfEntryPoint  ***(必须领悟)***

程序起初进行的地址,那是2个PRADOVA(相对虚拟地址)。对于exe文件,那里是开发银行代码;对于dll文件,那里是libMain()的地方。如果在一个可执行文件上附加了一段代码并想让那段代码首先被实践,那么只必要将这几个进口地址指向附加的代码就足以了。在脱壳时首先件事正是找入口点,指的就是以此值。

ImageBase  ***(必须掌握)***

PE文件的预先装入地址。也便是说,当文件被执行时,假使恐怕的话(当前地点未有被运用),Windows优先将文件装入到由ImageBase字段钦点的地点中。

对于EXE文件来说,由于每一种文件一连采用独立的虚拟地址空间,优先装入地址不容许被**模块占据,所以EXE总是能够服从这几个地方装入

那也意味着EXE文件不再要求重定位新闻。

对此DLL文件来说,由于五个DLL文件全体利用宿主EXE文件的地方空间,无法有限支撑优先装入地址未有被**的DLL使用,所以DLL文件中务必带有重从来新闻防止万一。

故而,在头里介绍的 IMAGE_FILE_HEADE中华V 结构的 Characteristics
字段中,DLL 文件对应的 IMAGE_FILE_RELOCS_STQX56IPPED
位总是为0,而EXE文件的那个标志位接二连三为一。

如果未有点名的话,dll文件私下认可为0x一千0000;exe文件默许为0x00四千00,但是在Windows
CE平台上是0x000一千0。此值必须是64K bytes的翻番!

SectionAlignment ***(必须驾驭)***

内部存款和储蓄器中区块的对齐单位。区块总是对齐到这几个值的整数倍。此字段必须大于或等于
FileAlignment ,暗中认可值是系统页面包车型客车大大小小。33个人cpu平常值为
0x一千(十陆进制),即40九陆,即4KB。陆拾贰个人cpu平时为 8kB
FileAlignment ***(必须询问)*****

pe文件中区块的对齐单位,以bytes(字节)为单位。此值必须是二的次方倍,不过必须在512和64K间隔之间(闭区间[521,
64*1024=65536]),要是SectionAlignment小于系统页面包车型地铁大小,那么SectionAlignment的轻重缓急就和FileAlignment相同。pe文件中暗许值为
5二一 字节(0.5KB) 即 0x200(十六进制)。

Subsystem ***(必须询问)***

pe文件的用户界面使用的子系统类型。定义如下:

#define IMAGE_SUBSYSTEM_UNKNOWN              0   // 未知子系统
#define IMAGE_SUBSYSTEM_NATIVE               1   // 不需要子系统(如驱动程序)
#define IMAGE_SUBSYSTEM_WINDOWS_GUI          2   // Windows GUI 子系统
#define IMAGE_SUBSYSTEM_WINDOWS_CUI          3   // Windows 控制台子系统
#define IMAGE_SUBSYSTEM_OS2_CUI              5   // OS/2 控制台子系统
#define IMAGE_SUBSYSTEM_POSIX_CUI            7   // Posix 控制台子系统
#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS       8   // 镜像是原生 Win9x 驱动程序
#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI       9   // Windows CE 图形界面

比如,Visual Studio 20壹第55中学编写翻译程序时得以在图形界面设置链接选项:

越多请查看:

微软官方文书档案:

DataDirectory ***(必须领会,首要)***

本条字段能够说是最重要的字段之1,它由17个一样的IMAGE_DATA_DIRECTOLX570Y结构组成。其协会如下:

typedef struct _IMAGE_DATA_DIRECTORY {

   DWORD   VirtualAddress; // 相对虚拟地址 

   DWORD   Size;           // 数据块的大小

} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

也正是概念了某块的岗位和尺寸。

虽说PE文件中的数据是比照装入内存后的页属性归类而被放在不一样的节中的,不过那一个地处各类节中的数据根据用途能够被分成导出表、导入表、能源、重定位表等数据块,那拾伍个IMAGE_DATA_DIRECTOMuranoY结构正是用来定义种种分化用途的数据块的(如下表所示)。IMAGE_DATA_DIRECTO猎豹CS陆Y结构的定义很不难,它可是提议了某种数据块的地方和尺寸。

#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // 导出表
#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // 导入表
#define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // 资源表
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   // 异常表(具体资料不详)
#define IMAGE_DIRECTORY_ENTRY_SECURITY        4   // 安全表(具体资料不详)
#define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // 重定位表
#define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // 调试表
//      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage) 版权信息
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   // 版权信息
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   // RVA of GP (具体资料不详)
#define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory (线程位置存储,具体资料不详)
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory (不详)
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers(不详)
#define IMAGE_DIRECTORY_ENTRY_IAT            12   // 导入函数地址表
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors(不详)
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   // COM Runtime descriptor(不详)

]
5.IMAGE_OPTIONAL_HEADEXC90,imageoptionalheader 结构体源代码如下:
typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. //
+18h WORD Magic; // 标志…

系统 1

8

pe文件的用户界面使用的子系统类型。定义如下:

The export table
address and size. For more information see section 6.3, “The .edata
Section (Image Only).”

内部存款和储蓄器中区块的对齐单位。区块总是对齐到那么些值的整好几倍。此字段必须超出或等于
FileAlignment ,默许值是系统页面的深浅。3二位cpu经常值为
0x一千(十六进制),即40玖陆,即4KB。60个人cpu通常为 八kB
FileAlignment ***(必须询问)****系统,*

104/120

The debug data starting
address and size. For more information, see section 6.1, “The .debug
Section.”

(PE/PE32+)

Base Relocation
Table

e_lfanew = MZ文件头大小(40) + DOS存根大小(可变:VC++下为A0) = E0

系统 2

8

8

8

Resource
Table

216/232

也正是概念了某块的职位和尺寸。

typedef struct _IMAGE_DATA_DIRECTORY {

   DWORD   VirtualAddress; // 相对虚拟地址 

   DWORD   Size;           // 数据块的大小

} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

128/144

Import
Table

Description

112/128

IAT

8

pe文件中区块的对齐单位,以bytes(字节)为单位。此值必须是二的次方倍,但是必须在51二和64K间隔之间(闭区间[521,
64*1024=65536]),假如SectionAlignment小于系统页面包车型地铁深浅,那么SectionAlignment的深浅就和FileAlignment相同。pe文件中暗中认可值为
521 字节(0.5KB) 即 0x200(十6进制)。

  96/112

例如,Visual Studio 二〇一五中编写翻译程序时得以在图形界面设置链接选项:

对于DLL文件来说,由于八个DLL文件全部用到宿主EXE文件的地方空间,不能保险优先装入地址未有被**的DLL使用,所以DLL文件中必须带有重平素新闻以免万一。

The delay import
descriptor address and size. For more information, see section 5.8,
“Delay-Load Import Tables (Image Only).”

CLR Runtime
Header

pe文件的用户界面使用的子系统类型。定义如下:

136/152

8

Bound
Import

 

8

160/176

Reserved, must be
0

The import table
address and size. For more information, see section 6.4, “The .idata
Section.”

The base relocation
table address and size. For more information, see section 6.6, “The
.reloc Section (Image
Only).”

程序开首实施的地方,那是2个索罗德VA(相对虚拟地址)。对于exe文件,那里是运维代码;对于dll文件,那里是libMain()的地址。若是在3个可执行文件上附加了一段代码并想让那段代码首先被执行,那么只需求将这么些进口地址指向附加的代码就足以了。在脱壳时首先件事正是找入口点,指的便是以此值。

8

The debug data starting
address and size. For more information, see section 6.1, “The .debug
Section.”

Delay Import
Descriptor

The exception table
address and size. For more information, see section 6.5, “The .pdata
Section.”

也正是概念了某块的职位和分寸。

Certificate
Table

160/176

对此DLL文件来说,由于多个DLL文件全体应用宿主EXE文件的地址空间,不可能担保优先装入地址未有被**的DLL使用,所以DLL文件中必须含有重从来音讯防止万一。

The load configuration
table address and size. For more information, see section 6.8, “The Load
Configuration Structure (Image Only).”

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图