Best Practices for Packaging Embedded Python Libraries for to Prevent Unauthorized Modification

I am working for embedding Python in C++ applications.
In Android testbeds, embedded Python resources are often extracted to the app’s private data directory. However, these files typically remain unencrypted, meaning that users with root access can still modify them. On desktop platforms, these files are directly exposed in the file system and are even easier to tamper with. This is especially problematic in gaming scenarios, where although anti-cheat measures can be implemented, it is still highly desirable to significantly increase the difficulty of unauthorized modification.

Question
Are there any recommended workflows or concepts to protect Python code (I am using C API) and resources in these environments, making them less vulnerable to modification? What additional methods or strategies can be used to strengthen protection, especially when the file system itself cannot guarantee security?

I can’t say DRM is close to my heart, but for apps that aren’t forced upon the user, it can be a reasonable requirement.

Can the operating system’s dynamic linker (e.g. ld) load a .so or .dll from a virtual disk backed by RAM, the only place that the library is decrypted to?

A root user can simply dump the RAM, but beyond that (according to my limited knowledge) more controversial measures are required, e.g. kernel level anti-cheat.

At the end of the day, preventing cheating in single player games is a non-problem (people who care about speed running may disagree, but I say fill your boots, it’s your software), and preventing cheating in multiplayer games can be done on a server.

1 Like

There’s pyarmor for obfuscating pure python code (along with the usual warning about obfuscation never being more than a smoke and mirrors exercise). I also want to emphasise that those who over focus on what’s on the filesystem tend to forget how easy it is to get a REPL or debugger into your code at runtime.

Really, the best practice for avoiding unauthorized access to any kind of code is to not distribute it in the first place. Either do the bits that require trust server side or make the game deterministic enough that the app can for example upload the randomisation seed and a log of the player’s actions alongside its self-proclaimed outcome (say a high score) and the server can do a simulation run of the game to verify that it gets the same outcome.

1 Like

If you really wanted to, you might be able to compare the hash of the python files with a hash you hard-code in your compiled C code?

As the others note, all these hurdles can be overcome. But it’s an extra hurdle.

You cannot fight cheating by encrypting the code that is placed on people’s computers. Don’t get into a massive arms race of trying to control what people run on their own computers, as you will fail, and fail badly. There are a number of games today that have kernel-level anti-cheat, which is basically a massive security vulnerability waiting to be exploited, and that STILL can’t prevent cheaters from getting around it.

If you want to control the code and not let people change it, don’t put the code on people’s computers. The ONLY way to maintain full control is to keep the code on your computer and provide access to it - for example, running a web service.

Exactly. There will never be any way that you can truly guarantee security like that.

1 Like

And there are kernel level cheats, so that’s just pushing the problem another level further.

1 Like