设为首页 加入收藏

TOP

2.2 PE结构:文件头详细解析(二)
2023-09-09 10:25:33 】 浏览:233
Tags:2.2 结构 文件头 解析
return 0; }

运行此段代码,则读者可以看到如下图所示的输出结果,程序会首先判断读入文件的pDosHead->e_magic是否为IMAGE_DOS_SIGNATURE用以验证是否为DOS头,接着通过IMAGE_DOS_HEADERe_lfanew值得到NT头部位置,并以此进一步判断是否为PE文件;

接下来则是读入PE文件中DOS头的重点部分,读者通过DosHeader指针,即可依次遍历出IMAGE_DOS_HEADER结构中的所有参数信息,这段代码可以总结为如下案例;

int main(int argc, char * argv[])
{
    BOOL PE = IsPeFile(OpenPeFile("c://pe/x86.exe"), 0);

    if (PE == TRUE)
    {
        printf("\t\t\t 十六进制 \t 十进制 \n");
        printf("DOS标志:                  %08X \t %08d \n", DosHeader->e_magic, DosHeader->e_magic);
        printf("文件最后一页的字节数:     %08X \t %08d \n", DosHeader->e_cblp, DosHeader->e_cblp);
        printf("文件中的页面:             %08X \t %08d \n", DosHeader->e_cp, DosHeader->e_cp);
        printf("重定位:                   %08X \t %08d \n", DosHeader->e_crlc, DosHeader->e_crlc);
        printf("段落中标题的大小:         %08X \t %08d \n", DosHeader->e_cparhdr, DosHeader->e_cparhdr);
        printf("至少需要额外段落:         %08X \t %08d \n", DosHeader->e_minalloc, DosHeader->e_minalloc);
        printf("所需的最大额外段落数:     %08X \t %08d \n", DosHeader->e_maxalloc, DosHeader->e_maxalloc);
        printf("初始(相对)SS值:         %08X \t %08d \n", DosHeader->e_ss, DosHeader->e_ss);
        printf("初始SP值:                 %08X \t %08d \n", DosHeader->e_sp, DosHeader->e_sp);
        printf("校验和:                   %08X \t %08d \n", DosHeader->e_csum, DosHeader->e_csum);
        printf("初始IP值:                 %08X \t %08d \n", DosHeader->e_ip, DosHeader->e_ip);
        printf("初始(相对)CS值:         %08X \t %08d \n", DosHeader->e_cs, DosHeader->e_cs);
        printf("重新定位表的文件地址:     %08X \t %08d \n", DosHeader->e_lfarlc, DosHeader->e_lfarlc);
        printf("叠加编号:                 %08X \t %08d \n", DosHeader->e_ovno, DosHeader->e_ovno);
        printf("保留字:                   %08X \t %08d \n", DosHeader->e_res, DosHeader->e_res);
        printf("OEM标识符                 %08X \t %08d \n", DosHeader->e_oemid, DosHeader->e_oemid);
        printf("OEM信息                   %08X \t %08d \n", DosHeader->e_res2, DosHeader->e_res2);
        printf("PE指针:                   %08X \t %08d \n", DosHeader->e_lfanew, DosHeader->e_lfanew);
    }
    else
    {
        printf("非标准程序 \n");
    }

    system("pause");
    return 0;
}

编译并运行上述代码片段,则读者可看到如下图所示的输出效果,此时DOS头部数据将被全部完整的输出;

2.3 PE文件头详细解析

从DOS文件头IMAGE_DOS_HEADERe_lfanew字段向下偏移003CH的位置,就是真正的PE文件头的位置,该文件头是由IMAGE_NT_HEADERS结构定义的,IMAGE_NT_HEADERS是PE文件格式的一部分,它包含了PE头和可选头的信息,用于描述PE文件的结构和属性。

typedef struct _IMAGE_NT_HEADERS
{
    DWORD Signature;                            // PE文件标识字符
    IMAGE_FILE_HEADER FileHeader;               // 文件头
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;     // 可选头
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

IMAGE_NT_HEADERS由IMAGE_NT_SIGNATURE(标识符)和IMAGE_FILE_HEADER(文件头)组成。其中,IMAGE_NT_SIGNATURE用于标识该文件是否为有效的PE文件,IMAGE_FILE_HEADER则用于描述可执行文件的基本结构信息,包括机器类型、段的数量、时间戳、符号表指针、符号表数量、可选头大小以及文件的各种标志和属性等。

如上_IMAGE_NT_HEADERS文件头的第一个DWORD是一个标志,默认情况下它被定义为00004550h也就是P,E两个字符另外加上两个零,而大部分的文件属性由标志后面的IMAGE_FILE_HEADERIMAGE_OPTIONAL_HEADER32结构来定义。

2.3.1 IMAGE_FILE_HEADER

我们跟进IMAGE_FILE_HEADER这个结构,文件头结构体IMAGE_FILE_HEADERIMAGE_NT_HEADERS结构体中的一个结构体,紧接在PE标识符的后面,IMAGE_FILE_HEADER结构体的大小为20字节,起始位置为0x000000CC结束位置在0x000000DF,这个IMAEG_FILE_HEADER结构体中包含了PE文件的大部分基础信息其结构的定义如下:

#define _IMAGE_FILE_HEADER 20

typedef struct _IMAGE_FILE_HEADER
{
    WORD    Machine;                  // 运行平台
首页 上一页 1 2 3 4 5 6 下一页 尾页 2/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++系列十:日常学习-元编程 下一篇C++的编译链接与在vs中build提速

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目