Skip to content

Instantly share code, notes, and snippets.

@vodik
Last active December 18, 2015 07:29
Show Gist options
  • Save vodik/5746670 to your computer and use it in GitHub Desktop.
Save vodik/5746670 to your computer and use it in GitHub Desktop.
Dump needed dependancies
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <err.h>
#include <elf.h>
#include <sys/stat.h>
#include <sys/mman.h>
static const char magic[] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
static uintptr_t find_relocbase(const char *memblock, const Elf64_Ehdr *elf)
{
const Elf64_Phdr *phdr = (Elf64_Phdr *)&memblock[elf->e_phoff];
while (phdr->p_type != PT_PHDR)
++phdr;
return elf->e_phoff - phdr->p_vaddr;
}
static const char *find_strtable(const char *memblock, uintptr_t relocbase, const Elf64_Dyn *dyn)
{
const Elf64_Dyn *i;
for (i = dyn; i->d_tag != DT_NULL; ++i) {
if (i->d_tag == DT_STRTAB)
return &memblock[i->d_un.d_ptr + relocbase];
}
}
static void dump_elf(const char *bin)
{
struct stat st;
char *memblock = MAP_FAILED;
uintptr_t relocbase = 0;
const Elf64_Ehdr *elf;
int fd = open(bin, O_RDONLY);
if (fd < 0) {
warn("failed to open %s", bin);
goto cleanup;
}
fstat(fd, &st);
memblock = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0);
if (memblock == MAP_FAILED) {
warn("failed to mmap %s", bin);
goto cleanup;
}
elf = (Elf64_Ehdr *)&memblock[0];
if (memcmp(elf->e_ident, magic, sizeof(magic)) != 0) {
warnx("invalid magic for %s", bin);
goto cleanup;
}
if (elf->e_type != ET_EXEC || elf->e_machine != EM_X86_64) {
goto cleanup;
}
printf(":: %s\n", bin);
if (elf->e_phoff) {
relocbase = find_relocbase(memblock, elf);
}
if (elf->e_shoff) {
const Elf64_Shdr *shdr = (Elf64_Shdr *)&memblock[elf->e_shoff];
int i;
for (i = 0; i < elf->e_shnum; ++i) {
if (shdr[i].sh_type == SHT_DYNAMIC) {
const Elf64_Dyn *j, *dyn = (Elf64_Dyn *)&memblock[shdr[i].sh_offset];
const char *strtable = find_strtable(memblock, relocbase, dyn);
for (j = dyn; j->d_tag != DT_NULL; ++j) {
if (j->d_tag == DT_NEEDED) {
const char *name = strtable + j->d_un.d_val;
printf(" NEEDED %s\n", name);
}
}
}
}
}
cleanup:
if (memblock != MAP_FAILED)
munmap(memblock, st.st_size);
if (fd >= 0)
close(fd);
}
int main(int argc, char *argv[])
{
int i;
if (argc < 2)
errx(1, "not enough arguments");
for (i = 1; i < argc; ++i) {
dump_elf(argv[i]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment