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
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]
add edi, [edi+8] ; nextSection=currentSection+currentSection Size