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的换算函数的更多相关文章

  1. excel中的单位换算函数convert()

    有时,我们在处理数据的时候,需要进行单位换算,比如“7小时24分”换算成小时,可以直接除以或乘以相应的进制来计算,但是在excel中,有一个convert()函数更加方便: 此函数属于工程函数,平时可 ...

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

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

  3. RVA与RWA的关系

    RVA与RWA的关系 原理比较简单:首先判断这个地址是否在PE头中,如果在,文件偏移和内存偏移相等,如果存在于文件的区段中,则利用以下公式: 内存偏移 - 该段起始的RVA(VirtualAddres ...

  4. 【python cookbook】【数据结构与算法】19.同时对数据做转换和换算

    问题:我们需要调用一个换算函数(例如sum().min().max()),但是首先需对数据做转换或者筛选处理 解决方案:非常优雅的方法---在函数参数中使用生成器表达式 例如: # 计算平方和 num ...

  5. C语言中fseek函数

    C语言fseek()函数:用来设定文件的当前读写位置 头文件: #include <stdio.h> 定义函数: int fseek(FILE * stream, long offset, ...

  6. 【Linux C中文函数手册】文件内容控制函数

    文件内容控制函数 1)clearerr 清除文件流的错误旗标 相关函数 feof表头文件 #include<stdio.h>定义函数 void clearerr(FILE * stream ...

  7. C语言文件函数

    FILE *fp: 其中的FILE应该大写,它实际上是系统定义的一个结构,在stdio.h文件中.该结构中有文件名,文件状态,文件当前的读写信息等. fp是指向FILE结构的指针变量,通过fp可以找到 ...

  8. C语言文件操作函数

    C语言文件操作函数大全 clearerr(清除文件流的错误旗标) 相关函数 feof表头文件 #include<stdio.h> 定义函数 void clearerr(FILE * str ...

  9. fseek/ftell/rewind/fgetpos/fsetpos函数使用-linux

    程序: #include<stdio.h> int main(int argc,char *argv[]) { FILE * stream; fpos_t pos; stream = fo ...

随机推荐

  1. Java数字处理

    给出一个不多于5位的正整数,要求如下: (1)求出该数是几位数. (2)分别打印出每一位数字. (3)按照逆序打印出各位数值. 按照以上要求,首先得用户从键盘输入一个不多于5位的正整数,可以用Syst ...

  2. DELPHI 使用dbexpress控件连接MySQL数据库方法

    1. 在窗体上放置4个控件: SQLConnection1,SimpleDataSet1,DataSource1,DBGrid (注意: 如果 出现"Operation not allowe ...

  3. 第三节:卸载AppDomain

    AppDomain很出色的一个能力就是它允许卸载.卸载AppDomain会导致CLR卸载AppDomain中的所有程序集.还会释放AppDomain的Loader堆.为了卸载一个AppDomain,可 ...

  4. 动态切换采用 CSplitterWnd 静态划分的视图布局(MFC)

    标题读起来有些拗口,具体是什么情况,我们来看: 一.问题的提出 一个采用MFC开发的软件,其窗体视图采用CSplitterWnd三分,效果如下图所示: 图1 软件的默认视图布局 该MFC开发的软件功能 ...

  5. JSAPI_Ticket签名

    1.微信 JS 接口签名校验工具 2.具体开发 2.1 获取access_token,然后jsapi_ticket /** * 获取access_token,然后jsapi_ticket */ pri ...

  6. SQL开发 循序渐进

    吉庆师傅整理: http://www.itpub.net/thread-1418150-1-1.html

  7. arcgis中注记的高级处理

    在实际制图过程中,常遇到一个图层的多个要素展示,将标注转换为注记的之后,可以对注记进行移动调整位置等手动更改.这样为避免重复地移动注记位置.可以采用如下方案: 1.将图层标注转换为注记 2.将注记存储 ...

  8. C# 堆和栈的区别-该文转自:http://www.itcodes.cn/746.html | 程序人生

    理解堆与栈对于理解.NET中的内存管理.垃圾回收.错误和异常.调试与日志有很大的帮助.垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不代表程 ...

  9. Android--Fragment的懒加载

    我们都知道,fragment放在viewPager里面,viewpager会帮我们预先加载一个,但是当我们要看fragment里面的内容时,我们也许只会去看第一个,不会去看第二个,如果这时候不去实现f ...

  10. linux命令行下使用R语言绘图

    系统:centos 6.4 64bit 环境安装参考:http://hi.baidu.com/solohac/item/4a18e78f1bef9b5825ebd99c 在R语言中可以使用png()等 ...