/* $ ./a.out DYNAMIC=0x601100 DEBUG=0x7f7e00e10780 r_version = 0 l_addr = 0x0, l_name = './a.out', l_ld = 0x601100 l_addr = 0x753ead400000, l_name = '/usr/lib/libc.so.12', l_ld = 0x753ead7d0780 l_addr = 0x7f7e00c00000, l_name = '/usr/libexec/ld.elf_so', l_ld = 0x7f7e00e0ff00 r_brk = 0x7f7e00c00cd0 r_state = CONSISTENT */ #include #include #include #include #include #include #include #include void * get_dynamic(void) { AuxInfo *aux = _dlauxinfo(); uintptr_t relocbase = (uintptr_t)~0U; const Elf_Phdr *phdr = NULL; Elf_Half phnum = (Elf_Half)~0; for (; aux->a_type != AT_NULL; ++aux) { switch (aux->a_type) { case AT_PHDR: phdr = (void *)aux->a_v; break; case AT_PHNUM: phnum = (Elf_Half)aux->a_v; break; } } if (phdr == NULL) errx(EXIT_FAILURE, "phdr == NULL"); if (phnum == (Elf_Half)~0) errx(EXIT_FAILURE, "phnum == (Elf_Half)~0"); const Elf_Phdr *phlimit = phdr + phnum, *dynphdr = NULL; for (; phdr < phlimit; ++phdr) { if (phdr->p_type == PT_DYNAMIC) dynphdr = phdr; if (phdr->p_type == PT_PHDR) relocbase = (uintptr_t)phdr - phdr->p_vaddr; } if (dynphdr == NULL) errx(EXIT_FAILURE, "dynphdr == NULL"); if (relocbase == (uintptr_t)~0U) errx(EXIT_FAILURE, "relocbase == (uintptr_t)~0U"); Elf_Dyn *dynp = (Elf_Dyn *)((uint8_t *)dynphdr->p_vaddr + relocbase); return dynp; } struct r_debug * get_r_debug() { Elf_Dyn *dynp = get_dynamic(); printf("DYNAMIC=%p\n", dynp); for (; dynp->d_tag != DT_NULL; dynp++) { if (dynp->d_tag == DT_DEBUG) return (void *)dynp->d_un.d_val; } errx(EXIT_FAILURE, "DT_DEBUG not found"); } int main(int argc, char **argv) { struct r_debug *r_debug; r_debug = get_r_debug(); printf("DEBUG=%p\n", r_debug); printf("r_version = %d\n", r_debug->r_version); struct link_map *map; for (map = r_debug->r_map; map; map = map->l_next) { printf("l_addr = %p, l_name = '%s', l_ld = %p\n", map->l_addr, map->l_name, map->l_ld); } printf("r_brk = %p\n", r_debug->r_brk); const char *r_state; switch (r_debug->r_state) { case RT_CONSISTENT: r_state = "CONSISTENT"; break; case RT_ADD: r_state = "ADD"; break; case RT_DELETE: r_state = "DELETE"; break; default: r_state = "???"; } printf("r_state = %s\n", r_state); return EXIT_SUCCESS; }