PE结构之节的操作(4)

节的操作

若要对PE文件填充自己的代码,然后发现字节空间不足,这时候就需要对节表进行操作

此处主要讲节的三种操作,分别为扩大节新增节合并节

扩大节

简介

对文件的节表进行扩大,为了方便操作,只需对最后一个节进行扩大OK了

此处演示扩大1000(16进制)个字节的操作


所需工具

  • Winhex
  • CFF Explorer

实例演示

首先将程序拖入到CFF Explorer工具,查看PE属性

例如文件对齐与内存对齐的值,此处内存对齐的值是1000

请添加图片描述


再查看最后一个节(rsrc)的Virtual Size(节的实际大小)和Raw Size(节文件对齐后的大小)

此处rsrc节的Virtual Size值为1E0, Raw Size的值为200, 两者取最大值200

再取200与1000(内存对齐)的最小公倍数,结果为1000

1000再加上1000(需扩大的字节数), 结果为2000

随后将Virtual Size和Raw Size的值都修改为2000

节内存对齐所增加的字节 = 节内存对齐后的大小(1000) - 节文件对齐后的大小(200), 计算结果为E00, 这个值在后面用winhex工具添加字节的操作中要用到

请添加图片描述

请添加图片描述


转到PE扩展头查看SizeOfimage(整个PE文件内存对齐后的大小),此处值为9000

将其修改成9000+1000(扩大的字节数), 即修改成10000

请添加图片描述


将文件保存后拖入到winhex中打开,将光标拖到最后一个字节,执行如下图操作

请添加图片描述

请添加图片描述


要插入的字节数 = E00(节内存对齐增加的字节) + 1000(需扩大的字节) = 1E00, 此处需换算成10进制,即为7680

请添加图片描述


然后winhex保存文件, 执行文件,若程序成功运行则说明扩大节操作成功


新增节

简介

扩大节扩出来的空白区还需要考虑节的权限问题,若扩大出来的节没有执行代码的权限,那么还要修改整个节的权限属性,节的权限属性由节表结构体的最后一个成员Characteristics决定

因为新增的节可以自己设置权限,所以相比扩大节而言还是方便挺多的


所需工具

  • winhex
  • CFE Explorer

实例演示

将文件拖入CFE Explorer中,找到段头部(节表属性)

请添加图片描述


在最后一个节的后面新增节, 以此方便后续的操作

对着最后一个节鼠标右键,为了研究原理,这里选择add section(Header Only), 意思为仅添加节表头。

若不想自己添加节数据,可以选择add section(File data)

请添加图片描述


对节表进行修改, 如下列表所示

节的成员 含义 修改后的值
Name 节的名字 .fuck
Virtual Size 节的实际大小 1000(要新增节的大小)
Virtual Address 节在内存中的偏移地址 9000(上一个节.Virtual Address + 上一个节内存对齐后的大小)
Raw Size 节文件对齐后的大小 1000(新增节的大小)
Raw Address 节在文件中的偏移地址 4E00(上一个节.RawAdress + 上一个节.Raw Size)
Characteristics 节的属性 0(即可读可写可执行)

请添加图片描述


切换到PE扩展头,修改SizeOfimage的值为10000(原先值9000+新增的字节1000)

请添加图片描述


文件保存后拖入到Winhex,新增4096个字节(16进制的1000),这里就不演示了,上面扩大节的操作就演示过了


合并节

简介

新增节有一个前提条件,最后一个节后面至少要有40个字节的空白区

若前提条件不满足, 那只能合并节,即将多个节合并成一个节,多余的空间就可以用于新增节


所需工具

  • Winhex
  • CFE Explorer

内存对齐

为了进行后面的合并节,需要先将所有的节进行内存对齐

内存对齐的意思是令节文件对齐后的大小和内存对齐后的大小相等

这里我们要将所有的节合并,所以全部节表都要进行内存对齐

只需修改节表三个成员值,分别是Virtual Size、Raw Size、Raw Address

此处演示的PE文件内存对齐值为1000

首先是第一个text节,将Virtual Size与Raw Size的值修改成内存对齐后的大小, 即修改成3000

注意: 由于是第一个节, 所以Raw Address的值就不用修改

请添加图片描述


第二个是rdata节,同样将Virtual Size与Raw Size的值修改成内存对齐后的大小

Raw Address = text节.Raw Address + text节.Raw Size

请添加图片描述

请添加图片描述


后面节的操作按上述演示来就行了,下图是所有节内存对齐前和内存对齐后的对比

请添加图片描述

请添加图片描述


计算出每个节的末尾地址, 随后在每个节的末尾地址填充字节

首先计算text节的内存对齐所增加的大小,称之为差值

差值 = 节内存对齐后的大小(3000) - 节文件对齐后的大小(2E00) = 200

text节的末尾地址 = 下一个节.RawAddress(3400) - 差值(200) = 3200

将程序拖入winhex, 点击工具栏的转到偏移量,输入text节的末尾地址, 随后光标会跳转到text节的末尾地址处

请添加图片描述
请添加图片描述


右键编辑插入0字节,插入512(十六进制的200,即差值)个字节

请添加图片描述


根据以上的步骤来完成对后面节的内存对齐, 这里特别注意下最后一个节的内存对齐

例如这里最后一个节的差值为E00, 不用计算它的节末尾地址, 直接将光标拖到文件末尾, 插入3584(差值)个字节即可


合并演示

内存对齐后再将文件拖入CFE Explorer, 只需修改第一个节的属性

将Vitrual Size和Raw Size的值修改成所有节内存对齐后大小的总和(3000+2000+1000+1000+1000=8000), 即修改成8000

将characteristics(节权限)的值修改成所有节的characteristics值相互异或运算后的结果, 即修改为E0000060, 这样修改的目的是令第一个节拥有所有节表的权限属性

请添加图片描述

请添加图片描述

将其他的节表头删掉,只留下一个text节表

请添加图片描述

请添加图片描述


将PE头里的NumberOfSections(节表个数)的值修改成1

请添加图片描述


后面程序执行成功则代表节合并成功

posted @ 2022-08-25 09:36  亨利其实很坏  阅读(247)  评论(0)    收藏  举报