复习一下,不然会忘

1.imagebase 映像基地址 ,默认是0x400000

PE 结构中 VA RVA FOA 互转_xcode

2.va 虚拟地址,载入OD后的地址,已经映射到内存的地址。

PE 结构中 VA RVA FOA 互转_虚拟地址_02

计算实际装入地址 VA imagebase (映像基址) + RVA(虚拟入口) =>

PE 结构中 VA RVA FOA 互转_取代码_03

0x400000 + 0x5d485 = 0x45d485 载入 od 验证

PE 结构中 VA RVA FOA 互转_取代码_04

节取虚拟地址范围区间: 虚拟地址开始位置: imagebase + .text节RVA => 0x400000 + 0x00001000 = 401000

PE 结构中 VA RVA FOA 互转_取代码_05

虚拟地址结束位置:imagebase + .text节尺寸 => 401000 + 0x0007B0DE = 0x47C0DE .text节结束地址

PE 结构中 VA RVA FOA 互转_xcode_06

od 验证 0x47c0de 在 0x47d000 之前,属于text节

PE 结构中 VA RVA FOA 互转_xcode_07

虚拟地址RVA 对应到文件中的FOA位置: 以计算 0045D485 对应到文件中位置为例。

PE 结构中 VA RVA FOA 互转_取代码_08

RVA(相对便宜) = VA - .text首地址 => 0045D485 - 401000 = 5C485

FOA(文件偏移) = RVA + .text节的文件偏移 0x00001000 = 5C485 + 1000 = 5D485

PE 结构中 VA RVA FOA 互转_虚拟地址_09

打开 winhex 验证真伪。

PE 结构中 VA RVA FOA 互转_取代码_10

文件偏移转为RVA 计算文件偏移 5d480 对应到虚拟VA中的位置。

PE 结构中 VA RVA FOA 互转_虚拟地址_11

vpk = text节首地址 - imagebase - 实际偏移 = 401000 - 400000 - 1000 = 0

PE 结构中 VA RVA FOA 互转_取代码_12

va = foa + imagebase + vpk = 5d480 + 400000 + 0 = 45d480

PE 结构中 VA RVA FOA 互转_虚拟地址_13

虚拟VA转文件偏移代码 读取代码如下.

import os
import pefile

def RVA_To_FOA(FilePath):
pe = pefile.PE(FilePath)
ImageBase = pe.OPTIONAL_HEADER.ImageBase

for item in pe.sections:
if str(item.Name.decode('UTF-8').strip(b'\x00'.decode())) == ".text":
#print("虚拟地址: 0x%.8X 虚拟大小: 0x%.8X" %(item.VirtualAddress,item.Misc_VirtualSize))
VirtualAddress = item.VirtualAddress
VirtualSize = item.Misc_VirtualSize
ActualOffset = item.PointerToRawData
StartVA = hex(ImageBase + VirtualAddress)
StopVA = hex(ImageBase + VirtualAddress + VirtualSize)
print("[+] 代码段起始地址: {} 结束: {} 实际偏移:{} 长度: {}".format(StartVA,StopVA,ActualOffset,VirtualSize))

with open(FilePath,"rb") as fp:
fp.seek(ActualOffset)
HexCode = fp.read(VirtualSize)
print(HexCode)

RVA_To_FOA("d://lyshark.exe")

PE 结构中 VA RVA FOA 互转_xcode_14

版权声明:本博客文章与代码均为学习时整理的笔记,文章 [均为原创] 作品,转载请 [添加出处] ,您添加出处是我创作的动力!