Skip to content

Instantly share code, notes, and snippets.

@colesbury
Last active March 18, 2019 20:57
Show Gist options
  • Select an option

  • Save colesbury/b10069870419ca1fa9c3a2a8668edbe3 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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