使用010手工添加节

使用010手工添加节

删除PE_Overlay

找到最后一个节的区块,在那之后的数据全部删除掉。

其实不删掉也行,不过学习起来的时候就不方便区别最后一个节和Overlay了。

网上有资料说PE_Overlay指PE结构的最后一个节的末尾位置,通常用于存储自定义资源

[!NOTE]

PE结构的基础上,增加了处理逻辑代码+自定义的资源

PE_Overlay指PE结构的最后一个节的末尾位置,通常用于存储自定义资源

PE结构的最后一个节末尾+1个字节的位置就是OverLay的起点。(last_section.Raw_offset + last_section.Raw_size) = Overlay;

PE_Overlay指的是PE(Portable Executable)文件格式中的Overlay ,它是PE文件的最后一个节(section)的末尾位置之后的额外数据。 在PE文件加载时,操作系统会将整个文件映射到内存中,其中Overlay部分通常被忽略。这部分数据可以用于存储任意类型的自定义资源,例如图像、音频、配置文件等,而不影响PE文件的正常执行。

Overlay的存在可以让开发者在不修改PE文件的基本结构的情况下,向其添加额外的数据。这对于包含了大量资源或者需要动态更新的程序来说非常有用。在安装包中,Overlay常常被用来存储自定义资源,例如软件的图标、帮助文件、配置文件等等。虽然Overlay不是PE文件的必需部分,但它为软件开发者提供了一个便捷的方式来扩展程序的功能。

关闭随机基址

将1改为0

添加节表

插入节表空间

在最后一个节表的地方插入n个字节大小的区域,这一块区域是为了写节表

这个n是参考 NT头的可选文件头里的FileAlignment的,如果是0x200就插入0x200个字节

快捷键:{Ctrl+Shift+I}

然后第一个节到最后一个节的PointerToRawData添加0x200,即节在磁盘文件上的偏移

如:400h->600h

Tips:如果想要插入的节表的空间足够0x28,那么就不用插入了,可以直接覆盖数据。

但是我编译出来的HelloWorld是需要插入了,就拿HelloWorld.exe学习了。

修改节的数量

NT头--文件头--节的数量:15改成16

修改SizeOfHeader

SizeOfHeaders是DOS头+PE头+区块表的总大小,后面的区块表更新了,所以这个也要更新的来着。

400h->600h

修改插入的节表的数据

参照着上面的填,

节表名字取名为.custom

union:实际使用的区块大小,该值可以不准确,所以申请了多少填多少,主要看壳代码的大小,学习示例申请1000h

VirtualAddresss:装载到内存中的RVA,这个要参照页对齐大小(在NT头的可选文件头里SectionAlignment),是0x1000h,所以在虚拟内存中,上一个表的0x11000+0x200=0x11200会对齐为0x12000h

SizeOfRawData:1000h,参考union,主要看壳代码的大小

PointerToRawData:6A00h,在磁盘文件中的偏移,上一个表的0x6800h+0x200h计算得到的

在节表最后的地方对Characteristics进行修改,修改可读可写可执行权限:0h->1h

添加节

申请空间

在最后一个节的末位插入申请的字节空间:0x1000h

修改节为壳的代码

为了简化学习,壳变成以下汇编

add ecx,0x17

jmp ???

其中,???为程序原始入口地址,如下图,原入口为:0x4014E0

然后将exe文件拖入IDA或者OD用插件patch得到对应字节码,然后在010里面修改

83 C1 17

E9 D8 F4 FE FF

修改入口点

AddressOfEntryPoint表示的是代码入口的RVA地址。也就是说,把一个文件加载到内存的时候,基地址加上AddressOfEntryPoint就是我们的入口代码地址

首先清楚这个0x14E0h是怎么计算得到的:

在磁盘文件中,实际的代码地址是8E0h,位于第一个表中

首先得到第一个表的信息:

第一个表在磁盘文件中的偏移为400h,实际代码地址为8E0h,

也就是说 实际的代码地址相对于第一个表的起始地址的偏移为4E0h,

这个地址位于第一个表的第0x4E0处,然后加上第一个表的VirtualAddress虚拟起始地址0x1000h,最后就得到了0x14E0h

注意:加的不是BaseOfCode,例如:如果换成了第二个表中的代码的话,那么就是需要用第二个表的VirtualAddress了。

然后要将0x14E0h修改为壳的VirtualAddress+偏移为0(因为是直接就在表的开始就注入了那两条简易汇编了)=0x12000h

实际上就三个值:

第一个值:汇编所在的表的 PointerToRawData

第二个值:磁盘文件中的 入口汇编代码 的地址

第三个值:汇编所在的表的 VirtualAddress

AddressOfEntryPoint=2-1+3

那是将0x14E0h改为0x6A00h吗?

错误!0x6A00h对应的是磁盘文件的入口,不是映像内存的入口,需要通过以上方法计算:

第一个值:6A00h

第二个值:6A00h

第三个值:12000h

==>相对偏移=0,所以直接就是VirtualAddress=0x12000h

修改SizeOfCode

1E00h还要再加上壳的代码的大小(0x1000h)=2E00h

修改SizeOfImage

映像装入内存后的总大小,必须满足页对齐

加上壳的代码的大小,12000h->13000h

最后成功添加节并运行!

相关推荐