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. PHP系统函数

    (一)字符串处理函数 Chr函数 作用:根据ASCII码返回相应的字符. 语法:string chr(int ascii): Chop函数 作用:去除字符串中连续空格和空白行. 语法:string c ...

  2. CSS 设置TABLE 表格 边框

    /*table列表 合并边框设置*/ .tablelist { border-collapse:collapse; } /*table列表 设置边框宽度及颜色*/ .tablelist td { bo ...

  3. linux 禁止指定账号ssh登陆

    1 2 3 4 vim /etc/pam.d/sshd   #在第一行添加以下代码 auth       required     pam_listfile.so item=user sense=de ...

  4. [转]分布式文件系统FastDFS架构剖析

    [转]分布式文件系统FastDFS架构剖析 http://www.programmer.com.cn/4380/ 文/余庆 FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实 ...

  5. svn merge和branch

    http://www.cnblogs.com/cxd4321/archive/2012/07/12/2588110.html 使用svn几年了,一直对分支和合并敬而远之,一来是因为分支的管理不该我操心 ...

  6. JAVA事务

    一.什么是事务 我们通常会认为事务与数据库有关. 事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库的操作.事务的正确执行使得数据库从一种状态转换成另外一种状态. 事务必须服从IS ...

  7. 状压DP

    今天稍微看了下状压DP,大概就是这样子的,最主要的就是位运算, i and (1<<k)=0 意味着i状态下没有 k : i and (1<<k)>0 意味着i状态下有 ...

  8. [shell基础]——split命令

    测试文本 # cat name1.txt name1 alvin1 name2 alvin2 name3 alvin3 name4 alvin4 此时目录下就只有这个文件 # ls name1.txt ...

  9. [网络配置相关]——ifconfig命令、ip命令、route命令

    ifconfig命令 1. 查看已被激活的网卡的详细信息 # ifconfig eth0 Link encap:Ethernet HWaddr 00:30:67:F2:10:CF inet addr: ...

  10. Ubuntu 14.04安装配置NFS服务器

    (一)安装NFS服务器1.1-安装Ubuntu nfs服务器端: sudo apt-get install nfs-kernel-server 1.2-安装nfs的客户端: sudo apt-get ...