流水账笔记:PE文件格式(OptionalHeader 下)

来源:互联网 发布:linux arp命令详解 编辑:程序博客网 时间:2024/05/16 11:19

Optional Header 的下部分的结构体成员

这里写图片描述

ImageBase(重要)

模块首地址,图中显示的值为 0x00400000

这里写图片描述

打开 OD,我们发现这个地址的数据和文件中开头的二进制数据对应,以 MZ 标志开头

这里写图片描述

该程序文件和内存的映射关系如下图,为什么要 分页映射文件中的数据 呢?因为不同的数据区域内存保护属性不同,不能映射在一起。正常的一个数据区域会以 512 个字节对齐。

内存中的地址 文件中的地址 0x00400000 ~ 0x00401000 0x000 ~ 0x400 0x00401000 ~ 0x00402000 0x400 ~ 0x600 0x00401000 ~ 0x00403000 0x600 ~ 0x800

如果我们单单修改这里的 ImageBase 为 0x00500000,那么程序将无法正常运行。这是因为程序中汇编代码的 相对地址 发生了改变,比如图中 pushMessageBox 的字符串的位置和调用的 API 的位置就发生了改变。

这里写图片描述

我们可以通过 编译器 来帮助我们修改模块的入口地址,于是汇编代码中的相对地址全部由编译器来修正。但是 并不是修改成任意的入口地址,都能够实现,如高 2G 的内存地址是不会分配给我们的。但是在低 2G内存中,大部分的内存地址都可以分配给我们。当然,这仅仅是对于 EXE 文件而言,对于 DLL 文件,由于是后期加载的,ImageBase 仅供参考。

Dll在加载后,文件中的代码偏移也需要得到修正,这就是 重定位代码

SectionAlignment

节的对齐值;节就是所谓的代码区、数据区。当把这些区中的内容拷贝到内存时,需要考虑对齐的问题。经过测试,在 Win10 操作系统上,该值只能为 1000h。1000h表示:如果一个节区在文件中占 200h 字节,那么拷贝到内存中,这段数据在内存中则会占 1000h 字节。

FileAlignment

文件的对齐值,该值在 Win10 系统中,只能修改为 200h 的倍数。

MajorOperatingSystemVersion & MinorOperatingSystemVersion

可运行的操作系统主版本和副版本,该字段仅供参考,可以修改

MajorImageVersion & MinorImageVersion

镜像的主版本号和副版本,该字段仅供参考,可以修改

MajorSubsystemVersion & MinorSubsystemVersion

子系统 的主版本版本号,结果修改,我们发现,对于 Win10 系统,该版本号只能在 3.10 ~ 6.02 之间修改,否则程序将 无法正常运行

Win32VersionValue

可以随意修改,系统并没有使用这个字段。

SizeOfImage

指整个程序在内存中占用多少空间(不包含加载的 DLL),不能随意修改。如果值不对,用 OD 调试时会出现如下错误:

这里写图片描述

有时候在 dump 时,文件中少粘贴了一个字节,文件和内存的映射关系发生错误

这里写图片描述

SizeOfHeaders

指文件中的所有文件头(并非FileHeader,而是指 NT 头、节头等)映射到内存的大小。如图中值为 0x400,而映射的模块基地址为 0x00400000,则内存中 0x00400000 ~ 0x00401000 的位置映射了文件 0 ~ 0x400 位置的的数据。该值在 一定范围内 可以修改。但修改的值一定不能超过1000h(一个页的大小)。

这里写图片描述

CheckSum

校验和,校验该文件是否被修改过。但是 Windows 操作系统并没有使用这个字段。但是该字段仍然 不能随意修改,因为一些驱动程序 或者 游戏程序 本身会检查校验和,只是普通的 EXE 文件不会检查。

Subsystem

子系统,其定义的宏如下图,不能随意修改

这里写图片描述

在 link 时选项 /subsystem:console 或 /subsystem:windows 即与该字段有关。

这里写图片描述

DllCharacteristics

Dll 的属性,定义的宏如下,该属性主要给驱动程序使用,不能随意修改

这里写图片描述

SizeOfStackReserve & SizeOfStackCommit

预留的栈空间大小以及马上需要申请的栈空间大小不能随意修改,该字段是有效的,如果修改过大,则系统会提示:

这里写图片描述

SizeOfHeapReserve & SizeOfHeapCommit

预留的堆空间大小以及马上需要申请的堆空间大小,和栈一样,不能随意修改

LoaderFlags

与程序的调试有关,系统并不关心

NumberOfRvaAndSizes

IMAGE_DATA_DIRECTORY 这个表的大小,不能小于正在使用的表的个数,不能随意修改

IMAGE_DATA_DIRECTORY

数据目录,记录各种表。

定义的宏如下:

这里写图片描述

IMAGE_DERECTORY_ENTRY_BOUND_IMPORT

绑定导入表,作用是为了加快软件的启动速度。因为软件在启动过程中,需要填写导入表的信息,API 调用得越多,启动速度越慢。如果 绑定导入表 上有信息,操作系统会先根据 绑定导入表 的信息直接在 IAT 上填写 API 地址,从而节省启动时间,缺点是不兼容。

一般开发者不会使用这种表,只有系统上的一些软件会使用这张表,比如计算器。

IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT

延时绑定表,在调用 API 时,才填写 导入表,从而提高软件的启动速度。但是一般程序也不会使用这张表,因为引用计数可以代替这张表的功能。如 kernel32.dll 中,不同进程,模块首地址都相等。如果一个程序的内存已经使用这个这个 dll,那么下一个程序在使用这个 dll 时,只要引用计数加1,就可以共享这份内存空间(物理上)。

IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR

与 COM 组件有关

IMAGE_DIRECTORY_ENTRY_EXPORT

–>导出表传送门

IMAGE_DIRECTORY_ENTRY_IMPORT

–>导入表传送门

IMAGE_DIRECTORY_ENTRY_BASERELOC

–>重定位表传送门

IMAGE_DIRECTORY_ENTRY_DEBUG

存放调试信息,由于windows操作系统的 PDB 文件是单独生成的,所以这张表对于 VC 编译器来说并没有用。

IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG

配置信息,由编译器决定其作用

IMAGE_DIRECTORY_ENTRY_SECURITY

待续…

IMAGE_DIRECTORY_ENTRY_TLS

–>TLS表传送门

IMAGE_DIRECTORY_ENTRY_RESOURCE

–>资源表传送门

阅读全文
0 0