typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic; // 标志字, ROM 映像(0107h),32位普通可执行文件(010Bh),64位可执行文件(0x20B)。
BYTE MajorLinkerVersion; // 链接程序的主版本号
BYTE MinorLinkerVersion; // 链接程序的次版本号
DWORD SizeOfCode; // 所有含代码的节的总大小
DWORD SizeOfInitializedData; // 所有含已初始化数据的节的总大小
DWORD SizeOfUninitializedData; // 所有含未初始化数据的节的大小
DWORD AddressOfEntryPoint; // 程序执行入口RVA
DWORD BaseOfCode; // 代码的区块的起始RVA
DWORD BaseOfData; // 数据的区块的起始RVA
//
// 64位里没有BaseOfData,有个8字节的ImageBase, ULONGLONG型
// NT additional fields. 以下是属于NT结构增加的领域。
//
DWORD ImageBase; // 程序的首选装载地址
DWORD SectionAlignment; // 内存中的区块的对齐大小
DWORD FileAlignment; // 文件中的区块的对齐大小
WORD MajorOperatingSystemVersion; // 要求操作系统最低版本号的主版本号
WORD MinorOperatingSystemVersion; // 要求操作系统最低版本号的副版本号
WORD MajorImageVersion; // 本PE文件映像的主版本号
WORD MinorImageVersion; // 本PE文件映像的次版本号
WORD MajorSubsystemVersion; // 运行所需要的子系统的主版本号
WORD MinorSubsystemVersion; // 运行所需要的子系统的次版本号
DWORD Win32VersionValue; // 子系统版本号,暂时保留未用。必须设置为0
DWORD SizeOfImage; // 映像装入内存后的总尺寸 +54h
DWORD SizeOfHeaders; // 所有头 + 区块表的尺寸大小,这个值是以FileAlignment对齐的。
DWORD CheckSum; // 映像的校检和 +5Ch
WORD Subsystem; // 可执行文件期望的子系统 表3-4
WORD DllCharacteristics; // Dll文件属性 +60h 表3-6
//
//4个堆栈元素在64位里都是8个字节,ULONGLONG型
//
DWORD SizeOfStackReserve; // 初始化时保留的栈大小
DWORD SizeOfStackCommit; // 初始化时实际提交的栈大小 +68h
DWORD SizeOfHeapReserve; // 初始化时保留的堆大小
DWORD SizeOfHeapCommit; // 初始化时实际提交的堆大小 +70h
DWORD LoaderFlags; // 加载标志 与调试有关,默认为 0
DWORD NumberOfRvaAndSizes; // 下边数据目录的项数,这个字段自Windows NT 发布以来一直是16
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; // 数据目录表,每个元素是一个8个字节,俩双字结构体,共16个,16*8=128个字节 } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

共有:32位224个字节,64位240个字节,4个堆栈元素每个多4个字节的原因

Magic字段 :说明文件的类型,如果为010Bh,表面文件为PE32;如果为0107h,表明文件为ROM映像;如果为20Bh,表面文件为PE64.
 
AddressOfEntryPoint字段:指出文件被执行时的入口地址,这是一个RVA地址。如果在一个可执行文件上附加了一段代码并想让这段代码首先被执行,那么只需要将这个入口地址指向附加的代码就可以了。
 
BaseOfCode字段:指出代码段的起始RVA。在内存中,代码段通常在PE文件头之后、数据块之前。在Microsoft链接器生成的执行文件中,RVA通常是1000h。Borland的Tlink32是将ImageBase加上第一个Code Section的RVA,并将该结果存入该字段。
 
ImageBase字段:指出文件的优先装入地址。也就是说当文件被执行时,如果可能的话,Windows优先将文件装入到由ImageBase字段指定的地址中。只有指定的地址已经被**模块使用时,文件才被装入到**地址中。链接器产生可执行文件的时候对应这个地址来生成机器码,所以当文件被装入这个地址时不需要进行重定位操作,装入的速度最快。如果文件被装载到**地址的话,将不得不进行重定位操作,这样就要慢一点。 对于EXE文件来说,由于每个文件总是使用独立的虚拟地址空间,优先装入地址不可能被**模块占据,所以EXE总是能够按照这个地址装入。这也意味着EXE文件不再需要重定位信息。对于DLL文件来说,由于多个DLL文件全部使用宿主EXE文件的地址空间,不能保证优先装入地址没有被**的DLL使用,所以DLL文件中必须包含重定位信息以防万一。因此,在前面介绍的 IMAGE_FILE_HEADER 结构的 Characteristics 字段中,DLL 文件对应IMAGE_FILE_RELOCS_STRIPPED位总是为0,而EXE文件的这个标志位总是为1。在链接的时候,可以通过对link.exe指定/base:address选项来自定义优先装入地址,如果不指定这个选项的话,一般EXE文件的默认优先装入地址被定为00400000h,而DLL文件的默认优先装入地址被定为10000000h。
 
SectionAlignment字段:指定了节被装入内存后的对齐单位。也就是说,每个节被装入的地址必定是本字段指定数值的整数倍。
 
FileAlignment字段:指定了节存储在磁盘文件中时的对齐单位。
 
SizeOfImage字段:内存中整个PE文件的映射尺寸。以加载在内存中的xxx.exe为例,xxx,exe中文件头占用了1000h字节,三个节各占用了1000h个字节,所以文件在内存中占用的空间总大小是04000h。该值可能比实际的大,但不能比它小,而且必须保证该值是SectionAlignment的整数倍。
 
SizeOfHeaders字段:指定所有头+节表按照文件对齐粒度对齐后的大小(即含补足的0),在PE文件中,这个值是以FileAlignment对齐后的大小,是FileAlignment的整数倍,如果不对齐,系统在加载时会提示出错。
 
Subsystem字段 指定使用界面的子系统,它的取值如表所示。这个字段决定了系统如何为程序建立初始的界面,链接时的/subsystem:**选项指定的就是这个字段的值,在前面章节的编程中我们早已知道:如果将子系统指定为Windows CUI,那么系统会自动为程序建立一个控制台窗口,而指定为Windows GUI的话,窗口必须由程序自己建立。
 
DllCharacteristics字段:DLL文件属性。它是一个标志集,不是针对DLL文件的,而是针对所以PE文件的。这个字段定义了PE文件装载时的一些特性。
 
SizeOfStackReserve字段:初始化时保留栈的大小。该字段表示初始线程的栈而保留的虚拟内存数量,然而并不是留出的所有虚拟内存都可以做栈(真正的栈大小由下一个字段SizeOfStackCommit决定)。该字段的默认值是0x100000(1MB),如果调用API函数CreateThread时,把NULL当作传入的参数那么创建出来的栈大小也会是1MB
 
SizeOfStackCommit字段:初始化时实际提交的栈大小。保证初始线程的栈实际占用内存空间的大小,它是被系统提交的。这些提交的栈不存在于交换文件里,而是存在于内存中。对于Microsoft的链接器来说,这个值的初始值为0x1000字节(1页),对于TLINK32,则为2页。
 
SizeOfHeapReserve字段:初始化时保留的堆大小。用来保留给初始进程堆使用的虚拟内存,这个堆的句柄可以通过调用GetProcessHeap函数获得。每一个进程至少会有一个默认的进程堆,改堆在进程启动的时候被创建,而且在进程的生命期中永远不会被删除。默认值1MB,我们可以通过链接器的“-heap”参数指定起始的保留堆内存大小和实际提交的堆大小。
 
SizeOfHeapCommit字段:初始化时提交的堆大小,在进程初始化时设定的堆所占用的内存空间。默认值为1页。
 
DataDirectory字段:这个字段可以说是最重要的字段之一,它由16个相同的IMAGE_DATA_DIRECTORY结构组成。虽然PE文件中的数据是按照装入内存后的页属性归类而被放在不同的节中的,但是这些处于各个节中的数据按照用途可以被分为导出表、导入表、资源、重定位表等数据块,这16个IMAGE_DATA_DIRECTORY结构就是用来定义多种不同用途的数据块的。

PE文件结构体-IMAGE_OPTIONAL_HEADER的更多相关文章

  1. PE文件结构体-IMAGE_DATA_DIRECTORY

    IMAGE_OPTIONAL_HEADER结构体最后一个成员是数组结构,大小为16,每个元素都是一个IMAGE_DATA_DIRECTORY结构体 typedef struct _IMAGE_DATA ...

  2. PE文件结构体-IMAGE_SECTION_HEADER

    在PE文件头与原始数据之间存在一个区块表(Section Table),它是一个IMAGE_SECTION_HEADER结构数组, 区块表包含每个块在映像中的信息(如位置.长度.属性),分别指向不同的 ...

  3. PE文件结构体-IMAGE_FILE_HEADER

    struct _IMAGE_FILE_HEADER { WORD Machine; //运行平台 WORD NumberOfSections; //文件的区块数目 DWORD TimeDateStam ...

  4. COFF/PE文件结构

    COFF/PE文件结构 原创 C++应用程序在Windows下的编译.链接(二)COFF/PE文件结构 2.1概述 在windows操作系统下,可执行文件的存储格式是PE格式:在Linux操作系统下, ...

  5. PE文件结构及其加载机制

    一.PE文件结构 PE即Portable Executable,是win32环境自身所带的执行体文件格式,其部分特性继承自Unix的COFF(Common Object File Format)文件格 ...

  6. PE文件结构详解(五)延迟导入表

    PE文件结构详解(四)PE导入表讲 了一般的PE导入表,这次我们来看一下另外一种导入表:延迟导入(Delay Import).看名字就知道,这种导入机制导入其他DLL的时机比较“迟”,为什么要迟呢?因 ...

  7. PE文件结构详解(四)PE导入表

    PE文件结构详解(二)可执行文件头的最后展示了一个数组,PE文件结构详解(三)PE导出表中解释了其中第一项的格式,本篇文章来揭示这个数组中的第二项:IMAGE_DIRECTORY_ENTRY_IMPO ...

  8. PE文件结构(四) 输出表

    PE文件结构(四) 參考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 输出表 一般来说输出表存在于dll中.输出表提供了 文件里函数的名字跟这些函数的地址, PE装载器通过输出表来改 ...

  9. PE文件结构(五岁以下儿童)基地搬迁

    PE文件结构(五岁以下儿童) 參考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 基址重定位 链接器生成一个PE文件时,它会如果程序被装入时使用的默认ImageBase基地址(VC默认 ...

随机推荐

  1. Python 爬取 热词并进行分类数据分析-[数据修复]

    日期:2020.02.01 博客期:140 星期六 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入] c.[拓扑 ...

  2. 在iOS项目中,这样才能完美的修改项目名称

    https://www.cnblogs.com/liangyi-cn/p/8657474.html 前言: 在iOS开发中,有时候想改一下项目的名字,这会遇到很多麻烦. 直接改项目名的话,Xcode不 ...

  3. 【转】postgres数据库创建索引

    一.索引的类型: PostgreSQL提供了多 种索引类型:B-Tree.Hash.GiST和GIN,由于它们使用了不同的算法,因此每种索引类型都有其适合的查询类型,缺省时,CREATE INDEX命 ...

  4. 「HNOI2002」营业额统计

    「HNOI2002」营业额统计 传送门 这题比较板子吧应该... 有几个需要注意的地方: 第一次插入时就要贡献答案 在每次计算贡献时,注意分裂出来的子树是否为空,并且要对两边的相邻元素之差取 \(\m ...

  5. [转]简单总结一下解决 添加 inline-block 后多出来的空隙

    添加 inline-block 后: 查询.借鉴的原网址:http://www.zhangxinxu.com/wordpress/?p=2357 html 结构: <ul class=" ...

  6. 科软-信息安全实验2-netfilter实验

    目录 一 前言 二 Talk is cheap, show me the code 三 前期准备 四 效果演示 五 遇到的问题&解决 六 参考资料 七 老师提供的代码 一 前言 文章不讲解理论 ...

  7. Ubuntu14 安装JDK 8

    参考: [1]Ubuntu安装JDK7/JDK8 [2]Oracle官网安装JDK10 安装包安装 本文采用安装包安装方式 1.下载JDK安装包 JDK8下载 ,根据所使用系统选择安装包(这里选.ta ...

  8. vb.net自学完整版

    https://m.book118.com/html/2016/1203/67671992.shtm

  9. UIWindow的获取

    注意:还是直接用下面这个比较靠谱.尤其是iOS11之后. [UIApplication sharedApplication].keyWindow;   1.下面这种是比较严谨的方式 - (UIWind ...

  10. 吴裕雄--天生自然HADOOP操作实验学习笔记:安装zookeeper集群

    实验目的 了解zookeeper的概念和原理 学会安装zookeeper集群并验证 掌握zookeeper命令使用 实验原理 1.Zookeeper介绍 ZooKeeper是一个分布式的,开放源码的分 ...