同样的,我们先在msdn中查看下这个结构体
第一个值,表示文件的格式,它可能的值有
IMAGE_NT_OPTIONAL_HDR_MAGIC,这个值包括两个值,分别为IMAGE_NT_OPTIONAL_HDR32_MAGIC、IMAGE_NT_OPTIONAL_HDR64_MAGIC,分别表示是32位的应用程序和64位的应用程序,具体的十六进制值为0x10b和0x20b。
还有一个值是IMAGE_ROM_OPTIONAL_HDR_MAGIC,表示这是一个ROM文件,其值为0x107。
总结为一张图
对于这个文件,它的值是
表示32位的应用程序。
第二个值是MajorLinkerVersion,表示主版本号的链接器,这个值一般来说是不重要的。
对于这个文件,它的值为
第三个值是MinorLinkerVersion,表示次版本号的连接器,这个值一般来说是不重要的。
它的值
第四个值是SizeOfCode,表示The size of the code section, in bytes, or the sum of all such sections if there are multiple code sections.
代码段的总大小,单位为字节,如果是多个部分,则表示它们的总和。
94208字节,即92kb。
第五个值是SizeOfInitializedData,表示所有含已初始化数据的节的大小。
The size of the initialized data section, in bytes, or the sum of all such sections if there are multiple initialized data sections.
77824字节,76kb。
第六个值是SizeOfUninitializedData,表示未初始化数据的节的大小。
The size of the uninitialized data section, in bytes, or the sum of all such sections if there are multiple uninitialized data sections.
第七个值是AddressOfEntryPoint,表示程序的入口点。
A pointer to the entry point function, relative to the image base address. For executable files, this is the starting address. For device drivers, this is the address of the initialization function. The entry point function is optional for DLLs. When no entry point is present, this member is zero.
我们用PEiD来看看这个值
如果看过《C++反汇编与逆向分析技术揭秘》的童鞋就会知道,PEiD是如何工作的。
第八个值是BaseOfCode,表示代码段的起始RVA。
即RVA为00001000,如果加上ImageBase的话,就可以知道这个位置在内存中的位置为00401000,我们用OD打开这个程序看看
第九个值是BaseOfData,表示数据段的起始RVA。
同样,我们用OD来查看下,00018000+00400000=00418000
第十个值是ImageBase,表示程序的建议装载地址。
用PEiD查看
第十一个值SectionAlignment,表示节对齐粒度。这个值一定要大于或等于文件对齐粒度。The alignment of sections loaded in memory, in bytes. This value must be greater than or equal to the FileAlignment member.The default value is the page size for the system.
原来是4096B,也就是4kb了。
第十二个值是FileAlignment,表示文件对齐粒度。
The alignment of the raw data of sections in the image file, in bytes. The value should be a power of 2 between 512 and 64K (inclusive). The default is 512. If the SectionAlignment member is less than the system page size, this member must be the same as SectionAlignment.
这个值应该是512B的倍数。
第十三个值是MajorOperatingSystemVersion,所需操作系统的主版本号。
The major version number of the required operating system.
第十四个值是MinorOperatingSystemVersion,所需操作系统的副版本号。
The minor version number of the required operating system.
第十五个值是MajorImageVersion
The major version number of the image.
第十六个值是MinorImageVersion
The minor version number of the image.
第十七个值是MajorSubsystemVersion
The major version number of the subsystem.
第十八个值为MinorSubsystemVersion
The minor version number of the subsystem.
第十九个值为Win32VersionValue,保留值,且必须为零。
This member is reserved and must be 0.
第二十个值为SizeOfImage,4个字节,表示程序调入后占用内存大小(字节),等于所有段的长度之和。
The size of the image, in bytes, including all headers. Must be a multiple of SectionAlignment.
0x2B000=?
好吧,两三天了,终于弄明白这个值了,由于在实验过程中,为了防止意外,所以复制了一个副本在当前文件夹下,通过二进制的对比,发现这两个文件的SizeOfImage值是不一样的,所以走了弯路。
既然错了文件,那么我还是以这个文件为例吧,因为其他的部分都一样,所以就不修改其他的部分了。
0x25000+0x5188=0x2A188,再考虑内存对齐,我们试着用这个值除以对齐粒度0x1000,看是否能除尽。
结果是不能除尽,所以要求大一点,结果这个SizeOfImage就变成了0x2B000。
第二十一个值为SizeOfHeaders,占用4个字节,表示所有头加节表的大小。
The combined size of the following items, rounded to a multiple of the value specified in the FileAlignment member.
4 byte signature
size of IMAGE_FILE_HEADER
size of optional header
size of all section headers
也就是0x1000了。
第二十二个值为CheckSum,占用四个字节。
The image file checksum. The following files are validated(验证) at load time: all drivers, any DLL loaded at boot time, and any DLL loaded into a critical (关键)system process.
第二十三个值为Subsystem,占用两个字节。表示文件运行所需的子系统。
The subsystem required to run this image. The following values are defined.
ValueMeaning
IMAGE_SUBSYSTEM_UNKNOWN0
Unknown subsystem.
IMAGE_SUBSYSTEM_NATIVE1
No subsystem required (device drivers and native system processes).
IMAGE_SUBSYSTEM_WINDOWS_GUI2
Windows graphical user interface (GUI) subsystem.
IMAGE_SUBSYSTEM_WINDOWS_CUI3
Windows character-mode user interface (CUI) subsystem.
IMAGE_SUBSYSTEM_OS2_CUI5
OS/2 CUI subsystem.
IMAGE_SUBSYSTEM_POSIX_CUI7
POSIX CUI subsystem.
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI9
Windows CE system.
IMAGE_SUBSYSTEM_EFI_APPLICATION10
Extensible Firmware Interface (EFI) application.
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER11
EFI driver with boot services.
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER12
EFI driver with run-time services.
IMAGE_SUBSYSTEM_EFI_ROM13
EFI ROM image.
IMAGE_SUBSYSTEM_XBOX14
Xbox system.
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION16
Boot application.
第二十四个值为DllCharacteristics,占用两个字节。表示dll文件的属性值。
The DLL characteristics of the image. The following values are defined.
ValueMeaning
0x0001
Reserved.(保留)
0x0002
Reserved.
0x0004
Reserved.
0x0008
Reserved.
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE0x0040
The DLL can be relocated at load time.(允许在载入的时候进行重定位)
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY0x0080
Code integrity checks are forced. If you set this flag and a section contains only uninitialized data, set the PointerToRawData member ofIMAGE_SECTION_HEADER for that section to zero; otherwise, the image will fail to load because the digital signature cannot be verified.
IMAGE_DLLCHARACTERISTICS_NX_COMPAT0x0100
The image is compatible(兼容) with data execution prevention (DEP).
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION0x0200
The image is isolation(隔离) aware, but should not be isolated.
IMAGE_DLLCHARACTERISTICS_NO_SEH0x0400
The image does not use structured exception handling (SEH). No handlers can be called in this image.
IMAGE_DLLCHARACTERISTICS_NO_BIND0x0800
Do not bind the image.
0x1000
Reserved.
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER0x2000
A WDM driver.
0x4000
Reserved.
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE0x8000
The image is terminal server aware.
第二十五个值为SizeOfStackReserve,占用4个字节。表示初始化是的堆栈大小。
The number of bytes to reserve for the stack. Only the memory specified by the SizeOfStackCommit member is committed at load time; the rest is made available one page at a time until this reserve size is reached.
0x00100000=1MB
第二十六个值为SizeOfStackCommit,占用四个字节。表示初始化时实际提交的堆栈大小。
The number of bytes to commit for the stack.
0x1000字节=4kb
第二十七个值为SizeOfHeapReserve,占用四个字节。初始化时保留堆的大小。
The number of bytes to reserve for the local heap. Only the memory specified by the SizeOfHeapCommit member is committed at load time; the rest is made available one page at a time until this reserve size is reached.
第二十八个值为SizeOfHeapCommit,占用四个字节。初始化时实际提交的堆得大小。
The number of bytes to commit for the local heap.
第二十九个值为LoaderFlags,占用4个字节。未使用。
This member is obsolete.
第三十个值为NumberOfRvaAndSizes,占用四个字节。表示下面个成员数据目录结构的数量。
这个值一般就直接是16.
下面是最后一个成员DataDirectory,占用128个字节,为一个IMAGE_DATA_DIRECTORY structure结构体数组(16个)。
A pointer to the first IMAGE_DATA_DIRECTORY structure in the data directory.
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
这个结构体有两个成员,一个成员占用4个字节,也就是8个字节。这个数组有16个数据,也就是16*8=128字节。
我们来看第一个。
IMAGE_DIRECTORY_ENTRY_EXPORT 导出表
这个程序没有导出函数,所以没有导出表。
第二个IMAGE_DIRECTORY_ENTRY_IMPORT 导入表
这个程序需要用到dll中的函数
我们用PEiD来查看下
结果是一样的。这个是RVA,表示偏移地址哦。
第三个IMAGE_DIRECTORY_ENTRY_RESOURCE 资源目录
从上面这张图也可以看出。RVA为00025000,大小为5188byte
第四个IMAGE_DIRECTORY_ENTRY_EXCEPTION 异常目录
未使用。
第五个 IMAGE_DIRECTORY_ENTRY_SECURITY 安全目录
第六个 IMAGE_DIRECTORY_ENTRY_BASERELOC 重定位表
第七个 IMAGE_DIRECTORY_ENTRY_DEBUG 调试信息
第八个 IMAGE_DIRECTORY_ENTRY_COPYRIGHT 版权信息
第九个 IMAGE_DIRECTORY_ENTRY_GLOBALPTR
第十个 IMAGE_DIRECTORY_ENTRY_TLS 线程的本地存储器
第十一个 IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 载入配置目录
Load configuration table address and size
第十二个 IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 绑定导入表地址和大小
Bound import table address and size
第十三个 IMAGE_DIRECTORY_ENTRY_IAT 导入函数地址表Import Address Table
Import address table address and size
用Exeinfo PE 查看
第十四个 IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
Delay import descriptor address and size
第十五个 IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
The CLR header address and size
第十六个 IMAGE_NUMBEROF_DIRECTORY_ENTRIES 保留值
到此,整个PE文件头结束了。