Jump to content
Sign in to follow this  
Sipher

File offset to Olly Address

Recommended Posts

Sipher

Hiya,


 


Am trying to wrap my brains around this.


 


I guess I need an example to really understand it.


 


For eg: Opening the file in Hex Workshop shows me the required byte/s I am interested in @ 00000156. How do I relate this address to Olly??


 


Inputs welcomed.


 


Thanks!!


 


 


Share this post


Link to post
Share on other sites
Blue Indian

Read the details given on the site below:


http://www.tech-juice.org/2011/02/21/portable-executable-converting-rva-to-file-offset-and-back/


 


C Source code (Credits of Eggi)


* is_hdr is a array of IMAGE_SECTION_HEADERS and scount is the number of sections (file header)



DWORD OffsetToRVA(DWORD offset, IMAGE_SECTION_HEADER *is_hdr, unsigned scount){
// Find section holding the Offset
for(unsigned i = 0; i < scount;i++)
if((offset >= is_hdr[i].PointerToRawData) && (offset <= is_hdr[i].PointerToRawData +is_hdr[i].SizeOfRawData)){
// Convert Offset to RVA
return offset+is_hdr[i].VirtualAddress-is_hdr[i].PointerToRawData;
}
return 0;
}

More details about this (taken from http://stackoverflow.com/questions/2170843/va-virtual-adress-rva-relative-virtual-address )



 



Most Windows process (*.exe) are loaded in (user mode) memory address 0x00400000, that's what we call the "virtual address" (VA) - because they are visible only to each process, and will be converted to different physical addresses by the OS (visible by the kernel / driver layer).


For example, a possible physical memory address (visible by the CPU):



0x00300000 on physical memory has process A's main
0x00500000 on physical memory has process B's main

And the OS may have a mapping table:



process A's 0x00400000 (VA) = physical address 0x00300000
process B's 0x00400000 (VA) = physical address 0x00500000

Then when you try to read 0x004000000 in process A, you'll get the content which is located on 0x00300000 of physical memory.


Regarding RVA, it's simply designed to ease relocation. When loading relocable modules (eg, DLL) the system will try to slide it through process memory space. So in file layout it puts a "relative" address to help calculation.


For example, a DLL C may have this address:



RVA 0x00001000 DLL C's main entry

When being loaded into process A at base address 0x10000000, C's main entry become



VA = 0x10000000 + 0x00001000 = 0x10001000
(if process A's VA 0x10000000 mapped to physical address was 0x30000000, then
C's main entry will be 0x30001000 for physical address).

When being loaded into process B at base address 0x32000000, C's main entry become



VA = 0x32000000 + 0x00001000 = 0x32001000
(if process B's VA 0x32000000 mapped to physical address was 0x50000000, then
C's main entry will be 0x50001000 for physical address).

Usually the RVA in image files is relative to process base address when being loaded into memory, but some RVA may be relative to the "section" starting address in image or object files (you have to check the PE format spec for detail). No matter which, RVA is relative to "some" base VA.


To summarize,


  1. Physical Memory Address is what CPU sees

  2. Virtual Addreess (VA) is relative to Physical Address, per process (managed by OS)

  3. RVA is relative to VA (file base or section base), per file (managed by linker and loader)

(edit) regarding claw's new question:


The value of RVA of a method/variable is NOT always its offset from the beginning of the file. The are usually relative to some VA, which may be a default loading base address or section base VA - that's why I say you must check the PE format spec for detail.


You tool PEView is trying to display every byte's RVA to load base address. Since the sections start at different base, RVA may become different when crossing sections.


Regarding your guesses, the are very close to the correct answers:



  1. Usually we won't discuss the "RVA" before sections, but the PE header will still be loaded until the end of section headers. Gap between section header and section body (if any) won't be loaded. You can examine that by debuggers. Moreoever, when there's some gap between sections, they may be not loaded.




  2. As I said, RVA is simply "relative to some VA", no matter what VA it is (although when talking about PE, the VA usually refers to the load base address). When you read thet PE format spec you may find some "RVA" which is relative to some special address like resource starting address. The PEView list RVA from 0x1000 is because that section starts at 0x1000. Why 0x1000? Because the linker left 0x1000 bytes for PE header, so the RVA starts at 0x1000.




  3. What you've missed is the concept of "section" in PE loading stage. The PE may contain several "sections", each section maps to a new starting VA address. For example, this is dumped from win7 kernel32.dll:



    # Name VirtSize RVA PhysSize Offset
    1 .text 000C44C1 00001000 000C4600 00000800
    2 .data 00000FEC 000C6000 00000E00 000C4E00
    3 .rsrc 00000520 000C7000 00000600 000C5C00
    4 .reloc 0000B098 000C8000 0000B200 000C6200

    There is an invisible "0 header RVA=0000, SIZE=1000" which forced .text to start at RVA 1000. The sections should be continuous when being loaded into memory (i.e., VA) so their RVA is continuous. However since the memory is allocated by pages, it'll be multiple of page size (4096=0x1000 bytes). That's why #2 section starts at 1000 + C5000 = C6000 (C5000 comes from C44C1).


    In order to provide memory mapping, these sections must still be aligned by some size (file alignment size - decide by linker. In my example above it's 0x200=512 bytes), which controls the PhysSize field. Offset means "offset to physical PE file beginning".


    So the headers occupy 0x800 bytes of file (and 0x1000 when being mapped to memory), which is the offset of section #1. Then by aligning its data (c44c1 bytes), we get physsize C4600. C4600+800 = C4E00, which is exactly the offset of second section.


    OK, this is related to whole PE loading stuff so it may be a little hard to understand...



(edit) let me make a new simple summary again.


  1. The "RVA" in DLL/EXE (PE Format) files are usually relative to the "load base address in memory" (but not always - you must read the spec)

  2. The PE Format contains a "section" mapping structure to map the physical file content into memory. So the RVA is not really relative to the file offset.

  3. To calculate a RVA of some byte, you have to find its offset in the section and add the section base.


  • Upvote 2

Share this post


Link to post
Share on other sites
CybotX

Please note that my below method only works when the Raw offset and virtual offset are the same, there are cases when RVA is different from file offset. In that case the below method fails.


 


@Sipher, if you don't mean coding method follow below,  bcoz you have mention method and example but it is not clear if its a coding you are looking for, or just a generic term.


 


Note: latest version of hexworkshop can find the VA for you. You can sill follow the below methods.


 


Solution: To find the VA in olly: Just add that offset you found in hexworkshop to the base address of PE. In case you don't know where to find base address, here's how to find the base address of a PE.


 


1. In olly menu goto  view > memory.


image.png


 


2. See the base address in the memory window:


image.png


 


3. For example i want to locate the offset 0x054 in olly: Add offset found in hexworkshop to base address you found in olly.


image.png


 


4. Press Ctrl + G in olly and goto that VA


image.png


 


5. Confirm contents in dump is similar to what you see in hexworkshop to very the address is correct. (Select that instruction > right click > follow in dump > selection)


image.png


 


6. Both the contents in hexworkshop and ollydbg is same. [ADDRESS CONFIRMED]


image.png


 


Other Methods to find base address:


 


Download LordPE or PETool


 


I am using LordPE here.


 


1. In LordPE Click [PEEditor] and open that file for which you want to find base address.


 


image.png


 


Check ollydbg dump the letter r (0x72) as the first, same as hex dump of lordPE below and hexworkshop output


 


All_lord.png


 


rletter.png


 


Another nice tool: QuickRVA


 


Drag and drop the file to see file offset, VA and base address all of them together


 


image.png


 


 


I have attached QuickRVA to this reply, incase google won't help, its quite a old tool but useful. And there's also a plugin for ollydbg which will help you to directly goto offset (I don't remember the name, i don't use it either)


quickrva.zip

  • Upvote 3

Share this post


Link to post
Share on other sites
Sipher

Amazing responses from you guys. Thank you.


 


CybotX... obviously your solution is a lot easier to understand and implement. Appreciate the efforts you have taken to post this along with the pics. It is infact a complete tutorial.


 


Blue Indian.. Thankz. For a deeper understanding, I will be studying up on the links you have posted.

  • Upvote 1

Share this post


Link to post
Share on other sites
CybotX

sounds like I was right. You were not looking for coding.


PS: I should have been a detective.


 


Please note that my above method only works when the Raw offset and virtual offset are the same, there are cases when RVA is different from file offset. In that case the above method fails.  See the output Lord PE, RVA and file offset both are 0x54. And see below virtual and raw offset are same.


 


image.png


 


In case where raw offset and virtual offset are different I came up with this below formula and is equivalently apply to all conditions whether raw offset and the virtual offset are same or different. It solves for all conditions


 


VA (Linear Addr) = File Offset + Virtual Offset - Raw Offset + base address (RAM's load addr)


 


For example if we have 0x1054 as the file offset seen in hexworkshop, thats within code section (.text). Put in above formula to calculate address for ollydbg. So from the above pic of LordPE they both are 0x1000


 


image.png


 


So , Raw offset = 0x1000, Virtual offset = 0x1000, File offset in hexworkshop = 0x1054, Base address = 400,000 , VA in olly == ?? we have to find


 


Substitute these values in the above formula:


VA = 0x1054 + 0x1000 - 0x1000 + 0x400000 = 0x401054 <== goto olly here


 


Also, Some author will treat RVA as the synonyms for VA . As one you can see from the tool QuickRVA. The RVA it is showing there is not relative to VA but is absolute vaue, its VA itself. So don't get confuse. RVA is not VA. RvA is an address without a base address. QuickRVA tool shows RVA with a base address included which is the VA. Check PEtool or LordPE they look promising .


 


All_lord.png


  • Like 1
  • Upvote 2

Share this post


Link to post
Share on other sites
Sipher

Thank you CybotX... Got it.


 


Have saved all your details too and will be a handy reference for the future.


 


Appreciate.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

Guidelines