PE——合并节

为什么要合并节

新增节的前提:节表后面要有至少40字节空白,用来存放新的IMAGE_SECTION_HEADER 节表项

● 如果节表后面没有空余空间,无法直接新增节

● 解决方案:合并节,把多个节合并为一个,减少节的总数量,释放节表的空白位置,之后就可以新增节表项

不建议合并 .rsrc资源节、.reloc重定位节,极易程序崩溃

前置概念回顾 IMAGE_SECTION_HEADER 节表关键成员

字段 说明
Name8 节名字,最多 8 字节
Misc(VirtualSize) 内存中节真实大小(联合体)
VirtualAddress RVA,内存起始地址
SizeOfRawData 磁盘文件中节大小,要文件对齐
PointerToRawData 节在文件中的 FOA 偏移
Characteristics 节属性:可读、可写、可执行等

合并节完整步骤

<1> 按照内存对齐展开所有节

把每一节做内存对齐:让每一节的SizeOfRawData和VirtualSize都向上对齐到SectionAlignment(内存对齐,一般 0x1000)

目的:让各个节内存页边界整齐,为合并做准备

<2> 修改第一个节的 VirtualSize、SizeOfRawData

  1. 取最大值:Max = (SizeOfRawData > VirtualSize) ? SizeOfRawData : VirtualSize
  2. 将第一个节的SizeOfRawData = VirtualSize = Max
  3. 合并后第一节新的大小:最后一节.VirtualAddress + Max − SizeOfHeaders,结果再向上做内存对齐
    其余所有被合并的节,它们的原始数据物理上是连续的,全部归入第一个节
    <3> 设置合并后节的权限 Characteristics
    把所有要合并的每一节的 Characteristics 值全部做 按位或 |,结果赋值给合并后的第一节
    新Characteristics = 节A.Char | 节B.Char | 节C.Char | ......
    例如有的节只读、有的节可写,合并之后权限要同时具备读 + 写
    <4> 修改 PE 头的节数量
    修改IMAGE_FILE_HEADER → NumberOfSections,把节的总数修改为1(全部合并成单节)
    <5> 配套必须修改的其他字段
  4. SizeOfImage:镜像总大小,按内存对齐向上对齐
  5. 磁盘实体:文件各个节之间不能有间隙,物理数据连续
  6. 废弃其余旧节表项(NumberOfSections 减小后加载器不再读取后面多余节表)

合并节、扩大节、新增节三者对比

技术 适用场景 难点风险
洞穴注入 少量 shellcode,利用现有空白洞穴 空间很小,不能放大量代码
扩大最后一节 空白洞穴放不下,不想改动节表数组 不能扩中间节;.rsrc不要随便扩
新增节 大段 shellcode,代码独立干净 节表后面必须有 36 字节以上空白区,没有就不能直接新增
合并节 节表尾部没有空白,无法新增节 步骤复杂,权限处理不当程序直接崩溃,不建议合并资源、重定位节

重点踩坑提醒

  1. 合并节会改变内存布局,重定位、导入表、资源表极易出错,实操尽量优先新增节 / 扩大最后一节,合并节是兜底手段
  2. 合并之后的Characteristics不能直接照搬某一节,需要把所有被合并节的属性做按位或
  3. SizeOfImage一定要向上对齐SectionAlignment,否则 PE 加载失败 0xc000007b
  4. 物理磁盘数据必须连续,只改节表结构体,文件不调整,直接报错
    流程总结:没有节表空余空间 → 执行合并节释放节表位置 → 再执行新增节,放入 shellcode
相关推荐
chenbingjie_c3 小时前
C++ 进阶核心知识点总结:模板、内存分区、new/delete、内存池
开发语言·c++
Escalating_xu5 小时前
【C 语言】深入理解指针(1·下):指针运算、野指针、assert 与传址实战
java·c语言·开发语言
实心儿儿5 小时前
Qt — Qt 事件
开发语言·qt
周杰偷奶茶5 小时前
【Java】数据类型与变量
java·开发语言
code斗5 小时前
Java数据结构:堆详解
java·开发语言·数据结构
重生之小比特5 小时前
【C++进阶】map和set
java·开发语言·c++
lie..6 小时前
30天从零开始学AI应用开发(Day 12):像产品一样稳:流式输出、报错重试、花钱控制
开发语言·人工智能·php
傻啦嘿哟6 小时前
Python的默认参数把我坑惨了,原来写[]和写None的区别这么大
开发语言·python·机器学习
DeepAgent6 小时前
AI Agent 工程实践(49):一次真实优化——从 Agent v1 到 v2
开发语言·人工智能·agent
知识分享小能手6 小时前
C++ 学习教程,从入门到精通,C++对象和类 — 详细知识点总结(10)
开发语言·c++·学习