PE

文件和内存的直观不同
开始位置不一样
中间的0块大小不一样
数据基本一样

.dll,.sys,.exe都是4D5A(MZ)开头
.txt,.doc自己没法运行,是exe把它打开的

为什么要分节
节省硬盘空间 硬盘间隙小,内存间隙大,相同数据硬盘废的空间小
空隙也能一样(硬盘对齐=内存对齐,就不用拉伸了,节省时间,之前硬盘对齐小是因为硬盘贵,书的页,为了增加读写速度),拉伸(FileBuffer到ImageBuffer),但都是分节了

任何exe都有自己的虚拟的4GB空间(寻址范围232),高2G低2G,与内存条无关

多开(大号小号),节省内存
共用一些节
PE

DOS头 PE头 可选PE头
PE
e_magic e_lfanew 从文件开始算,过E8个字节,真正PE文件开始的地方,从e_lfanew到真正开始的地方DOS stub 可以写些无关的数据如编译器放进去的cannot run in DOS model,该区域也在内存中,也有地址,意味着可以塞shellcode然后执行
NT头 包含了标准PE头和可选PE头

NT头
1.50 45 00 00 DWORD SIGNATURE PE
2.接着是标准PE头
PE
PEPE

DOS头,标准PE头大小确定,DOS 64字节,PE 20字节
可选PE不确定,由标准PE头的一个成员规定

3.接着是可选PE头
PE
PE
PE
PE
SizeOfHeaders是文件对齐后,不是SectionAlignment
一个exe可以包含多个PE文件
AddressOfEntryPoint+ImageBase = 在内存里运行时的OEP(类似Main)
FileBuffer开始的位置 = 0
ImageBase = ImageBuffer的开始位置

节表 一个40字节 判断节是否是代码节不应该用名字区分,而应该用节属性

PE
找节表的起始 DOS DOS Stub PE标记 标准PE 可选PE后
节表个数:标准PE头 NumberOfSections
Name名字8字节.text .data等,Misc可以不准确的意思是可以改动
VirtualAddress是距离imagebase的距离,应该是对齐的整数倍,文件中的偏移也是一样

PE
PE
PE
若节的属性为60000020h = 20000000(可执行)+40000000(可读)+20(有可执行代码)

FileBuffer & ImageBuffer

PE
MISC存的是在内存中真正分配的值,所以会存在大于SizeOfRawData
PE
拷到哪:VirtualAddress
拷多大:SizeOfRawData (Misc也行,不太好)

x在imagebuffer里位置是401234,找它在文件里的位置,假设内存对齐不一样:
401234 - imagebase = 1234
1234 - 该节对应的VirtualAddress(循环看节表的各VirtualAddress,应该<1234) = 234
该节的PointerToRawData + 1234 = 它在文件里的位置

FOA 文件中的偏移
RVA = VisualAddress
VA = ImageBase + RVA

代码节空白区添加自己的shellcode

将OEP改为call shellcode这句指令的地址,执行
call shellcode
jmp 原OEP

call 硬编码E8
jmp硬编码E9
PE

导出表

可选PE的最后一个项(96字节之后),16个数组中的第一个,size可改,VitualAddress是表在内存的偏移,所以会存在转为文件的转换
PE

导入表

可选PE的最后一个项,16个数组中的第2个
PE
这个表不止一个,因为不止用一个dll
PE
PE

相关文章:

  • 2021-07-28
  • 2021-05-30
  • 2021-11-07
  • 2021-05-29
  • 2021-08-24
  • 2021-08-05
  • 2021-11-22
猜你喜欢
  • 2022-12-23
  • 2022-01-06
  • 2022-01-17
  • 2022-01-10
  • 2022-12-23
相关资源
相似解决方案