PE

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

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

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

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

多开(大号小号),节省内存
共用一些节
PE_第1张图片

DOS头 PE头 可选PE头
PE_第2张图片
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_第3张图片
PE_第4张图片PE_第5张图片

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

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

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

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

MISC DWORD 该节没对齐前的真实尺寸,可以任意改动
PE_第11张图片
PE_第12张图片
若节的属性为60000020h = 20000000(可执行)+40000000(可读)+20(有可执行代码)

FileBuffer & ImageBuffer

PE_第13张图片
MISC存的是在内存中真正分配的值,所以会存在大于SizeOfRawData
PE_第14张图片
拷到哪: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_第15张图片

导出表

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

导入表

可选PE的最后一个项,16个数组中的第2个
PE_第17张图片
这个表不止一个,因为不止用一个dll
PE_第18张图片
PE_第19张图片

你可能感兴趣的:(PE)