herm1t LIVE!ng room - __gmon_start__ [entries|archive|friends|userinfo]
herm1t

[ website | twilight corner in the herm1t's cave ]
[ userinfo | ljr userinfo ]
[ archive | journal archive ]

__gmon_start__ [Oct. 8th, 2010|04:01 pm]
Previous Entry Add to Memories Tell A Friend Next Entry
[Tags|, , , ]
[Current Mood |awake]

Занятным образом вызывается 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;
        }
LinkLeave a comment