CensoredUsername / unrpyc

A ren'py script decompiler
Other
858 stars 156 forks source link

Add the ability to use this as a module #136

Open Bexa2 opened 2 years ago

Bexa2 commented 2 years ago

I think it's be nice to be able to use this as a module. Paired with rpatool we could do something like:

import rpatool
import unrpyc

archive = rpatool.RenPyArchive('archive.rpa')
for file in archive.list():
 if 'options.rpyc' in file:
  raw_contents = archive.read(file)
  decompiled_contents = unrpyc.decompile_rpyc(raw_contents)

It'd be useful if you want to extract information from the archive.rpa but don't need to write to file.

Bexa2 commented 2 years ago

My bad, you can use this as a module but unrpyc.decompile_rpyc has to write to file, it'd be cool to be able to choose to return the decompiled rpyc code to variable.

Bexa2 commented 2 years ago

Mmmm...

I've installed with python setup.py install but I get ModuleNotFoundError: No module named 'magic' when trying to import

Bexa2 commented 2 years ago

Yeah, maybe it doesn't really make sense. I can just write raw_contents to file, pass the filename to decompile_rpyc and then read from the decompiled file, then delete both files.

My suggestion would be to maybe use pathlib's Path and on decompile_rpyc return the path to the created file instead of True.

Bexa2 commented 2 years ago

unrpyc.py diff decompiler/__init__.py diff decompiler/astdump.py diff decompiler/codegen.py diff decompiler/screendecompiler.py diff decompiler/sl2decompiler.py decompiler/testcasedecompiler.py diff decompiler/translate.py diff decompiler/util.py diff

With these changes I was able to make it work with python 3.

unrpyc_3.zip

So if you have this structure:


unrpy_3
   ├──decompiler
   │   ├── __init__.py
   │   ├── astdump.py
   │   ├── codegen.py
   │   ├── magic.py
   │   ├── screendecompiler.py
   │   ├── sl2decompiler.py
   │   ├── testcasedecompiler.py
   │   ├── translate.py
   │   └── util.py
   ├── __init__.py (empty)
   ├── decompiler.py
   └── unrpyc.py

You can do

from unrpyc_3 import unrpyc

unrpyc.decompile_rpyc('archive.rpa')

And it works.

CensoredUsername commented 2 years ago

@Bexa2 making decomplie_rpyc operate on file objects instead of filenames would be a nice addition (then you could also just use a BytesIO object in/out when you need to).

Bexa2 commented 2 years ago

@Bexa2 making decomplie_rpyc operate on file objects instead of filenames would be a nice addition (then you could also just use a BytesIO object in/out when you need to).

Yeah, someone could make a script that combines rpatool and unrpyc. rpatool gives you a list of all the files in the archive and lets you read the rpyc, then with unrpyc you decompile/decompress/deobfuscate it without having to write to disk.

This is how I'm doing it right now:

if rpa:
        archive = rpatool.RenPyArchive(file_to_read)
        for file in archive.list():
            if "options.rpy" in file or "scripts.rpy" in file:
                file_contents = archive.read(file)
                tmp_filename = os.urandom(24).hex()

                with open(tmp_filename, mode='wb') as fp:
                    fp.write(file_contents)

                if not unrpyc.decompile_rpyc(tmp_filename):
                    print(f"Error decompiling {archive_rpa}")

                with open(tmp_filename+".rpy", mode="r") as fp:
                    decompiled = fp.read()

                Path(tmp_filename).unlink()

Then I can easily grab the game's name and version so I don't have to rely on many of the filenames devs give to their zip files. GameName_v0.1.3.zip game_name_pc-1.2.zip gamename-1.2.zip

It's a mess.

Drachenfels commented 4 months ago

I actually can do this. This does not feel like a difficult task (but I looked into the code only briefly - so perhaps there are issues I have not noticed yet). Will report back in a 2/3 weeks time.

madeddy commented 4 months ago

Before you base your work on some current branch, it should be taken into account there is a update coming in the next days. Especially unrpyc.py has some heavy changes coming.