Skip to content

Instantly share code, notes, and snippets.

@peadar
Last active January 3, 2018 19:34
Show Gist options
  • Save peadar/ca65a7dbac28f7e9173d8b164c0c4fc9 to your computer and use it in GitHub Desktop.
Save peadar/ca65a7dbac28f7e9173d8b164c0c4fc9 to your computer and use it in GitHub Desktop.
How to get the VDSO and see what's inside
#include <sys/auxv.h>
#include <stdlib.h>
#include <unistd.h>
#include <elf.h>
#ifdef __LP64__
typedef Elf64_auxv_t Elf_auxv_t;
typedef Elf64_Ehdr Elf_Ehdr;
typedef Elf64_Phdr Elf_Phdr;
#else
typedef Elf32_auxv_t Elf_auxv_t;
typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Phdr Elf_Phdr;
#endif
int
main(int argc, char *argv[], char **environ)
{
// First, skip the environment.
void **vpp = (void **)environ;
while (*vpp++)
;
// vpp now points to the first auxv entry.
for (Elf_auxv_t *auxvp = (Elf_auxv_t *)vpp; auxvp->a_type != AT_NULL; ++auxvp) {
if (auxvp->a_type == AT_SYSINFO_EHDR) {
// Find the end of the executable, either the end of the last segment,
// or the end of the section headers.
char *exebase = (char *)auxvp->a_un.a_val;
Elf_Ehdr *ehdr = (Elf_Ehdr *)exebase;
Elf_Phdr *phdr = (Elf_Phdr *)(exebase + ehdr->e_phoff);
size_t i;
size_t size = 0;
for (i = 0; i < ehdr->e_phnum; ++i) {
size_t hdrend = phdr[i].p_offset + phdr[i].p_filesz;
if (hdrend > size)
size = hdrend;
}
size_t section_end = ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize;
if (section_end > size)
size = section_end;
while (size) {
ssize_t chunk = write(1, exebase, size);
if (chunk == -1)
abort();
size -= chunk;
exebase += chunk;
}
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment