CensoredUsername / unrpyc

A ren'py script decompiler
Other
852 stars 154 forks source link

Diamond Rose can't be decompiled because it uses a custom rpc2 header #55

Closed MysteryCorgi closed 7 years ago

MysteryCorgi commented 7 years ago

unrpyc.log.txt

I keep getting this error, so I figured I'd drop the log here.

Thanks, keep up the great work!

jackmcbarn commented 7 years ago

Link to the game in question: https://sendo.itch.io/diamond-rose

jackmcbarn commented 7 years ago

Okay, I see what's going on. That developer modified the version of Ren'Py that ships with the game to format its .rpyc files differently, most likely with the goal of preventing users from doing exactly what you want to do. Luckily, it's impossible for anyone to ever succeed at this long-term. In this case, the following change to unrpyc will let it decompile this game:

diff --git a/un.rpyc/unrpyc-compile.py b/un.rpyc/unrpyc-compile.py
index abfc371..1c7334b 100644
--- a/un.rpyc/unrpyc-compile.py
+++ b/un.rpyc/unrpyc-compile.py
@@ -48,9 +48,9 @@ factory = magic.FakeClassFactory((PyExpr, PyCode), magic.FakeStrict)
 def read_ast_from_file(in_file):
     # .rpyc files are just zlib compressed pickles of a tuple of some data and the actual AST of the file
     raw_contents = in_file.read()
-    if raw_contents.startswith("RENPY RPC2"):
+    if raw_contents.startswith("aJ*@&#Najh@!#';12l41"):
         # parse the archive structure
-        position = 10
+        position = 20
         chunks = {}
         while True:
             slot, start, length = struct.unpack("III", raw_contents[position: position + 12])
diff --git a/unrpyc.py b/unrpyc.py
index 9049011..6d0ef08 100755
--- a/unrpyc.py
+++ b/unrpyc.py
@@ -61,9 +61,9 @@ printlock = Lock()
 def read_ast_from_file(in_file):
     # .rpyc files are just zlib compressed pickles of a tuple of some data and the actual AST of the file
     raw_contents = in_file.read()
-    if raw_contents.startswith("RENPY RPC2"):
+    if raw_contents.startswith("aJ*@&#Najh@!#';12l41"):
         # parse the archive structure
-        position = 10
+        position = 20
         chunks = {}
         while True:
             slot, start, length = struct.unpack("III", raw_contents[position: position + 12])

I'm not going to commit those changes, since that would then break decompiling of normal .rpyc files. However, I built a custom version of un.rpyc with those changes that you can download at http://s000.tinyupload.com/index.php?file_id=84463416005318263535.

@CensoredUsername Thoughts on how we handle this sort of thing?

jackmcbarn commented 7 years ago

At least for now, I think the best way to handle this is to have branches for games that modify Ren'Py. That's what I've done in this case.