Closed mattmurdock12 closed 3 years ago
What game are these from? Can you zip and attach the renpy
folder from it? Also, are the files you uploaded from before or after you ran sigCorrector? If after, can you also upload the original ones?
Renpy and .rpyc files in zip package,(Original files not use sigCorrector) Game name (Stay True, Stay You v0.2.1) I downloaded the game from a Turkish site, I want to convert these files to .rpy and edit
but when i try sigCorrector the rpyc file is 15gb :)
I need the .py files from the renpy folder. You left them out.
I am sorry, i cannot access the .py files because it was packaged as .exe, I pulled the .rpyc files from android
This is basically unsolvable then. Try looking for a more official source of the game, and I bet it doesn't have the same problem.
Okay :) Thank you very much for your answers.
I took a quick look at a file and there doesn't seem to be an altered signature. Have you tested running unrpyc on it directly without sigCorrector? A 15 GB .rpyc file doesn't sound right.
I took a quick look at a file and there doesn't seem to be an altered signature. Have you tested running unrpyc on it directly without sigCorrector? A 15 GB .rpyc file doesn't sound right.
I tried this myself on the non-sigCorrector version of the files in Files.zip, and got this for all of them:
raw_contents = raw_contents.decode('zlib')
File "/usr/lib/python2.7/encodings/zlib_codec.py", line 43, in zlib_decode
output = zlib.decompress(input)
error: Error -5 while decompressing data: incomplete or truncated stream
I made this change to see what was going on:
diff --git a/unrpyc.py b/unrpyc.py
index 2a783e8..6cf4e81 100755
--- a/unrpyc.py
+++ b/unrpyc.py
@@ -95,6 +95,7 @@ def read_ast_from_file(in_file):
chunks = {}
while True:
slot, start, length = struct.unpack("III", raw_contents[position: position + 12])
+ print((slot, start, length))
if slot == 0:
break
position += 12
And for options.rpyc
, it gave me this:
(1, 1207959598, 33554688)
(1633643008, 16842752, 39531777)
(3735552, 1, 74)
(3622, 2, 3696)
(3622, 0, 0)
(0, 1502452856, 1252161373)
For a "normal" options.rpyc from a different game, I got this:
(1, 46, 2638)
(2, 2684, 2638)
(0, 0, 0)
If I had the .py files, I could solve this easily. If the place he got this from really went to all the trouble to build a .exe instead of shipping .py files (which the official distribution of this game does not do, by the way), I'd suspect that it's the pirate site he got it from trying to hide malware in them.
hah. The contents table is indeed spoofed. The spoof just starts like a normal signature but then contains some binary garbage. But the actual contents table is still there. Whoever made this was probably aware of the existence of that signature corrector tool (or whatever it's called) and from what I've seen here I guess that tool just looks for the first word matching 0x00000001. So they just put in a fake 0x00000001 in their header to spoof it, amusing. Shenanigans like that are easily revealed by just comparing two files though.
(1, 1207959598, 33554688)
(1633643008, 16842752, 39531777)
(3735552, 1, 74)
(3622, 2, 3696)
(3622, 0, 0)
(0, 1502452856, 1252161373)
If we look closely the actual header is in there, hiding in plain sight:
1, 74)
(3622, 2, 3696)
(3622, 0, 0)
(0
(1, 74, 3622),
(2, 3696, 3622)
(0, 0, 0)
So basically just start parsing the header from byte 38 instead of byte 10 and it should decode fine.
Ooh but now we're getting into fun stuff. They messed around with the pickle implementation used as well I think. Diving in deeper, there are some proper shenanigans here.
Ok those further shenanigans were less interesting than I'd hoped. The actual contents were just base64-encoded before they were compressed. This edit to unrpyc.py will decode everything just fine.
diff --git a/unrpyc.py b/unrpyc.py
index 70b1a87..b359402 100755
--- a/unrpyc.py
+++ b/unrpyc.py
@@ -91,19 +91,21 @@ def read_ast_from_file(in_file):
raw_contents = in_file.read()
if raw_contents.startswith("RENPY RPC2"):
# parse the archive structure
- position = 10
+ position = 38
chunks = {}
while True:
slot, start, length = struct.unpack("III", raw_contents[position: position + 12])
if slot == 0:
break
position += 12
-
chunks[slot] = raw_contents[start: start + length]
raw_contents = chunks[1]
raw_contents = raw_contents.decode('zlib')
+ import base64
+ raw_contents = base64.b64decode(raw_contents)
+
data, stmts = magic.safe_loads(raw_contents, class_factory, {"_ast", "collections"})
return stmts
sorry i replied late but i found all .py files @jackmcbarn
@mattmurdock12 the above diff should solve your issue, please test it. It's game specific so it won't be merged in the mainline decompiler (I'll move it to a branch).
I have a unRen.bat, how can i edit this code ?
No idea. This is the issue tracker for unrpyc. You can try using it directly using the instructions in the README. I was able to decompile the files you sent with these changes, I'd like your confirmation that it works so I can finish this by branching it off on a game support branch.
I did change unrpyc.py and i have new error
The -'ses and +'ses are to indicate removed/added lines in the diff. So you need to change that part of the file to say this:
raw_contents = in_file.read()
if raw_contents.startswith("RENPY RPC2"):
# parse the archive structure
position = 38
chunks = {}
while True:
slot, start, length = struct.unpack("III", raw_contents[position: position + 12])
if slot == 0:
break
position += 12
chunks[slot] = raw_contents[start: start + length]
raw_contents = chunks[1]
raw_contents = raw_contents.decode('zlib')
import base64
raw_contents = base64.b64decode(raw_contents)
data, stmts = magic.safe_loads(raw_contents, class_factory, {"_ast", "collections"})
return stmts
New error :(
Successfully decompiled after the first 47 letters were deleted, thank you.
I'll close this soon then. Might add a command line argument to adjust the location that we expect the table to be at. Shenanigans beget shenanigans.
And , ı want ask you someting else , I find this code in other game .py files "encode('string-escape').encode('hex').encode('zlib')"
And I cant open this game rpyc files
it's doing something dumb to encode file contents in a different way. Just mod unrpyc to reverse the operation when unrpyc tries loading it.
As these shenanigans are getting a bit more common I've added some scaffolding code that tries to figure out if it's a known method on the dev branch. You can use it with the --try-harder option.
Hello, I have a new problem. I added the renpy folder, I can't convert files from .rpyc to .rpy. And I can't open .rpa archive.
please help :) @CensoredUsername
@mattmurdock12 please create a new issue, and follow the issue reporting guides listed in the README.
I cannot convert these files to .rpy, I used sig Corrector and unRen but failed I am waiting for your help, thank you
Rpyc.zip