#include #include #include #include #include #include #include #include #include int main(int argc, char **argv) { Elf *e; Elf_Scn *scn; Elf_Data *data; GElf_Shdr shdr; char *name; int i; int fd; size_t shstrndx; struct stat sb; char x; uint32_t nbuckets; uint32_t symndx; uint32_t maskwords; uint32_t shift2; uint32_t *header, *bm32; uint64_t *bm64; uint32_t *buckets; uint32_t *chains; unsigned char *raw, *rawlimit; if (argc != 2) { fprintf(stderr, "usage: gnuhash_dump file\n"); exit(1); } if (elf_version(EV_CURRENT) == EV_NONE) errx(EX_SOFTWARE, "ELF library initialization failed: %s", elf_errmsg(-1)); if ((fd = open(argv[1], O_RDONLY)) < 0 || fstat(fd, &sb) < 0) err(EX_NOINPUT, "%s", argv[1]); if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) errx(EX_SOFTWARE, "elf_begin() failed: %s", elf_errmsg(-1)); if (elf_kind(e) != ELF_K_ELF) errx(EX_DATAERR, "not an elf file"); if (elf_getshstrndx(e, &shstrndx) == 0) errx(EX_SOFTWARE, "elf_getshstrndx failed: %s", elf_errmsg(-1)); scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) != &shdr) errx(EX_SOFTWARE, "elf_getshdr failed: %s", elf_errmsg(-1)); if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) errx(EX_SOFTWARE, "elf_strptr failed: %s", elf_errmsg(-1)); if (strcmp(name, ".gnu.hash") != 0) continue; printf("section: %s\n\n", name); data = NULL; while ((data = elf_getdata(scn, data)) != NULL) { printf("data->d_align = %u\n", data->d_align); printf("data->d_size = %u\n", data->d_size); printf("data->d_type = %u\n", data->d_type); printf("\n"); header = data->d_buf; nbuckets = header[0]; symndx = header[1]; maskwords = header[2]; shift2 = header[3]; printf("nbuckets=%u\n", nbuckets); printf("symndx=%u\n", symndx); printf("maskwords=%u\n", maskwords); printf("shift2=%u\n", shift2); if (gelf_getclass(e) == ELFCLASS64) { bm64 = (uint64_t *) (data->d_buf + 4 * sizeof(uint32_t)); for(i = 0; i < maskwords; i++) { printf("bm64[%d]=%u\n", i, bm64[i]); } buckets = (uint32_t *) &bm64[i]; } else { bm32 = (uint32_t *) (data->d_buf + 4 * sizeof(uint32_t)); for(i = 0; i < maskwords; i++) { printf("bm32[%d]=%u\n", i, bm32[i]); } buckets = &bm32[i]; } for (i = 0; i < nbuckets; i++) { printf("buckets[%d]=%u\n", i, buckets[i]); } chains = &buckets[i]; i = 0; while ((char *)chains < ((char *)data->d_buf + data->d_size)) printf("chains[%d]=%u\n", i++, *chains++); } while ((data = elf_rawdata(scn, data)) != NULL) { printf("\n"); printf("dump of raw data:\n"); raw = data->d_buf; rawlimit = raw + data->d_size; i = 0; while (raw < rawlimit) { printf("0x%02X ", *raw++); if (++i % 16 == 0) printf("\n"); } } } return (0); }