Exetools  

Go Back   Exetools > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 07-09-2004, 07:12
yaa
 
Posts: n/a
Question How to obtain the file offset from an RVA???

Hello,

I'm writing a bit of code to better understand PE format, but one thing I still can't get is how a file offset (position in the physical file on disk) is obtained from an RVA. I don't need a tool, I'd need to understand. Can anyone explain (or provide the function) it in terms of the members of the C structures used to read the DOS, COFF, PE, Section headers???
Thx.

yaa
Reply With Quote
  #2  
Old 07-09-2004, 09:13
JMI JMI is offline
Leader
 
Join Date: Jan 2002
Posts: 1,627
Rept. Given: 5
Rept. Rcvd 199 Times in 99 Posts
Thanks Given: 0
Thanks Rcvd at 96 Times in 94 Posts
JMI Reputation: 100-199 JMI Reputation: 100-199
From "Iczelion's Win32 Assembly Homepage"

http://win32assembly.online.fr/pe-tut4.html


There is a word that's used frequently in relation to PE file format: RVA
RVA stands for relative virtual address. You know what virtual address is. RVA is a daunting term for such a simple concept. Simply put, an RVA is a distance from a reference point in the virtual address space. I bet you're familiar with file offset: an RVA is exactly the same thing as file offset. However, it's relative to a point in virtual address space, not a file. I'll show you an example. If a PE file loads at 400000h in the virtual address (VA) space and the program starts execution at the virtual address 401000h, we can say that the program starts execution at RVA 1000h. An RVA is relative to the starting VA of the module. Why does the PE file format use RVA? It's to help reduce the load of the PE loader. Since a module can be relocated anywhere in the virtual address space, it would be a hell for the PE loader to fix every relocatable items in the module. In contrast, if all relocatable items in the file use RVA, there is no need for the PE loader to fix anything: it simply relocates the whole module to a new starting VA. It's like the concept of relative path and absolute path: RVA is akin to relative path, VA is like absolute path.

Regards,
__________________
JMI
Reply With Quote
  #3  
Old 07-09-2004, 11:47
Lunar_Dust
 
Posts: n/a
I have source code that I use, looking thru it should help you understand at least a bit, it shows the structures you talk about:

Code:
// Converts an RVA virtual address to a file offset.
DWORD RvaToOffset(LPVOID dwFileBase, DWORD Rva)
{

	IMAGE_DOS_HEADER *DosHeader;
	IMAGE_NT_HEADERS * MainPEHeader;
	LPVOID PEHeader = NULL;
	LPVOID pSection = NULL;
	IMAGE_SECTION_HEADER* Section=NULL;
	long NumberOfSections;

	DosHeader = (IMAGE_DOS_HEADER*)dwFileBase;
	PEHeader = (LPVOID)((DWORD)dwFileBase + (DWORD)DosHeader->e_lfanew);

	MainPEHeader = (IMAGE_NT_HEADERS*)PEHeader;
	NumberOfSections = MainPEHeader->FileHeader.NumberOfSections;

	pSection = (LPVOID)((DWORD)PEHeader + sizeof(IMAGE_NT_HEADERS));

	for (int Count=0;Count <= NumberOfSections;Count++)
	{
		
		Section = (IMAGE_SECTION_HEADER*)pSection;
		if (Rva >= Section->VirtualAddress)
		{
			if (Rva < (Section->VirtualAddress + Section->SizeOfRawData))
			{
				// it's in this section..
				long AddressDiff = Rva - Section->VirtualAddress;
				return (Section->PointerToRawData + AddressDiff);

			}
		}
	
	pSection = (LPVOID)((DWORD)pSection + sizeof(IMAGE_SECTION_HEADER));

	}

	return 0;

}




// Converts a file offset to a RVA address
DWORD OffsetToRva(LPVOID dwFileBase, DWORD Offset)
{

	IMAGE_DOS_HEADER *DosHeader;
	IMAGE_NT_HEADERS * MainPEHeader;
	LPVOID PEHeader = NULL;
	LPVOID pSection = NULL;
	IMAGE_SECTION_HEADER* Section=NULL;
	long NumberOfSections;

	DosHeader = (IMAGE_DOS_HEADER*)dwFileBase;
	PEHeader = (LPVOID)((DWORD)dwFileBase + (DWORD)DosHeader->e_lfanew);

	MainPEHeader = (IMAGE_NT_HEADERS*)PEHeader;
	NumberOfSections = MainPEHeader->FileHeader.NumberOfSections;

	pSection = (LPVOID)((DWORD)PEHeader + sizeof(IMAGE_NT_HEADERS));

	for (int Count=0;Count <= NumberOfSections;Count++)
	{
		
		Section = (IMAGE_SECTION_HEADER*)pSection;
		if (Offset >= Section->PointerToRawData)
		{
			if (Offset < (Section->PointerToRawData + Section->SizeOfRawData))
			{
				// it's in this section..
				long AddressDiff = Offset - Section->PointerToRawData;
				return (Section->VirtualAddress + AddressDiff);

			}
		}
	
	pSection = (LPVOID)((DWORD)pSection + sizeof(IMAGE_SECTION_HEADER));

	}

	return 0;

}



-Lunar
Reply With Quote
  #4  
Old 07-09-2004, 17:26
yaa
 
Posts: n/a
JMI, thx for the snippet ... Iczelion was indeed very clear in explaining RVAs ... and has even taken the time to explain why RVAs are used so much around. Lunar_Dust thank you for the code ... I had written myself such functions but I wasn't sure that I was doing things correctly or was taking for granted some things to always be the same (and they often are not) in PE files.


yaa
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to calculate RVA from file offset Shub-Nigurrath General Discussion 9 09-22-2009 12:33


All times are GMT +8. The time now is 04:33.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( 1998 - 2024 )