miércoles, agosto 22, 2007

PE entry calculation

The way to calculate win32 PE entry point offset is similar than linux elf's.

We have to keep in mind 3 basic concepts:

RVA -> adress relative to the beginning of de loaded PE at runtime.
(can be relative to something, is like an offset, but often is referred to a running process)
VA -> Is an absolute memory address in the loaded binary at runtime.
offset -> Is a relative address, like RVA but is relative from the beginning of the file.

Wen a binary is executed, the loader maps some parts and do some relocations, the memory map of the binary at runtime is diferent than the file image. If we map the file, we speak of offsets from the beginnig of the map/file.


Entry RVA: 12475h
PE Imagebase: 100000h

Ok, when the PE is loaded, the entry is at 112475h, easy :)
but, we have maped the file image, and we wish to know the entry's offset.

Sections has 3 important values: RVA of the section, Size of the section and offset.

We know de entry's RVA, we can check with the sections RVA in order to see where is the entry.

When we get the section RVA, becouse of we hav the sections offset, we can get the Delta between his RVA and offset, if we apply this delta to the RVA we will get the entry's offset, then we have to add the beginning of the map and will have our entry.

;We have maped the file, and eax is pointing to the beginning of the file.

   mov edx, [eax+3Ch]       ; edx -> RVA of File Header
   add edx, eax          ; edx -> VA of File Header
   mov esi, [edx+28h]       ; esi -> RVA of entry point

   lea edi, [edx+74h]       ; edi -> ptr to the beginning of section table
   mov ecx, [edx+2]       ; ecx -> number of sections
   mov ebx, [edi+0Ch]       ; ebx -> RVA of section
   mov edx, ebx
   add edx, [edi+8]       ; edx -> rva of the end of the section

   cmp esi, ebx    ; entryRVA < sectionRVA => wrong
   jl wrongEntry

   cmp esi, edx  ; entryRVA > sectionRVA + sectionSize => nextSection
   jg nextSection ; entry is out of bounds of this section, check next section.

   sub esi, ebx       ; entry calculus
   add esi, [edi+10h]
   jmp gotEntry

   add edi, [edi+8]   ; nextSection=currentSection+currentSection Size
   loop seekEntrySection