Java教程

PE结构分析(二)

本文主要是介绍PE结构分析(二),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

在表中,我们知道了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

这篇关于PE结构分析(二)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!