打开IMAGE_OPTIONAL_HEADER结构.txt文件 成员13,2个字节,表示操作系统主版本号,此值不会影响程序的执行,我们这里填充零,此值为“0000”。
成员14,2个字节,表示操作系统副版本号,此值不会影响程序的执行,我们这里填充零,此值为“0000”。
成员15,2个字节,表示程序主版本号,此值不会影响程序的执行,我们这里填充零,此值为“0000”。
成员16,2个字节,表示程序副版本号,此值不会影响程序的执行,我们这里填充零,此值为“0000”。 填充8个00
成员17,2个字节,表示子系统主版本号。win32子系统版本。PE文件是专门为Win32设计的,该子系统版本必定是4.0那么此处值为“04 00”。 成员18,2个字节,表示子系统副版本号,此值应为“00 00”。
成员19,4个字节,此值一般为“00 00 00 00”。 插入6个null字节 成员20,4个字节,表示程序调入后占用内存大小(字节),等于所有段的长度之和。所有头和节经过节对齐处理后 的大小。我们知道,我们文件PE结构总长小于1000h,但是内存中的对齐粒度是1000h,所以PE结构被映射后要占1000h,尽管很多空间没有使用,另外我们有3个段,每个段的长度小于1000h,但是被映射后同样要占1000h,所以总共占用内存的大小为1000h(PE头的大小) + 3 * 1000h(3个区段的大小) = 4000h(总内存大小),因此此值为“00400000”。(符合内存对其) 成员21,4个字节,表示所有文件头的长度之和,这里指的是文件大小非映射到内存的大小(即从文件开始到第一个段之间的大小)。也就是所有头+节表的大小,也就等于文件尺寸减去文件中所有节的尺寸。那么我们怎么得到这个值呢?我们的可以以此值作为PE文件第一节的文件偏移量。PE文件结构总大小为:
64(dos头) + 112 + 4(NT头) + 20(文件头) + 224(可选头) + 3 * 40(节表) = 544 byte 转化成十六进制为220h,那么此值就是220h吗?
不是的,因为我们文件中的对齐粒度是200h,那么220h实际上要占用400h的空间,所以此值为“00040000”。 成员22,4个字节,表示校验和。它仅用在驱动程序中,在可执行文件中可能为0。它的计算方法Microsoft不公开,在imagehelp.dll中的CheckSumMappedFile()函数可以计算它,此处我们设为填充零,此值为“00000000”。
成员23,2个字节,表示NT子系统,可能是以下的值:
IMAGE_SUBSYSTEM_NATIVE (1) 不需要子系统。用在驱动程序中。
IMAGE_SUBSYSTEM_WINDOWS_GUI(2) WIN32 graphical程序(它可用AllocConsole()来打开一个控制台,但是不能在一开始自动得到)。
IMAGE_SUBSYSTEM_WINDOWS_CUI(3) WIN32 console程序(它可以一开始自动建立)。
IMAGE_SUBSYSTEM_OS2_CUI(5) OS/2 console程序(因为程序是OS/2格式,所以它很少用在PE)。
IMAGE_SUBSYSTEM_POSIX_CUI(7) POSIX console程序。
Windows程序总是用WIN32子系统,所以只有2和3是合法的值。也就是说此值必须为2或3,如果是3,那么程序运行后会自动打开一个控制台,我们这里设为2,此值为“0200“。
成员24,2个字节,表示Dll状态,我们这里填充零,此值为“0000”。
成员25,4个字节,保留堆栈大小,我们这里填充零,此值为“00000000”。
成员26,4个字节,启动后实际申请的堆栈数,可随实际情况变大,我们这里填充零,此值为“00000000”。
成员27,4个字节,保留堆大小,我们这里填充零,此值为“00000000”。
成员28,4个字节,实际堆大小,我们这里填充零,此值为“00000000”。
成员29,4个字节,装载标志,我们这里填充零,此值为“00000000”。
成员30,4个字节,在讲这个成员之前,我们应该先了解成员31,成员31实际上是一个IMAGE_DATA_DIRECTORY结构的数组,成员30的值就是表示该数组的大小。通常有16个元素,所以此值为:“10000000”。
|