#define _GNU_SOURCE #include #include int callback (struct dl_phdr_info *info, size_t size, void *data) { printf ("\nname: %s\n", info->dlpi_name); ElfW(Phdr) *phdr = (ElfW(Phdr) *) info->dlpi_phdr; for (ElfW(Half) i = 0; i < info->dlpi_phnum; i++) { if (phdr->p_type == PT_NOTE) { ElfW(Addr) addr = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr; ElfW(Addr) nend = addr + info->dlpi_phdr[i].p_memsz; //printf ("found NOTE segment at: %p to %p\n", addr, nend); while (addr < nend) { ElfW(Nhdr) *nhdr = (ElfW(Nhdr) *) addr; // According to the ELF spec, namesz and descsz do not include padding // but that's how they're laid out in memory; add the padding here. ElfW(Addr) nameoff = (((nhdr->n_namesz-1)>>2)+1)<<2; ElfW(Addr) descoff = (((nhdr->n_descsz-1)>>2)+1)<<2; if (nhdr->n_type == NT_GNU_BUILD_ID) { const uint8_t *buf = (const uint8_t *) ((ElfW(Addr))(nhdr + 1) + nameoff); printf("Build ID"); for (int j = 0; j < nhdr->n_descsz; j++) printf(":%02X", buf[j]); printf("\n"); } //printf("skipping section type %02X\n", nhdr->n_type); addr = (ElfW(Addr))(nhdr + 1) + nameoff + descoff; } } phdr += 1; } return 0; } int main() { dl_iterate_phdr(callback, NULL); }