How to encrypt / obfuscate your Ren'Py archive RPA files to prevent common programs from opening them

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Post Reply
Message
Author
User avatar
uyjulian
Regular
Posts: 115
Joined: Sun Mar 08, 2015 1:40 pm
Github: uyjulian
Contact:

How to encrypt / obfuscate your Ren'Py archive RPA files to prevent common programs from opening them

#1 Post by uyjulian » Sun Aug 02, 2020 5:12 pm

Here are some simple steps to prevent the current version of common archive unpackers like GARbro, unrpa, rpatool, arc_unpacker, etc… from opening your game's archives.
1. In the Ren'Py SDK directory, open the following files using a text editor such as "Atom", "Editra", or "jEdit": "launcher/game/archiver.rpy" and "renpy/loader.py"
2. Find the following string (using "Find" (Ctrl-F)): "RPA-3.0 " (It's okay if there is anything after it)
3. Replace the string with any 8-byte string.
You can use printable ASCII characters (this is good). Examples:
"ABCDEFGH"
"12345678"
"ASDFGHJK"
"!@#$%^&*"
You can also use non-printable characters (this is good). Examples:
"\x01\x02\x03\x04\x05\x06\x07\x08"
"\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11"
Using the following headers will cause existing common archive unpackers to attempt to parse the file, but fail (this is good):
"ZiX-12A "
"ZiX-12B "
"RPA-2.0 "
"ALT-1.0 "
"\x58\x50\x33\x0d\x0a\x20\x0a\x1a"
Use only 7-bit ASCII characters. The following is not acceptable (this is bad):
"åéêîíøπ¬"
"ホゲホゲホゲホゲ"
The following headers will not prevent unpacking with the current version of common archive unpackers, so avoid these (this is bad):
"RPA-3.0 "
"RPA-3.2 "
"RPA-4.0 "
Before:

Code: Select all

padding = b"RPA-3.0 XXXXXXXXXXXXXXXX XXXXXXXX\n"
self.f.write(b"RPA-3.0 %016x %08x\n" % (indexoff, self.key))
if l.startswith(b"RPA-3.0 "):
After:

Code: Select all

padding = b"12345678XXXXXXXXXXXXXXXX XXXXXXXX\n"
self.f.write(b"12345678%016x %08x\n" % (indexoff, self.key))
if l.startswith(b"12345678"):
where "12345678" is your own string.
After you are done making your changes, save both files, then close them.
4. Create distributions with the Ren'Py Launcher.
You can now distribute your game with the Ren'Py Launcher. The archives created in the distribution will (if you didn't use one of the "bad" strings above) not be openable in the current version of common archive unpackers like GARbro, unrpa, rpatool, arc_unpacker, etc…

This should be good enough to stop CG distributors or store reviewers from unpacking your game on the first day of release (or even before that).

demwilson
Newbie
Posts: 4
Joined: Sat Sep 28, 2019 11:09 pm
Github: demwilson
Contact:

Re: How to encrypt / obfuscate your Ren'Py archive RPA files to prevent common programs from opening them

#2 Post by demwilson » Sun Aug 02, 2020 5:56 pm

I didn't know this was a problem, but it makes sense.
Thanks for sharing your solution!

User avatar
Andredron
Veteran
Posts: 431
Joined: Thu Dec 28, 2017 2:37 pm
Location: Russia
Contact:

Re: How to encrypt / obfuscate your Ren'Py archive RPA files to prevent common programs from opening them

#3 Post by Andredron » Mon Aug 03, 2020 2:22 am

https://www.renpy.org/doc/html/file_pyt ... list_files



Inside the game itself, renpy.list_files will give you all the files in the game, renpy.file will return a file object, at least a physical one, even from an rpa, along the renpaev path. You read data from it, create a file on disk, and write data from a file object there.

Code: Select all


from os import (
..path,
..makedirs
)
output_folder = u"
destination folder address"
for myfile in renpy.list_files():
..out_file = path.abspath(path.join(output_folder, myfile))
.._dirname = path.dirname(out_file)
..if not path.isdir(_dirname):
....makedirs(_dirname)
..chunk = b""
..with renpy.file(myfile) as _readfile:
....with open(out_file, "wb") as _writefile:
......while True:
........chunk = _readfile.read((2 ** 10))
........if not chunk:
..........break
........_writefile.write(chunk)

Something like this and no protection from you


And

viewtopic.php?f=8&t=52149&p=497376#p497376
I know, I'm writing terribly in English.

I'm writing a Renpy textbook (in Russian). https://yadi.sk/d/ZX_DonP63USRru Update 22.06.18

Honest Critique

Post Reply

Who is online

Users browsing this forum: No registered users