Windows PE结构

307 阅读4分钟

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

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

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

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

多开(大号小号),节省内存 共用一些节 在这里插入图片描述

DOS头 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头 在这里插入图片描述 在这里插入图片描述在这里插入图片描述

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

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

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

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

MISC DWORD 该节没对齐前的真实尺寸,可以任意改动 在这里插入图片描述 在这里插入图片描述 若节的属性为60000020h = 20000000(可执行)+40000000(可读)+20(有可执行代码)

FileBuffer & ImageBuffer

在这里插入图片描述 MISC存的是在内存中真正分配的值,所以会存在大于SizeOfRawData 在这里插入图片描述 拷到哪:VirtualAddress 拷多大:SizeOfRawData (Misc也行,不太好)

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

一个应用程序是由一堆PE文件组成,exe不一定等于进程,单exe,贴exe后贴dll,然后重定位之类,可以自己写dll贴在空的地方然后自己重定位dll注入

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

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

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

call 硬编码E8 jmp硬编码E9 在这里插入图片描述

导出表(dll能供使用的函数)

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

导入表

可选PE的最后一个项,16个数组中的第2个 在这里插入图片描述 这个表不止一个,因为不止用一个dll 在这里插入图片描述 在这里插入图片描述 IAT表 在这里插入图片描述 所以调用的地址不在自己的进程空间而在dll的进程空间,把dll放到自己的进程空间里 4070DC(是在exe里)在文件偏移70DC处 在这里插入图片描述 运行前后寸的值不一样。77D5050B不在exe里,是dll,不会在编译的时候就写死messagebox的地址,所以要相对寻址下,是在dll全部贴完重定位了以后改的。Dll地址写死了不一定能占到想要的位置,占不到位置做的修改就是重定位,如果占到了重定位表没啥用 在这里插入图片描述

在这里插入图片描述