PE文件实战教程之手动实现新增节

前面我们说过在空白节添加代码,想要更多空间的话,可以扩大节,但是在最后一个节进行扩大的话,还需要修改原来节的属性,比较麻烦,所以不如直接新增一个节!
并且我们通过手动新增节,可以直观地看到非常多的细节,帮助我们理解原理!

什么是新增一个节?

pe文件有多个节表,我们随便找一个exe文件查看,可以看到有多个节表:
在这里插入图片描述
每个节都有自己的任务和功能,所以我们新增一个节可以专门用来实现我们自己想要实现的功能。

了解一下节表

详细看一下每个成员的注释!
重点知道下面4个成员

Name[IMAGE_SIZEOF_SHORT_NAME]:我们可以随便起一个自己喜欢的名字
VirtualSize:是在内存中的真实大小
VirtualAddress:是加载到内存中第一个字节的偏移地址
SizeOfRawData:该节在文件对齐后的大小。

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME]; //8个字节名字.自己可以起.编译器也可以给定.不重要.
    union {
            DWORD   PhysicalAddress;       
            DWORD   VirtualSize;           //节数据没有对齐后的大小.也就是没有对齐.节数据有多大.
    } Misc;
    DWORD   VirtualAddress;          //加载到内存中的第一个字节的地址.也就是虚拟地址.节在内存中哪里开始.内存中的VA + ImageBase 才是真正的节开始位置
    DWORD   SizeOfRawData;           //修改这个属性的值,即可扩大节.并且在PE文件中添加相应的0数据进行填充.
    DWORD   PointerToRawData;          //在文件中的偏移.是文件对齐成员倍数.
    DWORD   PointerToRelocations;           //一下都是调试相关.
    DWORD   PointerToLinenumbers;           //
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;          //节的属性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

在这里插入图片描述

新增节表的步骤

1.判断是否有足够的空间增加一个新节.

2.节表新增一个成员,在原最后一个成员后面添加

3.修改文件头中节表个数.

4.添加的新节表修改节表的属性. 节.VirtualAddress .这个成员指定了这个节在内存哪里展开.所以需要修改.

5.再原有数据的最后,新增一个节的数据(内存对齐的整数倍)

6.修改新增节表的属性

  1. 修改扩展头的PE镜像大小. sizeofImage.
    这个成员才是关键.如果不按照内存对齐修改镜像大小.那么我们的节就不会映射到内存中.或者PE文件根本无法执行.

  2. 修改节表文件偏移 节.PointerToRawData 我们指定了内存中从哪里展开节.那么也需要指定这个节在文件中在哪里展开

  3. 修改节表中的 节数据对齐后的大小. 节.SizeofRawData. 我们新增的节.自己需要在PE文件添加一段节数据.数据的大小按照文件对齐添加. 并且填写到这个成员中.

  4. 节.VirtualSize修改

  5. 节.Characteristics文件偏移修改

1.判断是否有足够的空间增加一个新节.

我们使用工具直接查看节表区域,我们仅需要40个字节,发现空间足够!
在这里插入图片描述

2.节表新增一个成员,在原最后一个成员后面添加

这里我们直接复制.text节表成员,因为text作为代码段,可读可写可执行,非常完美。
这里直接复制过来了,然后我们先将名字修改为.tttt
在这里插入图片描述

3.修改节的数量

文件头中有一个属性记录了我们节表的个数.我们新增了一个节.那么就需要在原有的个数上加1.找到文件头记录节表个数位置.并加一即可.

原来为8,现在改为9。
在这里插入图片描述

4 修改sizeOfImage的大小

修改前:
可选头中:SizeofImage :0001D000
在这里插入图片描述
我们新增了0x1000节数据大小.那么我们的镜像大小也要加0x1000大小进行映射.注意.要按照内存对齐。
我们的原镜像大小以及按照内存对齐的方式存放了. 就是0x1D000. 那么我们加了0x1000的数据就是 0x1E000大小.我们修改为0x1E000。
在这里插入图片描述

5.再原有数据的最后,新增一个节的数据(内存对齐的整数倍)

插入了0x1000字节,填充为0.
ps:这里使用pe editor进行插入。
在这里插入图片描述

6 修正新增节表的属性

我们新增了一个节表.那么我们就要为这个节表指明内存中开始展开的位置. 文件中展开的位置. 以及节数据的大小.

对应的三个成员分别是:

节.VirtualAddress

节.SizeOfRawData

节.PointerToRawData

节.VirtuallAddress修改

首先第一个成员. 节.virtuallAddress .我们按照文件对齐.与上一个节表对齐存放即可.

例如上一个节表对齐后的展开位置为 0x1c000 那么我们就修改为 0x1d000
修改前:
在这里插入图片描述
修改后:
在这里插入图片描述

节.sizeofRawData修改

这个成员就是节数据按照文件对齐后的大小.取决于我们给这个节添加多少数据,这里我们之前添加了0x1000个字节。
  这里修改为1000
  在这里插入图片描述

节.PointerRawToData 文件偏移修改

最后修改的就是节在文件中哪里展开的. 这个我们需要看上一个节的文件偏移.以及节数据大小. 算出来的.
例如:
新增节的上一个节,偏移位置为1000,节数据在文件中对齐后的尺寸为100,那么1000-1100都是上一个节的数据

.tttt上一个节在文件中的偏移为8200,大小为600;
 那么tttt节的文件偏移就为8800
 在这里插入图片描述

节.VirtualSize修改

申请的新节空间大小,1000

节.PointerRawToData 文件偏移修改

我们新增节一般都是要求可读可写可执行的,所以这里直接修改为60000020。

实验结果:
新增节后的文件正常执行
在这里插入图片描述

实验工具:
CFF
PE Editor

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值