Skip to content

Instantly share code, notes, and snippets.

@colesbury
Last active March 18, 2019 20:57
Show Gist options
  • Save colesbury/b10069870419ca1fa9c3a2a8668edbe3 to your computer and use it in GitHub Desktop.
Save colesbury/b10069870419ca1fa9c3a2a8668edbe3 to your computer and use it in GitHub Desktop.
// 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);
}
@omry
Copy link

omry commented Mar 18, 2019

awesome hack, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment