zoukankan      html  css  js  c++  java
  • 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.

    程序界面:

  • 相关阅读:
    生成随机数的范围的公式
    正则匹配<img src="xxxxxx" alt="" />标签的相关写法
    js 日常问题记录
    css 三角实例
    /users/products.:format 这种写法的其对应解析字符写法
    package.json 的语法解释
    replace 全局替换 和 数组去空
    js checkbox获取选中的值
    JavaScript基础知识一
    移动 Web 设计
  • 原文地址:https://www.cnblogs.com/milantgh/p/3959216.html
Copyright © 2011-2022 走看看