PE wrong entry point

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
LPeter
Member
Member
Posts: 30
Joined: Wed Jan 28, 2015 7:41 am

PE wrong entry point

Post by LPeter »

Hi!
I've made the PE header structures, so I decided to just test-run it and not make it's own address space or anything. So I've compiled the following code:

Code: Select all

int main(void){
   char *msg = "Hello process!\n";
   __asm__ __volatile__(
      ".intel_syntax noprefix\n"
      "mov ebx, %0;\n"
      "xor eax, eax;\n"
      "int 0x66;\n"
      ".att_syntax\n"
      :
      : "r"(msg)
           : "eax", "ebx"
   );
   
   for(;;);
   return 0;
}
As far as I know, the entry point of the PE is imageBase + addressOfEntryPoint, so I just made a function pointer and ran it:

Code: Select all

void (*func) () = (base + entry_point);
func();
However this doesn't work. The base is at 4 MiB, which is ok. The entry point is at 0x1280, at least this is what I get. If I check the file at the optional header at the entry point, there are just zeros (based of assembly dump). The objdump finds the code allright, but somehow I can't. At base + entry_point (after I've read the file and copied it to base) there are just a bunch of zeros. What should be at base + entry_point is actually at base + 0x680. What am I doing wrong?
Here's the compiled process if it helps:
http://www.mediafire.com/download/xd6y7 ... stproc.exe
pikasoo
Member
Member
Posts: 30
Joined: Sun Sep 02, 2012 11:04 am
Contact:

Re: PE wrong entry point

Post by pikasoo »

Mabe this will help you:

00000178 .text Section Name
00000180 00000C40 Virtual Size
00000184 00001000 RVA/Offset
00000188 00000E00 Size of Raw Data
0000018C 00000400 Pointer to Raw Data
00000190 00000000 Pointer to Relocs
00000194 00000000 Pointer to Line Numbers
00000198 0000 Number of Relocs
0000019A 0000 Number of Line Numbers
0000019C 60500060 Section Flags (Readable, Executable, Align 64 bytes, Align 32 bytes, Align 16 bytes, Align 8 bytes, Align 4 bytes, Align 1 byte, Initialized data, Code)

this is one of the 12 section header that are set in your exe file, eatch of them contain information about the data to be moved in memory.
00000180 00000C40 Virtual Size, is the size in memory that the section will use
00000184 00001000 RVA/Offset, is the offset from the base, where to copy the data

then you have the 2 other information relative to the data in the exe, this is mabe where your bug is:

00000188 00000E00 Size of Raw Data
0000018C 00000400 Pointer to Raw Data

the actual size of the data in the file and it's offset. this tell you to copy the data from 0x400 to the memory offset (base+0x1000)

you have to process eatch section header.


Also i noticed that you exe has a few import from kernel32.dll and msvcrt.dll, you might not be able to run this file on your os if the code make a call to them beafor your "main" function
LPeter
Member
Member
Posts: 30
Joined: Wed Jan 28, 2015 7:41 am

Re: PE wrong entry point

Post by LPeter »

Right, then the loading itself is wrong too. Could you tell me the detailed method of loading a PE file correctly? The wiki writes it down but there's no explanation (and I feel that it is less than I need).
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: PE wrong entry point

Post by neon »

Hello,

The Entry Point field is a Relative Virtual Address (RVA) which implies that it is relative to the Image Base field. This is where the Image Base + Entry Point comes from - because the Entry Point field is an RVA.

In the series, we opted for a simpler approach which we could get away with due to the section alignment being the same as file alignment (via /ALIGN:512). However, the more complete way of loading and mapping each section via the section table which is located right between the headers and raw data. It is an array of IMAGE_SECTION_HEADERs which contain the Virtual Address (relative to image base), size, and section attributes. You can map the section at that address in the virtual address space of the process (unless you need to relocate it.)

Finally, as noted above, please make sure not to link standard Windows libraries to your program. In addition, the subsystem should not be Console; it should be either Driver or Native. What was described in the PE article is correct (except the address of entry point does not need to be obtained from symbol table) - its the minimum needed to get a PE image ready for execution. There is more that you can do (such as relocations and dynamic linking) but it is advisable to do those later.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Post Reply