日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

逆向笔记——PE文件相对虚拟地址(RVA)转文件偏移地址(FOA)

發布時間:2023/12/15 综合教程 20 生活家
生活随笔 收集整理的這篇文章主要介紹了 逆向笔记——PE文件相对虚拟地址(RVA)转文件偏移地址(FOA) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

手工

編譯一個帶有全局變量的exe
這是代碼


#include <stdio.h>

int globalVar = 0x12345678;

void main()
{
	printf("globalVar = %x, RVA=%x
",globalVar,&globalVar);	//RVA=424a30 | FOA=424a30-400000=24a30

}

打印出來的是全局變量globalVar 在內存中的地址 VA=424a30

PETool看基址=00400000,RVA=VA-ImageBase=424a30-00400000 = 24a30

再看看在內存中、文件中的對齊方式
1、如果在內存中和文件中的對齊方式是一致的,那么 RVA=FOA=24a30
2、如果它們的對齊方式不一樣,那么 FOA = 節.PointToRawData+差值偏差
差值偏差=RVA - 節.VirtuallAddress,如果想不通,看下圖:

我這里的對齊方式是一樣的,所以FOA=24a30

PE編輯工具打開exe文件,找24a30地址的值,改之為 66666666

保存,運行exe看這時候的值

代碼實現 RVA->FVA

步驟:

代碼:


#include <stdio.h>
#include <windows.h>
/************************
功能:內存中的相對虛擬偏移轉換為文件中的偏移
步驟:假設x是需要計算FOA的內存地址
	1、先計算 RVA = x-ImageBase
	2、計算差值偏差 y = RVA-節.VirtualAddress
	3、計算FOA=節.PointToRawData+y
*************************/
unsigned char* FileBuffer(const char* FileName);
unsigned char* RVAToFVA(unsigned char* x) //x的位置
{
	unsigned char* FVA=NULL;
	unsigned char* RVA=NULL;
	PIMAGE_DOS_HEADER pDosHeader;
	PIMAGE_NT_HEADERS pNtHeaders;
	PIMAGE_SECTION_HEADER pSectionHeader;

	//打開文件映射到filebuffer
	unsigned char* fileBuffer = FileBuffer("test.exe");

	//得到 PIMAGE_OPTIONAL_HEADER=>ImageBase  PIMAGE_SECTION_HEADER=>VirtualAddress  PointToRawData
     pDosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
     pNtHeaders = (PIMAGE_NT_HEADERS)(fileBuffer + pDosHeader->e_lfanew);
     pSectionHeader = (PIMAGE_SECTION_HEADER)(pNtHeaders+1);
	 printf("%x
",pNtHeaders->OptionalHeader.ImageBase);
	 RVA = x-pNtHeaders->OptionalHeader.ImageBase;
	 //判斷是否在DOS+NT頭部內,是則RVA=FOA
	 if(x<=(unsigned char*)pNtHeaders->OptionalHeader.SizeOfHeaders)
	 {
		FVA = RVA;
		printf("在頭部FVA=RVA=%x
",FVA);
		return FVA;
	 }
	
	 //判斷在哪個節
	 unsigned int i=0;
	 for(i=0;i<pNtHeaders->FileHeader.NumberOfSections;i++)
	 {
		printf("%x
",pSectionHeader[i].PointerToRawData);

		printf("%x
",pSectionHeader[i].VirtualAddress);

		if(RVA>=(unsigned char*)pSectionHeader[i].VirtualAddress && RVA<=(unsigned char*)(pSectionHeader[i].VirtualAddress+pSectionHeader[i].Misc.VirtualSize) )
		{
			//在這個節:計算偏差->計算FOA

			FVA = pSectionHeader[i].PointerToRawData+(RVA-pSectionHeader[i].VirtualAddress);
			printf("在%s節中,FVA=%x
", pSectionHeader[i].Name,FVA);
			return FVA;
		}
	 }
	return NULL;
}

void main()
{
	unsigned char* x = (unsigned char*)0x424a30;
	RVAToFVA(x); //內存中的虛擬地址
}

//將PE文件讀到FileBuffer
unsigned char* FileBuffer(const char* FileName)
{
     unsigned char* Heap = NULL;
     FILE* Stream;

     //打開文件
     Stream = fopen(FileName,"rb");
     //計算文件大小
     fseek(Stream,0,SEEK_END);
     long FileSize = ftell(Stream);
     fseek(Stream,0,SEEK_SET);

     //分配堆空間
     Heap = (unsigned char*)malloc(sizeof(char)*FileSize);
     //將文件拷到堆
     fread(Heap,sizeof(char),FileSize,Stream);
     fclose(Stream);

	 return Heap;
}

FVA->RVA 原理同上

      設x 為節數據的任意一位置

      1.計算差值偏移:
差值 = x - 節.PointerToRawData(節數據在文件中開始的位置)

      2.計算RVA
RVA = 差值 + 節.VirtuallAddress(節數據在內存中展開的位置)

      3.計算虛擬地址:
VA = RVA + ImageBase

判斷x在哪一個節中的條件: x <= 節.PointerToRawData + 節.SizeofRawData

總結

以上是生活随笔為你收集整理的逆向笔记——PE文件相对虚拟地址(RVA)转文件偏移地址(FOA)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。