- 公开视频 -> 链接点击跳转公开课程
- 博客首页 -> 链接点击跳转博客主页
目录
核心地址概念解析
基础定义
缩写 | 全称 | 描述 |
VA | Virtual Address | 进程虚拟内存中的绝对地址,由ImageBase + RVA计算得到 |
RVA | Relative Virtual Address | 相对于ImageBase的偏移地址,用于定位内存中的节、表等数据 |
FOA | File Offset Address | 文件在磁盘上的物理偏移地址(从文件开头计算的字节偏移) |
ImageBase | - | PE文件加载到内存时的首选基址,默认EXE为0x00400000,DLL为0x10000000 |
关键公式
-
VA = ImageBase + RVA
-
RVA = VA - ImageBase
-
FOA = RVA - Section.VirtualAddress + Section.PointerToRawData
地址转换实战步骤
RVA ↔ FOA 转换
前提条件:需遍历所有节表,判断目标RVA属于哪个节。
转换步骤:
-
遍历节表:检查每个节的
VirtualAddress
和VirtualSize
,确定RVA是否落在该节的内存范围内。 -
计算偏移差:
FOA = (RVA - Section.VirtualAddress) + Section.PointerToRawData
-
验证对齐: 确保计算结果满足
FileAlignment
(文件对齐)规则。
示例: 假设某节的VirtualAddress=0x1000
,PointerToRawData=0x400
,若RVA=0x1234:
FOA = (0x1234 - 0x1000) + 0x400 = 0x234 + 0x400 = 0x634
VA ↔ RVA 转换
- 直接计算:
RVA = VA - ImageBase
(需注意实际加载基址可能与ImageBase不同,此时需用GetModuleHandle(NULL)
获取真实基址)
VA ↔ FOA 转换
-
将VA转换为RVA:
RVA = VA - ImageBase
-
将RVA转换为FOA(见上述步骤)
PE文件头中的关键地址字段
IMAGE_OPTIONAL_HEADER中的地址相关字段
字段名 | 描述 |
ImageBase | 首选加载基址,影响所有VA的计算 |
AddressOfEntryPoint | 入口点RVA,即程序执行的起始位置 |
BaseOfCode | 代码段起始RVA(通常为.text段) |
BaseOfData | 数据段起始RVA(通常为.data段,64位PE中已废弃) |
SectionAlignment | 内存对齐粒度(通常0x1000,即4KB) |
FileAlignment | 文件对齐粒度(通常0x200,即512字节) |
数据目录表(Data Directories)
-
位于
IMAGE_OPTIONAL_HEADER
末尾的16个IMAGE_DATA_DIRECTORY
结构。 -
每个目录项包含
VirtualAddress
(RVA)和Size
,如:-
导出表(Export Table)
-
导入表(Import Table)
-
资源表(Resource Table)
-
重定位表(Base Relocation Table)
-