RVA与Offset的换算函数
function RVAToFileOffset(FileName:string; RVA: Cardinal): Cardinal;
var
MemPE: TFileStream;
PEDosHead: TImageDosHeader;
PENtHead: TImageNtHeaders;
Section : TImageSectionHeader;
i, SectionsCount: Integer;
begin
Result := RVA;
MemPE:=TFileStream.Create(FileName,fmOpenReadWrite);
try
MemPE.Seek(0, soFromBeginning);
MemPE.Read(PEDosHead, SizeOf(PEDosHead));
MemPE.Seek(PEDosHead._lfanew, soFromBeginning);
MemPE.Read(PENtHead, SizeOf(PENtHead));
SectionsCount := PENtHead.FileHeader.NumberOfSections;
if SectionsCount <> 0 then
for i := 0 to SectionsCount - 1 do
begin
MemPE.Read(Section, SizeOf(Section));
if (RVA >= Section.VirtualAddress) and (RVA < Section.VirtualAddress + Section.SizeOfRawData) then
begin
Result := RVA - Section.VirtualAddress + Section.PointerToRawData;
Break;
end;
end;
finally
FreeAndNil(MemPE);
end;
end;
function FileOffsetToRVA(FileName:string; Offset: Cardinal): Cardinal;
var
MemPE: TFileStream;
PEDosHead: TImageDosHeader;
PENtHead: TImageNtHeaders;
Section : TImageSectionHeader;
i, SectionsCount: Integer;
begin
Result :=Offset;
MemPE:=TFileStream.Create(FileName,fmOpenReadWrite);
try
MemPE.Seek(0, soFromBeginning);
MemPE.Read(PEDosHead, SizeOf(PEDosHead));
MemPE.Seek(PEDosHead._lfanew, soFromBeginning);
MemPE.Read(PENtHead, SizeOf(PENtHead));
SectionsCount := PENtHead.FileHeader.NumberOfSections;
if SectionsCount <> 0 then
for i := 0 to SectionsCount - 1 do
begin
MemPE.Read(Section, SizeOf(Section));
if (Offset >= Section.PointerToRawData) and (Offset < Section.PointerToRawData + Section.SizeOfRawData) then
begin
Result := Offset - Section.PointerToRawData + Section.VirtualAddress;
Break;
end;
end;
finally
FreeAndNil(MemPE);
end;
end;
程序源代码:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Button2: TButton;
Edit5: TEdit;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function FileOffsetToRVA(FileName:string; Offset: Cardinal): Cardinal;
var
MemPE: TFileStream;
PEDosHead: TImageDosHeader;
PENtHead: TImageNtHeaders;
Section : TImageSectionHeader;
i, SectionsCount: Integer;
begin
Result :=Offset;
MemPE:=TFileStream.Create(FileName,fmOpenReadWrite);
try
MemPE.Seek(0, soFromBeginning);
MemPE.Read(PEDosHead, SizeOf(PEDosHead));
MemPE.Seek(PEDosHead._lfanew, soFromBeginning);
MemPE.Read(PENtHead, SizeOf(PENtHead));
SectionsCount := PENtHead.FileHeader.NumberOfSections;
if SectionsCount <> 0 then
for i := 0 to SectionsCount - 1 do
begin
MemPE.Read(Section, SizeOf(Section));
if (Offset >= Section.PointerToRawData) and (Offset < Section.PointerToRawData + Section.SizeOfRawData) then
begin
Result := Offset - Section.PointerToRawData + Section.VirtualAddress;
Break;
end;
end;
finally
FreeAndNil(MemPE);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2.Text := string(FileOffsetToRVA(Edit5.Text,Cardinal(Edit1.Text)));
end;
function RVAToFileOffset(FileName:string; RVA: Cardinal): Cardinal;
var
MemPE: TFileStream;
PEDosHead: TImageDosHeader;
PENtHead: TImageNtHeaders;
Section : TImageSectionHeader;
i, SectionsCount: Integer;
begin
Result := RVA;
MemPE:=TFileStream.Create(FileName,fmOpenReadWrite);
try
MemPE.Seek(0, soFromBeginning);
MemPE.Read(PEDosHead, SizeOf(PEDosHead));
MemPE.Seek(PEDosHead._lfanew, soFromBeginning);
MemPE.Read(PENtHead, SizeOf(PENtHead));
SectionsCount := PENtHead.FileHeader.NumberOfSections;
if SectionsCount <> 0 then
for i := 0 to SectionsCount - 1 do
begin
MemPE.Read(Section, SizeOf(Section));
if (RVA >= Section.VirtualAddress) and (RVA < Section.VirtualAddress + Section.SizeOfRawData) then
begin
Result := RVA - Section.VirtualAddress + Section.PointerToRawData;
Break;
end;
end;
finally
FreeAndNil(MemPE);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Edit4.Text := string(RVAToFileOffset(Edit5.Text,Cardinal(Edit3.Text)));
end;
end.
程序界面:

RVA与Offset的换算函数的更多相关文章
- excel中的单位换算函数convert()
有时,我们在处理数据的时候,需要进行单位换算,比如“7小时24分”换算成小时,可以直接除以或乘以相应的进制来计算,但是在excel中,有一个convert()函数更加方便: 此函数属于工程函数,平时可 ...
- 【PE结构】由浅入深PE基础学习-菜鸟手动查询导出表、相对虚拟地址(RVA)与文件偏移地址转换(FOA)
0 前言 此篇文章想写如何通过工具手查导出表.PE文件代码编程过程中的原理.文笔不是很好,内容也是查阅了很多的资料后整合出来的.希望借此加深对PE文件格式的理解,也希望可以对看雪论坛有所贡献.因为了解 ...
- RVA与RWA的关系
RVA与RWA的关系 原理比较简单:首先判断这个地址是否在PE头中,如果在,文件偏移和内存偏移相等,如果存在于文件的区段中,则利用以下公式: 内存偏移 - 该段起始的RVA(VirtualAddres ...
- 【python cookbook】【数据结构与算法】19.同时对数据做转换和换算
问题:我们需要调用一个换算函数(例如sum().min().max()),但是首先需对数据做转换或者筛选处理 解决方案:非常优雅的方法---在函数参数中使用生成器表达式 例如: # 计算平方和 num ...
- C语言中fseek函数
C语言fseek()函数:用来设定文件的当前读写位置 头文件: #include <stdio.h> 定义函数: int fseek(FILE * stream, long offset, ...
- 【Linux C中文函数手册】文件内容控制函数
文件内容控制函数 1)clearerr 清除文件流的错误旗标 相关函数 feof表头文件 #include<stdio.h>定义函数 void clearerr(FILE * stream ...
- C语言文件函数
FILE *fp: 其中的FILE应该大写,它实际上是系统定义的一个结构,在stdio.h文件中.该结构中有文件名,文件状态,文件当前的读写信息等. fp是指向FILE结构的指针变量,通过fp可以找到 ...
- C语言文件操作函数
C语言文件操作函数大全 clearerr(清除文件流的错误旗标) 相关函数 feof表头文件 #include<stdio.h> 定义函数 void clearerr(FILE * str ...
- fseek/ftell/rewind/fgetpos/fsetpos函数使用-linux
程序: #include<stdio.h> int main(int argc,char *argv[]) { FILE * stream; fpos_t pos; stream = fo ...
随机推荐
- 装黑苹果的那些事儿(以ThinkpadE540为例)
苹果系统,有着比window更好的安全性和方便性,更重要的事,没有MAC系统环境,进行iOS开发,是很麻烦的,对新手来说,是很懊恼的一件事.但是白苹果像件奢侈品,吾等常人,很难有经济消费.如是黑苹果是 ...
- 对云风 cstring 第二次解析
前言 从明天起 关心粮食和蔬菜 我有一所房子 面朝大海 春暖花开 本文前提条件 1.了解 posix 线程 2.了解 原子操作 3.具备简单C基础,或者 你也敲一遍. 如果上面不太清楚,你可以翻看我以 ...
- 使用 libevent 和 libev 提高网络应用性能——I/O模型演进变化史
构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件,无论它们是内部请求还是网络连接,都要有效地处理它们的操作. 有许多解决方案,但事件驱动也被广泛应用到网络编程中.并大规模部署在高 ...
- hdu 4715 Difference Between Primes
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4715 Difference Between Primes Description All you kn ...
- CDN技术原理
要了解CDN的实现原理,首先让我们来回顾一下网站传统的访问过程,以便理解其与CDN访问方式之间的差别: 由上图可见,传统的网站访问过程为: 1. 用户在浏览器中输入要访问的域名: 2. 浏览器向域名解 ...
- 三种嵌入式web服务器(Boa / lighttpd / shttpd)的 linux移植笔记
一:移植Boa(web服务器)到嵌入式Linux系统 一.Boa程序的移植 1.下载Boa源码 下载地址: http://www.boa.org/ 目前最新发行版本: 0.94.13 ...
- Go中的指针与函数接收器
Go中使用*号表示指针,但是没有指针算数,不能对其进行加减.同时内存管理都由Go来负责,不需要拖动释放内存. Go中的函数接收者,可以为值类型,也可以是引用类型. 看代码: package main ...
- [译]rabbitmq 2.4 Multiple tenants: virtual hosts and separation
我对rabbitmq学习还不深入,这些翻译仅仅做资料保存,希望不要误导大家. With exchanges, bindings, and queues under your belt, you mig ...
- Block 块
代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱字符(^)是块的语法标记.按照我们熟悉的参数语法规约所定 ...
- 2. VS使用---HelloWorld
摘要: ------------------------------------------------------------------------------------- 1. VS2010里 ...