Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
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);
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;
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;
Copy link

tomioe commented Jan 2, 2022

Very impressive analysis and fix! What arguments are you passing to gcc to compile this? Is there a Makefile?

Copy link

jacobsebek commented Jan 2, 2022

Hi. Great and educational article. Although I am not sure if it wouldn't be easier to just create a stub for the global symbol SDL_JoystickInit.

Copy link

TibixDev commented Jan 3, 2022

Very impressive article, it was an amazing read.

Copy link

Kudos and great write-up!

Copy link

santiacq commented Jan 14, 2022

Great article! It came really handy to me as yesterday I had the same problem

@tomioe here's the commands to compile into a shared library:
g++ -g -ggdb -fPIC -rdynamic -I../static -c papers_please_fix.cpp -o papers_please_fix.o
g++ -g -ggdb -fPIC -rdynamic -shared -o papers_please_fix.o

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