前置知识:
Windows的内存可以被分为两个层面:物理内存和虚拟内存。其中,物理内存非常复杂,需要进入到Windows内核级别ring0才能看到。通常在用户模式下,用调试器看到的内存地址都是虚拟地址。
1.虚拟内存的定义
虚拟地址定义:用户编译程序时使用的地址称为虚拟地址或逻辑地址。其对应的存储空间称为虚拟内存或逻辑空间。
物理地址定义:计算机物理内存的访问地址则称为实际地址或物理地址,其对应的存储空间称为物理存储空间或主存空间。
程序重定位概念:程序进行虚拟地址到实际地址的转换过程称为程序的重定位
2.PE文件与虚拟内存的映射
在程序重定位(漏洞分析)时,可能通常需要进行以下两种操作:
(1)通过静态反汇编工具看到的PE文件中某条指令的位置是相对于磁盘文件而言的,即文件偏移。但是我们常常还需要知道这条指令在内存中的位置,即虚拟地址。
(2)当我们在调试时看到的某条指令的地址是虚拟内存地址,我们就需要回到PE文件中找到这条指令对应的机器码。
总结:我们在调试漏洞或程序重定位的时候,需要将PE文件格式和反汇编结果联系起来。
3.程序重定位涉及到的重要概念
(1)文件偏移地址(File Offset):数据在PE文件中的地址叫文件偏移地址,这是文件在磁盘上存放时相对于文件开头的偏移。
(2)装载基址(Image Base):PE装入内存是的基址地址。默认情况下,"".exe"文件在内存中的基址是0x00400000,“.dll”文件是0x10000000,这些位置可以通过修改编译选项修改。
(3)虚拟内存地址(Virtual Address)**:PE文件".text“节中的指令被装入内存后的地址。**
(4)相对虚拟地址(Relative Virtual Address)**:相对虚拟地址是内存地址相对于映射基址的偏移量。**(注意:相对虚拟地址是偏移量,不是地址)
虚拟内存地址、映射基址、相对虚拟内存地址的关系:(重要)
相对虚拟内存地址(RVA)=虚拟内存地址(VA)-装载基址(IB)
4.PE文件和内存的映射关系图
通过以上示意图:我们对PE文件映射到内存有了直观的认识,但是我们发现将PE文件中的每个数据节映射到内存后,内存中对应的每个数据节变大了。这是因为PE文件数据的存放单位与内存数据存放单位不同造成的差异。
5.PE文件存储数据与内存存储数据的差异
(1)PE文件中的数据按照磁盘数据标准存放,以0x200字节为单位进行组织。当一个数据节不足0x200字节时,不足地方被0x00填充;当一个数据节大小超过0x200字节,会将下一个0x200字节分配给这个数据节使用。所以在PE文件中节的大小总是0x200的整数倍。
(2)同理,当代码装入内存后,将按照内存数据标准存放,并以0x1000字节为基本单位进行组织,当不足时会不全,当超过0x1000字节,会将下一0x1000块分配给改数据节使用,所以内存中的节总是0x1000的整数倍。
补充:分析PE文件可以使用工具——LordPE软件