miércoles, octubre 04, 2006

Elf entry calculation in c

e_entry points to the virtual address where will be _start at runtime.
In order to calculate the relative virtual address of the entry point from the beginning of the file image, we should look for the code segment and use this formula:

(elf).e_entry - (code).p_vaddr + (code).p_offset

p_offset is the distance from the begining of the file to the code segment.
p_addr is the virtual address of the code segment.

The diference e_entry - p_vaddr can be drawed like this:


(at runtime)
+--- code segment ---- <- p_vaddr
|
|
|
|<---- e_entry
|
We already know the distance inside the code segment where is the entry point (usually at the begining of .text section) If now we sum the offset where code segment starts from the beginning, we will have the offset from the beginning of the file where is exactly the entry point.

void getentry (struct map *elf) {
 int ph;
 int s; //text section Index text
 elf->text.s = elf->s;

 for (s=0; se->e_shnum; s++) {

  if (strcmp(".text",(char *)((unsigned long)elf->e + (unsigned    long)elf->strtab->sh_offset + (unsigned long)elf->text.s->sh_name))    == 0)
   break;

  elf->text.s++;
 }

 if (elf->e->e_shnum == s) {
  printf(".text section can not be found, bad elf\n");
  final();
 }

//elf->p Is the first record, elf->text.p This ptr will be travelling throw the memory since arrive to the text segment
elf->text.p = elf->p;

 for (ph=elf->e->e_phnum; ph>0; ph--) {

  if (elf->text.p->p_type == PT_LOAD && elf->text.p->p_flags == 5) {
   elf->text.size = elf->text.p->p_memsz;
   elf->text.entry.rel = (unsigned long)((unsigned long)elf->e->e_entry -
(unsigned long)elf->text.p->p_vaddr +
(unsigned long)elf->text.p->p_offset);
   elf->text.entry.abs = elf->text.entry.rel + (unsigned long)elf->e;


/*
We have 4 entry points
* elf->e->e_entry (VA of the entry at runtime)
* elf->text.entry.rel (RVA of the entry from the beginning of .text)
* elf->text.entry.abs (VA of the entry from the beginning of the file)
*/

   return;
  }
  elf->text.p++;
 }

 printf("There is no entry point\n");
 final();
}

// EOF

No hay comentarios: