《Windows PE》3.1 基本概念

在正式讲解PE文件格式之前,我们有必要先熟悉和PE相关的一些基本概念,以便于更好的理解和掌握PE文件格式。

本节必须掌握的知识点:

        地址

        指针

        数据目录项

        

        对齐方式

        字符串编码格式

3.1.1 地址

       ■PE文件中涉及到四类地址

       ●VA虚拟内存地址

VA(Virtual Address)是指虚拟内存地址,它是在操作系统中使用的一种抽象地址空间。虚拟内存是一种内存管理技术,它允许程序使用连续的、逻辑上连续的内存地址来访问内存,而不考虑实际的物理内存布局。

在虚拟内存系统中,每个进程拥有自己的独立的虚拟地址空间,进程中的程序代码、数据和堆栈都使用虚拟内存地址来进行访问。这些虚拟内存地址被映射到物理内存中的实际存储位置。

虚拟内存地址空间通常是由一定的位数来表示,例如32位或64位。在32位系统中,虚拟内存地址空间的范围是从0x00000000到0xFFFFFFFF(0到4GB)。在64位系统中,虚拟内存地址空间的范围更大,可以达到2的64次方(即18,446,744,073,709,551,616)个地址。

虚拟内存地址和物理内存地址之间的映射是通过操作系统的内存管理单元(Memory Management Unit,MMU)来实现的。MMU通过地址映射表将虚拟内存地址转换为物理内存地址,以便正确地访问和管理内存。

虚拟内存的使用带来了许多优势,包括更大的地址空间、内存隔离、内存保护和灵活的内存分配等。它使得操作系统能够更有效地管理内存资源,并为每个进程提供独立的地址空间,提高了系统的稳定性和安全性。

我们在程序源代码中写的地址都是虚拟地址,具有R3权限的普通应用程序源代码只需要写32位或64位偏移地址。

1.32位Windows系统给定默认的段选择子,通过段选择子在段描述符表中找到对应的段描述符。将32位(4GB虚拟空间内的)偏移地址加上段描述符中的32位段基址(通常为0段)得到32位线性地址,我们在OD调试器中看到的虚拟地址就是线性地址。线性地址再由MMU内存管理器通过地址映射表将虚拟内存地址转换为物理内存地址。

2.在64位Windows程序中,段寄存器的使用已经大大减少,甚至可以说几乎没有。这是因为在64位寻址模式下,采用了平坦模型(Flat Model),寻址空间足够大,整个虚拟地址空间被视为一片连续的地址范围,不再需要段选择。32位保护模式下分段的寻址方式在64位寻址模式下已经被废弃。在64位Windows程序中,虚拟内存地址直接映射到物理内存,程序可以直接使用虚拟地址来访问内存,无需进行段选择。64位寻址模式使用了分页机制,通过分页机制将虚拟地址映射到物理地址,实现了地址的转换和内存的管理。因此64位程序直接写64为偏移地址就可以了。

将32位或64位程序源代码编译为二进制可执行文件(PE文件)后,PE文件内与此对应的地址同样也是虚拟地址。只不过PE文件中的虚拟地址将VA地址分为两部分,由基址和相对虚拟内存地址构成。即:

VA(虚拟内存地址)=进程的基址+RVA(相对虚拟内存地址)

       ●RVA相对虚拟内存地址

RVA(Relative Virtual Address)是指相对虚拟内存地址,它用于描述在可执行文件(如EXE、DLL)的内部,某个特定的数据或代码的地址相对于该文件的基地址(Image Base)的偏移量。

在Windows操作系统中,可执行文件包含了各种节(Section),每个节都有自己的起始地址和大小。RVA是相对于所属节起始地址的偏移量,它是一个相对值,而不是绝对的内存地址。

当可执行文件加载到内存中时,操作系统会将文件的基地址(Image Base)分配给该文件。此时,RVA可以通过加上文件的基地址得到绝对的虚拟内存地址(线性地址),从而定位到文件中的特定数据或代码。

RVA的使用有助于可执行文件的可移植性和重定位。通过使用RVA,程序在不同的内存位置加载时,可以根据基地址的变化自动调整地址的偏移量,而不需要对文件进行修改。

【注意】RVA与虚拟内存地址之间的转换需要了解可执行文件的内部结构以及操作系统的加载过程。在Windows操作系统中,可以使用相关的API函数(如ImageRvaToVa)来进行RVA和虚拟内存地址的转换。

总结起来,RVA是指相对虚拟内存地址,在可执行文件内部描述某个数据或代码相对于文件基地址的偏移量。通过RVA,程序可以在加载时自动调整地址,实现可移植性和重定位。

●FOA文件偏移地址

FOA(File Offset Address)是指文件偏移地址,它用于描述可执行文件(如EXE、DLL)中某个特定数据或代码在文件中的位置偏移量。

在可执行文件中,各个节(Section)包含了不同的数据和代码。FOA是相对于文件起始位置的偏移量,用于表示某个数据或代码在文件中的位置。

当可执行文件被加载到内存时,操作系统将文件的内容映射到内存中。此时,FOA可以与文件的起始位置相加,得到数据或代码在内存中的绝对虚拟内存地址。

FOA的使用有助于在文件中定位特定的数据或代码。通过FOA,程序可以根据文件起始位置和偏移量来准确定位所需的内容。

需要注意的是,FOA与虚拟内存地址之间的转换需要了解可执行文件的内部结构以及操作系统的加载过程。在Windows操作系统中,可以使用相关的API函数(如SetFilePointer)来进行FOA和虚拟内存地址的转换。

总结起来,FOA是指文件偏移地址,在可执行文件中描述某个数据或代码相对于文件起始位置的偏移量。通过FOA,程序可以准确地定位文件中的内容。

实验八:使用调试器观察32位和64位记事本程序的VA虚拟地址

       ●32位记事本程序

第一步:将notepad32.exe拖入DTDebug调试器,按Ctrl+F9进入程序的入口地址。如图3-1所示,notepad32.exe的入口地址为0x0100739D。这个入口地址是一个VA虚拟内存地址(线性地址),即代码段执行的起始地址。入口地址由两部分组成,其中基址为0x01000000,偏移地址为0x739D(RVA地址)。

第二步:查看进程的内存映射窗口,加载notepad32.exe映像文件的起始地址为为0x01000000,这个地址即PE头的开始地址。</

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值