PDA

View Full Version : How to convert RVA to RAW Offset in a program?


Solomon
September 12th, 2001, 23:21
In my little program I just open the PE file(using CreateFile, not LoadLibrary), read the byte stream and get some RVAs.

How to convert the RVA to the corresponding RAW OFFSETS?
I know there are such tools but wonder how to implement this.

Thank you very much for your hint.

CoDe_InSiDe
September 13th, 2001, 00:49
Hi Solomon,

It's actually very easy, but maybe difficult to explain
Suppose you want to convert the OEP from Virtual to Raw Offset.
And the OEP = 0000135F
Now first thing you need to do is subtracting the ImageBase, In the PE Header the OEP doesn't have the ImageBase so it's not needed now
Then you must find out to which Section this OEP belongs.
Suppose we've got the following 2 Sections:

1st Section
Name: .text
VirtualSize: 00001000
VirtualOffset: 00001000
RawSize: 00000C00
RawOffset: 00000400

2nd Section
Name: .data
VirtualSize: 00001000
VirtualOffset: 00002000
RawSize: 00000800
RawOffset: 00001000

Then you must check (beginning from the first Section) if it's VirtualOffset is equal or lower then the VirtualOffset you want to convert (this case our OEP = 0000135F)
The first Section has VirtualOffset = 00001000 so that's lower then our OEP and so that's good
If the VirtualOffset would be equal to our OEP then we already found the correct Section, but if it's lower then you need to check the second Section if that VirtualOffset is "higher" then our OEP.
If so then we need the first Section.
If the VirtualOffset of the second Section is still lower then our OEP we need to continue searching in the same way
Ok, so in this example we need the first Section
So after you found the correct Section then you can do this to convert it:

OEP - VirtualOffset + RawOffset
0000135F - 00001000 + 00000400 = 0000075F

So 0000075F is the converted OEP
Now the only thing that's left is to add the BaseAddress of where you load the Program in memory, with ReadFile for example
And that's it i hope you understand about what i'm talking here
There are maybe some other ways but i always do it like this

Cya...

CoDe_InSiDe

Solomon
September 13th, 2001, 03:43
Thank you CoDe_InSiDe for your so detailed illustration.

I just finished my little prog using this section_table_traversing algorithm. Now I have a deeper understanding of PE structure.

thx again

CrackZ
September 16th, 2001, 08:40
Hiya,

I know its a while since this thread was 'active', but anyhow.

I wrote a function many moons ago to do this conversion, I've pasted it here, all it relies on you doing is passing a pointer to the PE header and the RVA you desire converting, (how you get the PE header is your business ;-) ).

; ##################################################
; RvaToRaw() - Takes a rva and converts it to a raw offset.
; Returns : EAX=raw.
; ##################################################

RvaToRaw proc pe_headerWORD, rvaWORD
push ebp ebx ecx edx esi edi
xor eax, eax
mov ecx, rva
cdq
mov edi, pe_header
mov ax, word ptr [edi.3ch] ; offset 'PE'
add edi, eax
mov dx, [edi.6h] ; number of sections
add edi, 0f8h ; start of sections

RvaToRawLoop:
mov eax, [edi.0ch] ; virtual address
cmp eax, ecx
ja RvaToRawDone
add edi, 28h ; next section
dec edx
jnz RvaToRawLoop ; last section drops out of the loop

RvaToRawDone:
mov eax, rva
mov ecx, [edi-1ch] ; previous sections virtual address
sub eax, ecx
mov ecx, [edi-14h] ; previous sections raw offset
add ecx, eax
xchg eax, ecx

RvaToRawEnd:
pop edi esi edx ecx ebx ebp
ret
RvaToRaw endp

Amend, use, abuse or improve it to your needs.

Regards

CrackZ.

Solomon
September 16th, 2001, 20:37
Thank you CrackZ for your nice source!