Skip to content

Instantly share code, notes, and snippets.

@pldubouilh
Forked from Henje/papers_please_fix.cpp
Created January 2, 2022 14:23
Show Gist options
  • Save pldubouilh/f737e70ef512ccae07bfc591e73b00a9 to your computer and use it in GitHub Desktop.
Save pldubouilh/f737e70ef512ccae07bfc591e73b00a9 to your computer and use it in GitHub Desktop.
Simple hack to disable joystick scanning and remove stutters from Papers Please.
#include <string>
#include <dlfcn.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
using namespace std::literals;
template<class T>
constexpr T* page_round_down(T* ptr, size_t page_size) {
size_t page = reinterpret_cast<size_t>(ptr) & ~(page_size - 1);
return reinterpret_cast<T*>(page);
}
void patch_function(void* ptr, size_t offset) {
char* func = reinterpret_cast<char*>(ptr);
func += offset;
const long page_size = sysconf(_SC_PAGESIZE);
int result = mprotect(page_round_down(func, page_size), 1, PROT_READ | PROT_WRITE | PROT_EXEC);
if(result) {
fprintf(stderr, "result %d %d\n", result, errno);
return;
}
func[0] = 0xc3;
mprotect(page_round_down(func, page_size), 1, PROT_READ | PROT_EXEC);
}
using dlopen_t = void* (*)(const char*, int);
extern "C"
void* dlopen(const char* filename, int flags) {
static dlopen_t real_dlopen = nullptr;
if(!real_dlopen)
real_dlopen = reinterpret_cast<dlopen_t>(dlsym(RTLD_NEXT, "dlopen"));
void* handle = real_dlopen(filename, flags);
if(!filename || filename != "././lime.ndll"s) {
return handle;
}
char* symbol = getenv("PP_SYMBOL");
if(!symbol) {
fprintf(stderr, "PP_SYMBOL not set\n");
return handle;
}
char* offset = getenv("PP_OFFSET");
if(!offset) {
fprintf(stderr, "PP_OFFSET not set\n");
return handle;
}
void* func = dlsym(handle, symbol);
if(!func) {
fprintf(stderr, "could not find symbol: %s\n", symbol);
return handle;
}
patch_function(func, atoi(offset));
return handle;
}⏎
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment