Skip to content

Instantly share code, notes, and snippets.

@stong
Created November 13, 2024 11:30
// gcc -shared -fPIC -I/usr/local/cuda-12.0/targets/x86_64-linux/include/ hook.c -o hook.so -ldl && LD_PRELOAD=./hook.so python3.11 obfuscated_file.py
// Thanks Claude!
#include <nvml.h>
#define _GNU_SOURCE
#define PAGE_SIZE 4096
#include <stdio.h>
#include <dlfcn.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
typedef nvmlReturn_t (*nvmlDeviceGetCount_v2_t)(unsigned int*);
typedef nvmlReturn_t (*nvmlInitWithFlags_t)(unsigned int);
typedef nvmlReturn_t (*nvmlDeviceGetName_t)(nvmlDevice_t device, char* name, unsigned int length);
typedef nvmlReturn_t (*nvmlDeviceGetMemoryInfo_t)(nvmlDevice_t device, nvmlMemory_t* memory);
// Storage for original function bytes
static unsigned char orig_nvmlDeviceGetCount_v2_bytes[14];
static unsigned char orig_nvmlInitWithFlags_bytes[14];
static unsigned char orig_nvmlDeviceGetName_bytes[14];
static unsigned char orig_nvmlDeviceGetMemoryInfo_bytes[14];
// Global handle to the NVIDIA library
static void* nvml_handle = NULL;
// Our hook functions
nvmlReturn_t hook_nvmlDeviceGetCount_v2(unsigned int* deviceCount) {
// Restore original bytes to call the real function
void* func_addr = dlsym(nvml_handle, "nvmlDeviceGetCount_v2");
mprotect((void*)((uintptr_t)func_addr & ~(PAGE_SIZE-1)), PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
memcpy(func_addr, orig_nvmlDeviceGetCount_v2_bytes, sizeof(orig_nvmlDeviceGetCount_v2_bytes));
// Call original
nvmlReturn_t result = ((nvmlDeviceGetCount_v2_t)func_addr)(deviceCount);
// Log the call
fprintf(stderr, "nvmlDeviceGetCount_v2(0x%p) = %d, count=%u\n",
deviceCount, result, deviceCount ? *deviceCount : 0);
// Restore our hook
unsigned char jump[] = {
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp qword ptr [rip]
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // absolute address
};
*(uint64_t*)(jump + 6) = (uint64_t)hook_nvmlDeviceGetCount_v2;
memcpy(func_addr, jump, sizeof(jump));
return result;
}
nvmlReturn_t hook_nvmlInitWithFlags(unsigned int flags) {
// Restore original bytes to call the real function
void* func_addr = dlsym(nvml_handle, "nvmlInitWithFlags");
mprotect((void*)((uintptr_t)func_addr & ~(PAGE_SIZE-1)), PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
memcpy(func_addr, orig_nvmlInitWithFlags_bytes, sizeof(orig_nvmlInitWithFlags_bytes));
// Call original
nvmlReturn_t result = ((nvmlInitWithFlags_t)func_addr)(flags);
// Log the call
fprintf(stderr, "nvmlInitWithFlags(0x%x) = %d\n", flags, result);
// Restore our hook
unsigned char jump[] = {
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp qword ptr [rip]
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // absolute address
};
*(uint64_t*)(jump + 6) = (uint64_t)hook_nvmlInitWithFlags;
memcpy(func_addr, jump, sizeof(jump));
return result;
}
nvmlReturn_t hook_nvmlDeviceGetName(nvmlDevice_t device, char* name, unsigned int length) {
// Restore original bytes to call the real function
void* func_addr = dlsym(nvml_handle, "nvmlDeviceGetName");
mprotect((void*)((uintptr_t)func_addr & ~(PAGE_SIZE-1)), PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
memcpy(func_addr, orig_nvmlDeviceGetName_bytes, sizeof(orig_nvmlDeviceGetName_bytes));
// Call original
nvmlReturn_t result = ((nvmlDeviceGetName_t)func_addr)(device, name, length);
// Log the call
fprintf(stderr, "nvmlDeviceGetName(device=%p, name_buf=%p, len=%u) = %d",
device, name, length, result);
if (result == NVML_SUCCESS && name) {
fprintf(stderr, ", name='%s'", name);
}
fprintf(stderr, "\n");
char* newName = "NVIDIA DeezNuts RTX 6969";
fprintf(stderr, "Setting new name: '%s'\n", newName);
strncpy(name, newName, length);
// Restore our hook
unsigned char jump[] = {
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp qword ptr [rip]
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // absolute address
};
*(uint64_t*)(jump + 6) = (uint64_t)hook_nvmlDeviceGetName;
memcpy(func_addr, jump, sizeof(jump));
return result;
}
nvmlReturn_t hook_nvmlDeviceGetMemoryInfo(nvmlDevice_t device, nvmlMemory_t* memory) {
// Restore original bytes to call the real function
void* func_addr = dlsym(nvml_handle, "nvmlDeviceGetMemoryInfo");
mprotect((void*)((uintptr_t)func_addr & ~(PAGE_SIZE-1)), PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
memcpy(func_addr, orig_nvmlDeviceGetMemoryInfo_bytes, sizeof(orig_nvmlDeviceGetMemoryInfo_bytes));
// Call original
nvmlReturn_t result = ((nvmlDeviceGetMemoryInfo_t)func_addr)(device, memory);
// Log the call
fprintf(stderr, "nvmlDeviceGetMemoryInfo(device=%p, memory=%p) = %d",
device, memory, result);
if (result == NVML_SUCCESS && memory) {
fprintf(stderr, ", total=%llu bytes, free=%llu bytes, used=%llu bytes",
memory->total, memory->free, memory->used);
}
fprintf(stderr, "\n");
uint64_t fakeMemory = 69420ULL*1024ULL*1024ULL;
fprintf(stderr, "Actually I have %llu megabytes of memory lol\n", fakeMemory>>20);
memory->free = fakeMemory - memory->used;
memory->total = fakeMemory;
// Restore our hook
unsigned char jump[] = {
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp qword ptr [rip]
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // absolute address
};
*(uint64_t*)(jump + 6) = (uint64_t)hook_nvmlDeviceGetMemoryInfo;
memcpy(func_addr, jump, sizeof(jump));
return result;
}
// Function to install a hook
static void install_hook(const char* symbol_name, void* hook_func, unsigned char* orig_bytes) {
// Get address of target function
void* func_addr = dlsym(nvml_handle, symbol_name);
if (!func_addr) {
fprintf(stderr, "Failed to find %s: %s\n", symbol_name, dlerror());
return;
}
fprintf(stderr, "Found %s at %p\n", symbol_name, func_addr);
// Save original bytes
memcpy(orig_bytes, func_addr, 14);
// Make page writable
mprotect((void*)((uintptr_t)func_addr & ~(PAGE_SIZE-1)), PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
// Write jump instruction
unsigned char jump[] = {
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp qword ptr [rip]
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // absolute address
};
*(uint64_t*)(jump + 6) = (uint64_t)hook_func;
memcpy(func_addr, jump, sizeof(jump));
}
__attribute__((constructor))
static void init(void) {
// Load NVIDIA library first
nvml_handle = dlopen("libnvidia-ml.so.1", RTLD_LAZY | RTLD_GLOBAL);
if (!nvml_handle) {
fprintf(stderr, "Failed to load libnvidia-ml.so.1: %s\n", dlerror());
return;
}
fprintf(stderr, "Successfully loaded libnvidia-ml.so.1\n");
// Install hooks
install_hook("nvmlDeviceGetCount_v2", hook_nvmlDeviceGetCount_v2, orig_nvmlDeviceGetCount_v2_bytes);
install_hook("nvmlInitWithFlags", hook_nvmlInitWithFlags, orig_nvmlInitWithFlags_bytes);
install_hook("nvmlDeviceGetName", hook_nvmlDeviceGetName, orig_nvmlDeviceGetName_bytes);
install_hook("nvmlDeviceGetMemoryInfo", hook_nvmlDeviceGetMemoryInfo, orig_nvmlDeviceGetMemoryInfo_bytes);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment