| __gmon_start__ |
[Oct. 8th, 2010|04:01 pm] |
Занятным образом вызывается gmon, в связи с чем небольшая вариация на тему PLT-redirection. И так, как стартует ELF? Точка входа указывает на кусок из CRT, который зовет __libc_start_main, далее _init, из _init в call_gmon_start, который зовет __gmon_start__@plt, если __gmon_start__@GOT не равен нулю (sysdeps/generic/initfini.c):
58 static void
59 call_gmon_start(void)
60 {
61 extern void __gmon_start__ (void) __attribute__ ((weak)); /*weak_extern (__gmon_start__);*/
62 void (*gmon_start) (void) = __gmon_start__;
63 if (gmon_start)
64 gmon_start ();
65 }
В связи с чем:
...datafix = data->p_vaddr - data->p_offset
...
/* find __gmon_start__@gotplt */
uint32_t *patch_addr = NULL;
for (i = 0; i < relsz / sizeof(Elf32_Rel); i++)
if (! strcmp("__gmon_start__",
dynsym[ELF32_R_SYM(jmprel[i].r_info)].st_name + dynstr) &&
ELF32_R_TYPE(jmprel[i].r_info) == R_386_JMP_SLOT) {
patch_addr = (uint32_t*)(m + jmprel[i].r_offset - datafix);
break;
}
if (patch_addr == NULL)
goto error;
pltgot--;
if (0 == *pltgot) {
memcpy(m + note->p_offset, snippet, sizeof(snippet));
(*pltgot)++;
*patch_addr = note->p_vaddr;
}
|
|
|