Skip to content

Instantly share code, notes, and snippets.

@croepha
Created December 15, 2016 18:09
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save croepha/e7f5142006c8510df7b6f7763557b7d7 to your computer and use it in GitHub Desktop.
Save croepha/e7f5142006c8510df7b6f7763557b7d7 to your computer and use it in GitHub Desktop.
Example of calling into the kernel vdso directly
#include <stdio.h>
#include <sys/auxv.h> // For getauxval and AT_SYSINFO_EHDR
#include <string.h>
#include <elf.h>
typedef unsigned char u8;
void* vdso_sym(char* name) {
// in order to semantically inline getauxval one would have to bypass glibc, as the auxval is passed
// by the kernel to the bin's entrypoint used by the kernel
auto vdso_addr = (u8*)getauxval(AT_SYSINFO_EHDR);
auto elf_header = (Elf64_Ehdr*)vdso_addr;
auto section_header = (Elf64_Shdr*)(vdso_addr + elf_header->e_shoff);
char* dynstr = 0;
for (int i=0; i<elf_header->e_shnum; i++) {
auto& s = section_header[i];
auto& ss_ = section_header[elf_header->e_shstrndx];
auto name = (char*)(vdso_addr + ss_.sh_offset + s.sh_name);
if (strcmp(name, ".dynstr") == 0) {
dynstr = (char*)(vdso_addr + s.sh_offset);
break;
}
}
void *ret = NULL;
for (int i=0; i<elf_header->e_shnum; i++) {
auto& s = section_header[i];
auto& ss_ = section_header[elf_header->e_shstrndx];
auto name = (char*)(vdso_addr + ss_.sh_offset + s.sh_name);
if (strcmp(name, ".dynsym") == 0) {
for (int si=0; si<(s.sh_size/s.sh_entsize); si++) {
auto &sym = ((Elf64_Sym*)(vdso_addr + s.sh_offset))[si];
auto name = dynstr + sym.st_name;
if (strcmp(name, "clock_gettime") == 0) {
ret = (vdso_addr + sym.st_value);
break;
}
}
if (ret) break;
}
}
return ret;
}
#include <time.h> // for clockid_t, timespec, and CLOCK_REALTIME
typedef int (clock_gettime_t)(clockid_t clk_id, struct timespec *tp);
int main(int argc, char *argv[])
{
auto my_clock_gettime = (clock_gettime_t*)vdso_sym("clock_gettime");
timespec tp;
my_clock_gettime(CLOCK_REALTIME, &tp);
printf("tp: %ld", tp.tv_sec);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment