Skip to content

Commit

Permalink
ren'py started leaking RevertableLists and OrderedDicts into the AST,…
Browse files Browse the repository at this point in the history
… so allow decompilation of those. Make improvement to astdump so we can actually see where they end up from in the AST.
  • Loading branch information
CensoredUsername committed Jun 30, 2019
1 parent 0c70d59 commit 129c4e1
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
17 changes: 15 additions & 2 deletions decompiler/astdump.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,17 @@ def print_ast(self, ast):

def print_list(self, ast):
# handles the printing of simple containers of N elements.
self.p(self.MAP_OPEN[ast.__class__])
if type(ast) not in (list, tuple, set, frozenset):
self.p(repr(type(ast)))

for k in (list, tuple, set, frozenset):
if isinstance(ast, k):
klass = k

else:
klass = ast.__class__

self.p(self.MAP_OPEN[klass])

self.ind(1, ast)
for i, obj in enumerate(ast):
Expand All @@ -88,10 +98,13 @@ def print_list(self, ast):
self.p(',')
self.ind()
self.ind(-1, ast)
self.p(self.MAP_CLOSE[ast.__class__])
self.p(self.MAP_CLOSE[klass])

def print_dict(self, ast):
# handles the printing of dictionaries
if type(ast) != dict:
self.p(repr(type(ast)))

self.p('{')

self.ind(1, ast)
Expand Down
9 changes: 7 additions & 2 deletions un.rpyc/unrpyc-compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ def __setstate__(self, state):
(_, self.source, self.location, self.mode) = state
self.bytecode = None

factory = magic.FakeClassFactory((PyExpr, PyCode), magic.FakeStrict)
class RevertableList(magic.FakeStrict, list):
__module__ = "renpy.python"
def __new__(cls):
return list.__new__(cls)

class_factory = magic.FakeClassFactory((PyExpr, PyCode, RevertableList), magic.FakeStrict)

def read_ast_from_file(raw_contents):
# .rpyc files are just zlib compressed pickles of a tuple of some data and the actual AST of the file
Expand All @@ -61,7 +66,7 @@ def read_ast_from_file(raw_contents):

raw_contents = chunks[1]
raw_contents = raw_contents.decode('zlib')
data, stmts = magic.safe_loads(raw_contents, factory, ("_ast",))
data, stmts = magic.safe_loads(raw_contents, factory, ("_ast, collections",))
return stmts

def ensure_dir(filename):
Expand Down
9 changes: 7 additions & 2 deletions unrpyc.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ def __setstate__(self, state):
(_, self.source, self.location, self.mode) = state
self.bytecode = None

class_factory = magic.FakeClassFactory((PyExpr, PyCode), magic.FakeStrict)
class RevertableList(magic.FakeStrict, list):
__module__ = "renpy.python"
def __new__(cls):
return list.__new__(cls)

class_factory = magic.FakeClassFactory((PyExpr, PyCode, RevertableList), magic.FakeStrict)

printlock = Lock()

Expand All @@ -76,7 +81,7 @@ def read_ast_from_file(in_file):
raw_contents = chunks[1]

raw_contents = raw_contents.decode('zlib')
data, stmts = magic.safe_loads(raw_contents, class_factory, {"_ast"})
data, stmts = magic.safe_loads(raw_contents, class_factory, {"_ast", "collections"})
return stmts

def decompile_rpyc(input_filename, overwrite=False, dump=False, decompile_python=False,
Expand Down

0 comments on commit 129c4e1

Please sign in to comment.