PE文件RVA-VA-Offset

VA     |   Memory    |           Offset  | Disk Files  |

         |             |                   |             |
00400000 +-------------+<---------00000000 +-------------+ 
         | DOS Header  |                   | DOS Header  |
         +-------------+                   +-------------+
         |  DOS stub   |                   |  DOS stub   |
         +-------------+                   +-------------+
         |  PE header  |                   |  PE header  |
         +-------------+                   +-------------+
         |Section Table|                   |Section Table|
         +-------------+  /-------00000600 +-------------+
         |000 Full 0000|  |                |   .text     |
         |000 Zero 0000|  |  /----0000D400 +-------------+
00401000 +-------------+<-/  |             |   .data  - A -|  0000D450  
         |   .text     |     |  /-00010000 +-------------+
         +-------------+     |  |          |   .rsrc     |
         |000 Full 0000|     |  |          +-------------+
         |000 Zero 0000|     |  |
0040E000 +-------------+<----/  |
0040E050  |- .data     |        |
         +-------------+        |
         |000 Full 0000|        |
         |000 Zero 0000|        |
00413000 +-------------+<-------/
         |   .rsrc     |
         +-------------+                 

#   Name     Virt Size    RVA        Phys Size  Phys Off   Flags  
--  -------- ---------  ---------  ---------  ---------  --------- 
01  .text     0000CCC0   00001000   0000CE00   00000600   60000020 [] 
02  .data      00004628    0000E000    00002C00    0000D400    C0000040 [] 

03  .rsrc     000003C8   00013000   00000400   00010000   40000040 [] 


对于变量A来说:

File_Offset   就是磁盘文件中A的位置。
              File_Offset = VA - ImageBase - VRk = RVA - VRk

ImageBase     就是文件加载到内存的起始位置。
              ImageBase = VA - RVA
              多为:0x00400000,0x01000000

EntryPoint    就是.text的VA地址。

VA    就是内存映像中A的位置,即A的地址。
      VA = ImageBase + FileOffset + VRk = ImageBase + RVA

RVA   就是内存映像中A的位置文件映射基址的差。
      RVA = VA - ImageBase = File_Offset + VRk

  PSVA  就好比是“某一时刻”,例如:九点到校上课。
      RVA 就好比是“某一时间段”,例如:七点起床后,过两个小时到校上课。
      VA  是绝对的,一旦确定便不可更改。九点到校迟一秒钟也不行。
      RVA 是系相对的,虽然说过两个小时到校上课,但是如果我七点起床,便是九点上课。
         而如果我八点起床,便是十点上课了。

VRk  就是文件映射到内存后,每一节之间填充的00的个数。
         由于要进行对齐,所以文件加载到内存后每一节之间要填充大量00
         因此文件中A的位置会变化。由于各个文件头各个节大小不变,所以:
         VRk = RVA - File_Offset = <填充的00的个数>

最终,我们计算:

由FileOffset到RVA/VA

     ImageBase    = 00400000
     A FileOffset = 0000D450

     RVA = FileOffset(A) + ( RVA(.data) - FileOffset(.data) )
         = FileOffset(A) +  VRk
         = 0000D450 + ( 0000E000 - 0000D400 )
         = 0000D450 + C00
         = 0000E050

     VA  = RVA + ImageBase = 0000E050 + 00400000 = 0040E050


RVA/VA到FileOffset:

     RVA = 0000E050   /   VA = 0040E050   /   ImageBase = 00400000

     FileOffset = RVA(A) - RVk
                = RVA(A) - ( RVA(.data) - FileOffset(.data) )
                = 0000E050 - ( 0000E000 - 0000D400 )
                = 0000E050 - C00
                = 0000D450 


==========================================================================



(表一)列出的文件偏移地址和RVA之间的对应关系可以让大家更直接地理解这种细微的差异

   由于内存数据节相对于装载基址的偏移量和文件数据节的偏移量有上述差异,所以进行文件偏移到虚拟内存地址之间的换算时,还要看所转换的地址位于第几个节内。

   我们把这种由存储单位差异引起的节基址差称作节偏移,在上例

   .text节偏移=0x1000-0x400=0xc00

   .rdata节偏移=0x7000-0x6200=0xE00

   .data节偏移=0x9000-0x7400=0x1C00

   .rsrc节偏移=0x2D000-0x7800=0x25800

   文件偏移地址与虚拟内存地址之间的换算关系可以用下面的公式来计算。

   文件偏移地址=虚拟内存地址(VA)-装载基址(Image Base)-节偏移=RVA-节偏移


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值