Last active
March 18, 2019 20:57
-
-
Save colesbury/b10069870419ca1fa9c3a2a8668edbe3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compile with: | |
// g++ -c -fpic -o hack.o hack.cpp && g++ -shared -o libhack.so hack.o | |
// Then load with the Python | |
// import ctypes; ctypes.CDLL('libhack.so') | |
#include <stdio.h> | |
#include <dlfcn.h> | |
#include <stddef.h> | |
#include <stdint.h> | |
#include <sys/mman.h> | |
#include <sys/user.h> | |
static int cudaGetDeviceFake(int* device) { | |
*device = 0; | |
return 0; | |
} | |
static int cudaSetDeviceFake(int device) { | |
return 0; | |
} | |
// Taken from http://jmkeyes.github.io/post/hot-patching-unconditional-jumps-x86-x86-64/ | |
static void write_redirection_medium(unsigned char *source, unsigned char *destination) { | |
ptrdiff_t delta = (destination - (source + 5)); | |
if (delta < -2147483648 || delta > 2147483647) { | |
perror("unable to redirect function: jmp to large"); | |
return; | |
} | |
/* 0xe9 is the unconditional jump opcode. */ | |
source[0] = 0xe9; | |
/* Write each of the octets of the delta. */ | |
source[1] = (delta >> 0) & 0xff; | |
source[2] = (delta >> 8) & 0xff; | |
source[3] = (delta >> 16) & 0xff; | |
source[4] = (delta >> 24) & 0xff; | |
return; | |
} | |
static void alter_page_attributes(const unsigned char *address, unsigned long length, int mask) { | |
/* mprotect() needs an address that is page-aligned. */ | |
unsigned char *addr = (unsigned char *) ((unsigned long) address & PAGE_MASK); | |
length += (address - addr); | |
if (mprotect(addr, length, mask) == -1) { | |
perror("mprotect"); | |
} | |
return; | |
} | |
static void redirect(const char* sym, void* dst) { | |
unsigned char* src = (unsigned char*)dlsym(NULL, sym); | |
if (!src) { | |
perror("src symbol not found"); | |
return; | |
} | |
alter_page_attributes(src, 5, PROT_READ|PROT_WRITE); | |
write_redirection_medium(src, (unsigned char*)dst); | |
alter_page_attributes(src, 5, PROT_READ|PROT_EXEC); | |
printf("patched %s\n", sym); | |
} | |
__attribute__((constructor)) static void init() { | |
redirect("cudaGetDevice", (void*)&cudaGetDeviceFake); | |
redirect("cudaSetDevice", (void*)&cudaSetDeviceFake); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
awesome hack, thanks.