Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to use this as a module #136

Open
Bexa2 opened this issue Jan 30, 2022 · 8 comments
Open

Add the ability to use this as a module #136

Bexa2 opened this issue Jan 30, 2022 · 8 comments

Comments

@Bexa2
Copy link

Bexa2 commented Jan 30, 2022

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
Copy link
Author

Bexa2 commented Jan 30, 2022

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
Copy link
Author

Bexa2 commented Jan 30, 2022

Mmmm...

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

@Bexa2
Copy link
Author

Bexa2 commented Jan 30, 2022

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
Copy link
Author

Bexa2 commented Jan 30, 2022

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
Copy link
Owner

@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
Copy link
Author

Bexa2 commented Jan 31, 2022

@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
Copy link

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
Copy link
Contributor

madeddy commented May 8, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants