2.4 PE结构:节表详细解析

这篇具有很好参考价值的文章主要介绍了2.4 PE结构:节表详细解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

节表(Section Table)是Windows PE/COFF格式的可执行文件中一个非常重要的数据结构,它记录了各个代码段、数据段、资源段、重定向表等在文件中的位置和大小信息,是操作系统加载文件时根据节表来进行各个段的映射和初始化的重要依据。节表中的每个记录则被称为IMAGE_SECTION_HEADER,它记录了一个段的各种属性信息和在文件中的位置和大小等信息,一个文件可以由多个IMAGE_SECTION_HEADER构成。

在执行PE文件的时候,Windows 并不在一开始就将整个文件读入内存,PE装载器在装载的时候仅仅建立好虚拟地址和PE文件之间的映射关系,只有真正执行到某个内存页中的指令或者访问页中的数据时,这个页面才会被从磁盘提交到内存中,这种机制极大的节约了内存资源,使文件的装入速度和文件的大小没有太多的关系。

2.4 PE结构:节表详细解析

Windows 装载器在装载DOS部分PE文件头部分和节表部分时不进行任何处理,而在装载节区的时候会根据节的不同属性做不同的处理,一般需要处理以下几个方面的内容:

节区的属性: 节是相同属性的数据的组合,当节被装入内存的时候,同一个节对应的内存页面将被赋予相同的页属性,Windows系统对内存属性的设置是以页为单位进行的,所以节在内存中的对其单位必须至少是一个页的大小,对于X86来说这个值是4KB(1000h),而对于X64来说这个值是8KB(2000h),磁盘中存储的程序并不会对齐4KB,而只有被PE加载器载入内存的时候,PE装载器才会自动的补齐4KB对其的零头数据。

节区的偏移: 节的起始地址在磁盘文件中是按照IMAGE_OPTIONAL_HEADER结构的FileAhgnment字段的值对齐的,而被加载到内存中时是按照同一结构中的SectionAlignment字段的值对齐的,两者的值可能不同,所以一个节被装入内存后相对于文件头的偏移和在磁盘文件中的偏移可能是不同的。

节区的尺寸: 由于磁盘映像和内存映像的对齐单位不同,磁盘中的映像在装入内存后会自动的进行长度扩展,而对于未初始化的数据段(.data?)来说,则没有必要为它在磁盘文件中预留空间,只要可执行文件装入内存后动态的为其分配空间即可,所以包含未初始化数据的节在磁盘中长度被定义为0,只有在运行后PE加载器才会动态的为他们开辟空间。

不进行映射的节: 有些节中包含的数据仅仅是在装入的时候用到,当文件装载完毕时,他们不会被递交到物理内存中,例如重定位节,该节的数据对于文件的执行代码来说是透明的,他只供Windows装载器使用,可执行代码根本不会访问他们,所以这些节存在于磁盘文件中,不会被映射到内存中。

一般来说,当一个PE文件被编译生成时则默认会存在.text,.data等基本节表,而每一个节表都是由一个IMAGE_SECTION_HEADER结构排列而成,每个结构都用来描述一个节,节表总被存放在紧接在PE文件头的地方,也即是从PE文件头开始偏移为00f8h的位置,针对每一个节中的定义可查看节表结构体的定义;

typedef struct _IMAGE_SECTION_HEADER
{
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;           // 节区尺寸
    } Misc;
    DWORD   VirtualAddress;                // 节区RVA
    DWORD   SizeOfRawData;                 // 在文件中对齐后的尺寸
    DWORD   PointerToRawData;              // 在文件中的偏移
    DWORD   PointerToRelocations;          // 在OBJ文件中使用
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;               // 节区属性字段
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

针对IMAGE_SECTION_HEADER中各个字段的详细解析:

  • Name:段名,是一个8字节的ASCII字符串,不足8字节用0补齐。

  • VirtualSize:虚拟大小,标识在内存中占用的大小,请勿与PhysicalSize(物理大小)混淆。

  • VirtualAddress:虚拟地址,标识在内存中对应段头的地址,与实际加载的位置有关。

  • SizeOfRawData:物理大小,标识在PE文件中该段的占用大小,不足以文件对齐单位则会进行填充。

  • PointerToRawData:物理地址,标识该段在文件中的偏移位置。

  • PointerToRelocations:重定向表的偏移位置。

  • PointerToLinenumbers:行号表的偏移位置。

  • NumberOfRelocations:重定向表数量。

  • NumberOfLinenumbers:行号表数量。

  • Characteristics:标识该段的各种属性信息,包括下列常用属性:

    • IMAGE_SCN_MEM_READ:可读;
    • IMAGE_SCN_MEM_WRITE:可写;
    • IMAGE_SCN_MEM_EXECUTE:可执行;
    • IMAGE_SCN_CNT_CODE:代码段;
    • IMAGE_SCN_CNT_INITIALIZED_DATA:已初始化数据段;
    • IMAGE_SCN_CNT_UNINITIALIZED_DATA:未初始化数据段;
    • IMAGE_SCN_LNK_INFO:包含附加信息。

与数据目录表的枚举方式基本一致,数据目录表的枚举也不会太难,读者只需要通过NtHeader->FileHeader.NumberOfSections获取到当前有多少个节,并通过循环的方式依次得到这些节中的指针,并将该指针转换为PIMAGE_SECTION_HEADER结构,依次循环输出即可得到;

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

    if (PE == TRUE)
    {
        printf("编号\t 节区名称\t虚拟偏移\t虚拟大小\t实际偏移\t实际大小\t节区属性\n");

        for (DWORD each = 0; each < NtHeader->FileHeader.NumberOfSections; each++, pSection++)
        {
            printf("%d\t %-9s\t 0x%.8X \t 0x%.8X \t 0x%.8X \t 0x%.8X \t 0x%.8X \n",
                each + 1, pSection->Name, pSection->VirtualAddress, pSection->Misc.VirtualSize,
                pSection->PointerToRawData, pSection->SizeOfRawData, pSection->Characteristics);
        }
    }
    else
    {
        printf("非标准程序 \n");
    }

    system("pause");
    return 0;
}

运行上述程序,即可输出当前程序中存在的节表信息,输出效果如下图所示;

2.4 PE结构:节表详细解析文章来源地址https://www.toymoban.com/news/detail-695018.html

到了这里,关于2.4 PE结构:节表详细解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 劫持 PE 文件:新建节表并插入指定 DLL 文件

    PE格式简介 PE(Portable Executable)格式,是微软Win32环境可移植可执行文件(如exe、dll、vxd、sys和vdm等)的标准文件格式。PE格式衍生于早期建立在VAX(R)VMS(R)上的COFF(Common Object File Format)文件格式。 Portable 是指对于不同的Windows版本和不同的CPU类型上PE文件的格式是一样的,当然CPU不一样

    2024年02月03日
    浏览(46)
  • 驱动开发:内核解析PE结构导出表

    在笔者的上一篇文章 《驱动开发:内核特征码扫描PE代码段》 中 LyShark 带大家通过封装好的 LySharkToolsUtilKernelBase 函数实现了动态获取内核模块基址,并通过 ntimage.h 头文件中提供的系列函数解析了指定内核模块的 PE节表 参数,本章将继续延申这个话题,实现对PE文件导出表的

    2024年02月07日
    浏览(32)
  • PE解释器之PE文件结构(二)

    接下来的内容是对IMAGE_OPTIONAL_HEADER32中的最后一个成员DataDirectory,虽然他只是一个结构体数组,每个结构体的大小也不过是个字节,但是它却是PE文件中最重要的成员。PE装载器通过查看它才能准确的找到某个函数或某个资源。 一:IMAGE_DATA_DIRECTORY——数据目录结构 此数据目

    2024年01月20日
    浏览(49)
  • 2.12 PE结构:实现PE字节注入

    本章笔者将介绍一种通过Metasploit生成ShellCode并将其注入到特定PE文件内的Shell注入技术。该技术能够劫持原始PE文件的入口地址,在PE程序运行之前执行ShellCode反弹,执行后挂入后台并继续运行原始程序,实现了一种隐蔽的Shell访问。而我把这种技术叫做字节注入反弹。 字节注

    2024年02月09日
    浏览(31)
  • 【手写数据库toadb】SQL解析器的实现架构,create table/insert 多values语句的解析树生成流程和输出结构分析

    ​ 专栏内容 : 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段学

    2024年02月05日
    浏览(68)
  • 2.9 PE结构:重建导入表结构

    脱壳修复是指在进行加壳保护后的二进制程序脱壳操作后,由于加壳操作的不同,有些程序的导入表可能会受到影响,导致脱壳后程序无法正常运行。因此,需要进行修复操作,将脱壳前的导入表覆盖到脱壳后的程序中,以使程序恢复正常运行。一般情况下,导入表被分为

    2024年02月09日
    浏览(35)
  • 二 PE破解windows系统密码

    本期,是 黑客学好好,牢饭香喷喷 合集的第二篇 这期的目的与上次类似,也是破解windows系统密码。 PS:与其说是破解密码,还不如说是清除密码。 破解方式 第一步 将带有PE系统的U盘插入电脑,通过快捷键引导U盘启动。不同品牌的电脑启动u盘的快捷键不同,常用的如按

    2024年02月11日
    浏览(46)
  • PE 文件结构图

    最近在进行免杀的学习,在《黑客免杀攻防》这本书中找到了非常好的关于PE文件的描述,虽然书比较古老的,但是里面的内容是非常精细和优秀的。它的附页中有非常清晰的PE文件结构图,可是翻看比较麻烦,撕下来又可惜,于是我今天对着附页的图用excel重新画了一个。这

    2024年02月10日
    浏览(50)
  • 2.10 PE结构:重建重定位表结构

    Relocation(重定位)是一种将程序中的一些地址修正为运行时可用的实际地址的机制。在程序编译过程中,由于程序中使用了各种全局变量和函数,这些变量和函数的地址还没有确定,因此它们的地址只能暂时使用一个相对地址。当程序被加载到内存中运行时,这些相对地址需

    2024年02月09日
    浏览(39)
  • 2.14 PE结构:地址之间的转换

    在可执行文件PE文件结构中,通常我们需要用到地址转换相关知识,PE文件针对地址的规范有三种,其中就包括了 VA , RVA , FOA 三种,这三种该地址之间的灵活转换也是非常有用的,本节将介绍这些地址范围如何通过编程的方式实现转换。 如下是三种格式的异同点: VA(Vi

    2024年02月09日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包