PE文件结构:节表-手动添加节

admin 2025年2月11日20:15:10评论16 views字数 2642阅读8分48秒阅读模式

在所有节的空白区域都不够存放我们想要添加的数据时,这个时候可以通过添加节来扩展我们可操作的空间去存储新的数据(如导入表、代码或资源)。

过程步骤

1.判断是否有足够的空间添加节表

PE文件的节表紧跟在PE头之后,每个节表的大小为40字节。判断是否有足够的空间添加节表需要先定位到最后一个节表,这边以之前PE文件系列文章中的样例程序为例子,样例程序中的最后一个节表后存在一大片"空地",有足够的空间可以添加一个节表。

PE文件结构:节表-手动添加节

注意:如果节表后有非0数据,这些数据可能是其他有用数据(如对齐数据或其他结构),直接覆盖可能会导致文件损坏。

2.添加节表

在紧挨着最后一个节表末尾的空间添加一个节表(40个字节),此处先用CC占位。

PE文件结构:节表-手动添加节

使用CC填充空白区域后,ctrl + s保存一下修改结果,接着尝试运行一下该程序。若程序能够正常运行则表示此处可以添加节表。

PE文件结构:节表-手动添加节

接着就需要修改节表的数据,这边附上节表结构体:

#define IMAGE_SIZEOF_SHORT_NAME              8

typedefstruct_IMAGE_SECTION_HEADER {
BYTEName[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORDPhysicalAddress;
DWORDVirtualSize;
    } Misc;
DWORDVirtualAddress;
DWORDSizeOfRawData;
DWORDPointerToRawData;
DWORDPointerToRelocations;
DWORDPointerToLinenumbers;
WORDNumberOfRelocations;
WORDNumberOfLinenumbers;
DWORDCharacteristics;
IMAGE_SECTION_HEADER*PIMAGE_SECTION_HEADER;

①首先修改第一个字段:Name[IMAGE_SIZEOF_SHORT_NAME]节表名称,这边将新增的节表命名为.addc

PE文件结构:节表-手动添加节

②修改第二个字段:VirtualSizeVirtualSize 表示节在内存中的大小,通常需要按内存对齐值(SectionAlignment)对齐。

节表的Misc联合体字段中的PhysicalAddress最初用于描述节的实际物理地址,但在现代 PE 文件中,这个字段已经被废弃;出于兼容性原因,仍然保留此名称,但其实际用途已被重定义。所以在现代 PE 文件中该字段中上存储的数据为VirtualSize。
PE文件结构:节表-手动添加节

这边设置新增的节在内存中的大小为0x1000字节,该字段的大小可以根据自己要填入的数据大小进行设置。

③修改第三个字段:VirtualAddressVirtualAddress是 PE 文件中每个节的虚拟地址,描述了该节在内存中的起始位置(相对于 ImageBase 的偏移量),它指示操作系统加载器将该节映射到内存的哪个位置。

修改该字段时,我们需要按照文件对齐,与上一个节表对齐存放,该样例文件中最后一个节表的内容如下:

PE文件结构:节表-手动添加节

此时我的上一个节在内存中的大小为:0000 0DF8,因为该字段需要与SectionAlignment(0x1000),所以此时该节在内存中实际占用的空间为0000 1000,且上一个节的开始地址(VirtualAddress)为0001 6000,通过这些信息可以确定新增节在内存中的起始地址应该为0001 7000

④修改第四个字段:SizeOfRawDataSizeOfRawData表示节在文件中占用的大小(以字节为单位),这是节在磁盘上的对齐后的大小,该值必须是 FileAlignment (文件对齐值)的倍数。

由于我们第二个字段的值为0x1000,已经是文件对齐值的倍数,所以我们可以直接修改SizeOfRawData的值为0x1000

PE文件结构:节表-手动添加节

⑤修改第五个字段:PointerToRawData表示该节在 PE 文件中开始位置的偏移量(以字节为单位)。新增的节应该要紧挨着PE文件原来的节,此时应该参照上一个节在PE文件中的大小和在PE文件存储的起始位置。

PE文件结构:节表-手动添加节

如图所示,前一个节在PE中所占的大小为0000 0E00,在PE文件中的起始位置为0001 2800,那么此时新增节在PE文件中的其实地址应该为:0001 3600

PE文件结构:节表-手动添加节

节表的后四个字段基本上不用,可以随意修改,这边我们就将前一个中的值拿过来填充新增节表的这四个字段好了,以下就是我们新增的节表最后的数据内容:

PE文件结构:节表-手动添加节
3.修改NumberOfSections字段

修改文件头中(_IMAGE_FILE_HEADER)中的NumberOfSections字段,该字段记录了文件中节的个数,此时我们要新增一个节,所以要将文件头中的该字段加1(原本是05,现改为06)。

PE文件结构:节表-手动添加节
4.修改SizeOfImage字段

修改扩展头(IMAGE_OPTIONAL_HEADER)中SizeOfImage字段,我们新增了0x1000节数据大小,那么我们的镜像大小也要加0x1000大小进行映射。当前SizeOfImage的值为0001 7000。(定位就是从PE标识开始数10个半行)

PE文件结构:节表-手动添加节

这个时候加上0x1000就是0001 8000

PE文件结构:节表-手动添加节
5.新增节

根据我们新增的节表中的SizeOfRawDataPointerToRawData字段信息在PE文件中添加节。

PE文件结构:节表-手动添加节

通过PointerToRawData得到新增节的在PE文件中开始地址为:0001 3600,通过SizeOfRawData得到节的大小为0x1000,接着就可以直接加数据了。

PE文件结构:节表-手动添加节

接着选中结尾部分,右击:

编辑->粘贴0字节->输入粘贴的0字节个数
PE文件结构:节表-手动添加节

添加4096个字节,即可快速添加数据。

PE文件结构:节表-手动添加节

这边我们可以将该PE文件的导入表数据贴入其中,接着进行动态调试查看该节是否成功载入。通过CFF工具定位到导入表。(如果不会定位导入表,可以看笔者前面的PE文件结构系列文章:《PE文件结构:导入表》)

PE文件结构:节表-手动添加节

成功将导入表复制到新加的节中。

PE文件结构:节表-手动添加节

最后,使用x86dbg动态调试该文件,查看节的内容。

PE文件结构:节表-手动添加节

通过新增的节表定位节,这边需要计算节的VA,ImageBaseRVA如下图:

PE文件结构:节表-手动添加节
PE文件结构:节表-手动添加节
VA = ImageBase + RVA
   = 0056 0000 + 0001 7000
   = 0057 7000

选定内存框,ctrl + G进行定位,下面附上PE文件加载进内存前和和加载后的结果对比。

加载前
PE文件结构:节表-手动添加节
加载后
PE文件结构:节表-手动添加节

可以看到新增节中的导入表已经成功被载入内存。

原文始发于微信公众号(风铃Sec):PE文件结构:节表-手动添加节

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月11日20:15:10
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   PE文件结构:节表-手动添加节https://cn-sec.com/archives/3642240.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息