在表中,我们知道了0x01 4c对应的平台结构是i386;

我们接着分析下一个字段,给出PE结构图

 

 向后推移2个字节,现在来到(图片高亮部分):

 高亮部分对应IMAGE_NT_HEADERS结构的NumberofSections字段;

图中高亮部分是PE_HEADER部分的TimeDateStamp字段,这个字段的功能是记录文件的创建时间(姑且就叫时间戳字段)

对应下图中的:

 

我们接着分析下一个字段(PE_HEADER结构中的PointertoSymbolTable),这个字段的指向“符号表”(Coff符号表的偏移地址):

对应下图中的:

 

 

 

 符号表是什么?

首先我们先来解释下COFF文件格式:

 

 

 

 1.文件头(File Header)

 

 

 

 

 

 现在接着来转到PE_HEADER部分的NumberofSymbols(这个字段表示Coff表中符号的个数);

 

 

 我们定位到具体文件中的16进制代码中去:

 

我们接着转到PE_HEADER部分(结构体_IMAGE_FILE_HEADER)中的字段SizeOfOptionalHeader中去;

 

 

看到代码中高亮的部分显示0xE0h,说明这是一个32位文件。

我们接着转到PE_HEADER部分(结构_IMAGE_FILE_HEADER)中的Characteristics字段中去;

可以看到是0x0102h。

 

 

 

 说明我们的这个软件是可执行文件(也就是EXE可执行程序)。

我们接着转出PE_HEADER部分,重新转到_IMAGE_NT_HEADERS结构体当中的_IMAGE_OPTIONAL_HEADER OptionalHeader中去;

 

 

 

 

 

 接着按照OPTIONAL_PE_HEADER部分(_IMAGE_OPTIONAL_HEADER)的代码结构去看对应的16进制代码

 

 

 可以看到是0x010bh。

从01到42就是_IMAGE_OPTIONAL_HEADER结构体中各部分所对应的注释。

01.typedef struct _IMAGE_OPTIONAL_HEADER {
02.    //
03.    // Standard fields.
04.    //
05.  
06.    00h WORD    Magic;                   //幻数,32位pe文件总为010bh
07.    02h BYTE    MajorLinkerVersion;      //连接器主版本号
08.    03h BYTE    MinorLinkerVersion;      //连接器副版本号
09.    04h DWORD   SizeOfCode;              //代码段总大小
10.    08h DWORD   SizeOfInitializedData;   //已初始化数据段总大小
11.    0ch DWORD   SizeOfUninitializedData; //未初始化数据段总大小
12.    10h DWORD   AddressOfEntryPoint;     //程序执行入口地址(RVA)
13.    14h DWORD   BaseOfCode;              //代码段起始地址(RVA)
14.    18h DWORD   BaseOfData;              //数据段起始地址(RVA)
15.  
16.    //
17.    // NT additional fields.
18.    //
19.  
20.    1ch DWORD   ImageBase;               //程序默认的装入起始地址
21.    20h DWORD   SectionAlignment;        //内存中区块的对齐单位
22.    24h DWORD   FileAlignment;           //文件中区块的对齐单位
23.    28h WORD    MajorOperatingSystemVersion; //所需操作系统主版本号
24.    2ah WORD    MinorOperatingSystemVersion; //所需操作系统副版本号
25.    2ch WORD    MajorImageVersion;       //自定义主版本号
26.    2eh WORD    MinorImageVersion;       //自定义副版本号
27.    30h WORD    MajorSubsystemVersion;   //所需子系统主版本号
28.    32h WORD    MinorSubsystemVersion;   //所需子系统副版本号
29.    34h DWORD   Win32VersionValue;       //总是0
30.    38h DWORD   SizeOfImage;             //pe文件在内存中的映像总大小
31.    3ch DWORD   SizeOfHeaders;           //从pe文件开始到节表(包含节表)的总大小
32.    40h DWORD   CheckSum;                //pe文件CRC校验和
33.    44h WORD    Subsystem;               //用户界面使用的子系统类型
34.    46h WORD    DllCharacteristics;      //为0
35.    48h DWORD   SizeOfStackReserve;      //为线程的栈初始保留的虚拟内存的默认值
36.    4ch DWORD   SizeOfStackCommit;       //为线程的栈初始提交的虚拟内存的大小
37.    50h DWORD   SizeOfHeapReserve;       //为进程的堆保留的虚拟内存的大小
38.    54h DWORD   SizeOfHeapCommit;        //为进程的堆初始提交的虚拟内存的大小
39.    58h DWORD   LoaderFlags;             //为0
40.    5ch DWORD   NumberOfRvaAndSizes;     //数据目录结构数组的项数,总为 00000010h
41.    60h IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];  //数据目录结构数组
42.} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

 

 我们接着来看MajorLinkerVersion字段部分对应的16进制代码:

 

 接着看第二个字段MaionrLinkerVersion;

 

 所对应的16进制代码是:

 

 接着看下一个字段SizeOfCode(代码总大小):

 

 所对应的十六进制代码是:

接着看下一个字段SizeOfInitializedData(已初始化代码总大小):

 

 所对应的16进制代码为:

 

 接着看下一个字段SizeofUninitlizedData:

所对应的16进制代码为:

 

我们转到下一个字段AddressOfEntryPoint(这个字段表示的是程序执行入口的地址,相对于C语言的main函数的地址)接着分析:

 

 

 

 所对应的16进制代码为0x00001869h:

 

 这个地址对应的是程序对应的默认装入的起始地址为0x00001869h;

接着分析下一个字段BaseOfCode(这个字段指向的是程序的代码段起始地址):

可以看到所对应的16进制代码为0x00001000h

 

接着转到SizeOfData字段(这一字段指向的是程序代码的数据段起始地址)分析:

下面的这一个是SizeOfData字段对应的16进制代码:

 

这一个字段(ImageBase字段)所对应的是内存映像的基址:

 什么是内存映像?

https://baike.baidu.com/item/%E5%86%85%E5%AD%98%E6%98%A0%E5%83%8F/9046372?fr=aladdin

版权声明:本文为users123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/users123/p/14695126.html