RVA-FOA之间转换

1.首先PE头加载到内存之后是和文件头内容一样的,就算是偏移不同,一个是磁盘扇区大小(400H)另一个是内存页大小(1000H),但是因为两个都是开头位置,所以相同。

2.看下IMAGE_SECTION_HEADER定义

也就是这样:

然后就可以算了(RVA->FOA)

(1) RVA20 < RVA < RVA30
可以知道在第二节

(2) 然后 off = RVA - RVA20 ,得出距离第二节的偏移off

(3) FOA = FOA 20 + off
求出FOA

计算FOA->RVA也是同理...

/************************************************************************/
/*
功能:虚拟内存相对地址和文件偏移的转换
参数:stRVA: 虚拟内存相对偏移地址
lpFileBuf: 文件起始地址
返回:转换后的文件偏移地址
*/
/************************************************************************/
size_t RVAToOffset(size_t stRVA,PVOID lpFileBuf)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf;
size_t stPEHeadAddr = (size_t)lpFileBuf + pDos ->e_lfanew;
PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr;
//区段数
DWORD dwSectionCount = pNT->FileHeader.NumberOfSections;
//内存对齐大小
DWORD dwMemoruAil = pNT->OptionalHeader.SectionAlignment;
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT);
//距离命中节的起始虚拟地址的偏移值。
DWORD dwDiffer = 0;
for (DWORD i = 0; i < dwSectionCount; i++)
{
//模拟内存对齐机制
DWORD dwBlockCount = pSection[i].SizeOfRawData/dwMemoruAil;
dwBlockCount += pSection[i].SizeOfRawData%dwMemoruAil? 1 : 0; DWORD dwBeginVA = pSection[i].VirtualAddress;
DWORD dwEndVA = pSection[i].VirtualAddress + dwBlockCount * dwMemoruAil;
//如果stRVA在某个区段中
if (stRVA >= dwBeginVA && stRVA < dwEndVA)
{
dwDiffer = stRVA - dwBeginVA;
return pSection[i].PointerToRawData + dwDiffer;
}
else if (stRVA < dwBeginVA)//在文件头中直接返回
{
return stRVA;
}
}
return 0;
} /************************************************************************/
/*
功能:文件偏移地址和虚拟地址的转换
参数:stOffset:文件偏移地址
lpFileBuf:虚拟内存起始地址
返回:转换后的虚拟地址
*/
/************************************************************************/
size_t Offset2VA(size_t stOffset, PVOID lpFileBuf)
{
//获取DOS头
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf;
//获取PE头
//e_lfanew:PE头相对于文件的偏移地址
size_t stPEHeadAddr = (size_t)lpFileBuf + pDos ->e_lfanew;
PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr;
//区段数
DWORD dwSectionCount = pNT->FileHeader.NumberOfSections;
//映像地址
DWORD dwImageBase = pNT->OptionalHeader.ImageBase;
//区段头
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT); //相对大小
DWORD dwDiffer = 0;
for (DWORD i = 0; i < dwSectionCount; i++)
{
//区段的起始地址和结束地址
DWORD dwBeginVA = pSection[i].PointerToRawData;
DWORD dwEndVA = pSection[i].PointerToRawData + pSection[i].SizeOfRawData;
//如果文件偏移地址在dwBeginVA和dwEndVA之间
if (stOffset >= dwBeginVA && stOffset < dwEndVA)
{
//相对大小
dwDiffer = stOffset - dwBeginVA;
//进程的起始地址 + 区段的相对地址 + 相对区段的大小
//return dwImageBase + pSection[i].VirtualAddress + dwDiffer;
return pSection[i].VirtualAddress + dwDiffer;
}
else if (stOffset < dwBeginVA) //如果文件偏移地址不在区段中
{
return dwImageBase + stOffset;
}
}
return 0;
}

测试了上面两个函数,没发现什么问题,测试结果:

随手写了个简单的工具,直接控制台写的,功能简单,懒得写界面了。源码在:

http://download.csdn.net/detail/u013761036/9643230

运行效果:

Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)的更多相关文章

  1. Windows Pe 第三章 PE头文件(上)

    第三章  PE头文件 本章是全书重点,所以要好好理解,概念比较多,但是非常重要. PE头文件记录了PE文件中所有的数据的组织方式,它类似于一本书的目录,通过目录我们可以快速定位到某个具体的章节:通过P ...

  2. Windows Pe 第三章 PE头文件(下)

    3.5  数据结构字段详解 3.5.1  PE头IMAGE_NT_HEADER的字段 1.IMAGE_NT_HEADER.Signature +0000h,双字.PE文件标识,被定义为00004550 ...

  3. Windows Pe 第三章 PE头文件(中)

    这一章的上半部分大体介绍了下PE文件头,下半部分是详细介绍里面的内容,这一章一定要多读几遍,好好记记基础概念和知识,方便之后的学习. 简单回忆一下: 3.4  PE文件头部解析 3.4.1 DOS M ...

  4. Windows Pe 第三章 PE头文件-EX-相关编程-1(PE头内容获取)

    获取pE头相关的内容,就是类似如下内容 原理:比较简单,直接读取PE到内存,然后直接强转就行了. #include <windows.h> #include <stdio.h> ...

  5. Android JNI入门第三篇——jni头文件分析

    一. 首先写了java文件: public class HeaderFile { private native void  doVoid(); native int doShort(); native ...

  6. conan使用(三)--打包只有头文件的库

    参考:https://docs.conan.io/en/latest/howtos/header_only.html?highlight=header%20only 对于只含头文件的库打包非常简单,以 ...

  7. Windows PE 第十三章 PE补丁技术

    PE补丁技术 这章很多东西之前都见过,也单独总结过,比如动态补丁里说的远程代码注入,还有hijack什么的.之前整理过的这里就不细说了,大体说下思路.这里总结一些之前没总结过的东西. 资料中把补丁分为 ...

  8. Python开发【第三章】:文件操作

    一.文件操作模式概述 1.打开文件的模式: r, 只读模式[默认] w,只写模式[不可读:不存在则创建:存在则删除内容:] a, 追加模式[不可读:不存在则创建:存在则只追加内容:] 2." ...

  9. 【PE结构】由浅入深PE基础学习-菜鸟手动查询导出表、相对虚拟地址(RVA)与文件偏移地址转换(FOA)

    0 前言 此篇文章想写如何通过工具手查导出表.PE文件代码编程过程中的原理.文笔不是很好,内容也是查阅了很多的资料后整合出来的.希望借此加深对PE文件格式的理解,也希望可以对看雪论坛有所贡献.因为了解 ...

随机推荐

  1. 【小白学算法】5.链表(linked list)、链表的添加

    链表其实也就是 线性表的链式存储结构,与之前讲到的顺序存储结构不同. 我们知道顺序存储结构中的元素地址都是连续的,那么这就有一个最大的缺点:当做插入跟删除操作的时候,大量的元素需要移动. 如图所示,元 ...

  2. 「免费开源」基于Vue和Quasar的前端SPA项目crudapi后台管理系统实战之自定义组件(四)

    基于Vue和Quasar的前端SPA项目实战之序列号(四) 回顾 通过上一篇文章 基于Vue和Quasar的前端SPA项目实战之布局菜单(三)的介绍,我们已经完成了布局菜单,本文主要介绍序列号功能的实 ...

  3. 【FreeRTOS】cpu利用率统计

    目录 前言 概念 作用 必看点 实现 添加几个宏定义 源码 FreeRTOS STM32 定时器 简要说明 前言 本笔记基于 stm32+FreeRTOS. 主要参考野火.安富莱. 概念 简单概要: ...

  4. go的令牌桶实现库 go-rate

    关于我 我的博客|文章首发 go-rate是速率限制器库,基于 Token Bucket(令牌桶)算法实现. go-rate被用在LangTrend的生产中 用于遵守GitHub API速率限制. 速 ...

  5. Dynamics CRM绑定表单查看当前表单的数据参数传递

    我们做报表的时候,报表运行的位置可以在列表.也可以在报表区同时也可以在表单界面 其他两个都还好,不需要进行过滤,但是在表单界面运行报表需要将表单的GUID传给报表获取数据,否则就得手动去输入ID 具体 ...

  6. spring-cloud-consul 服务注册发现与配置

    下面是 Spring Cloud 支持的服务发现软件以及特性对比(Eureka 已停止更新,取而代之的是 Consul): Feature euerka Consul zookeeper etcd 服 ...

  7. 关于js中this的指向详细总结、分析

    目录 this的指向详细剖析 当作为函数直接调用时, this => window 当作为构造函数时,this => 构造出的实例对象 当作为对象的方法调用时,this => 调用方 ...

  8. 消息中间件-ActiveMQ支持的消息协议

    package com.study.mq.a1_example.helloworld.queue; import org.apache.activemq.ActiveMQConnectionFacto ...

  9. 又一起.NET程序挂死, 用 Windbg 抽丝剥茧式的真实案例分析

    一:背景 1. 讲故事 前天有位粉丝朋友在后台留言让我帮忙看看他的 Winform程序 UI无响应 + 410线程 到底是啥情况,如下图: 说实话,能看到这些真实案例我是特别喜欢的 ,就像医生看病,光 ...

  10. 1.稀疏数组_java实现

    稀疏数组 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组. 稀疏数组的处理方法是: 记录数组一共有几行几列,有多少个不同的值 把具有不同值的元素行列及值记录在一个小规 ...