Skip to content
/ pyrev Public

A Python bytecode reversing tool built in pure Rust

License

Notifications You must be signed in to change notification settings

hacbit/pyrev

Repository files navigation

Pyrev v1.1.0-alpha

A Python bytecode reversing tool built in pure Rust

Update

2024/6/2: Added PyInstallerPlugin which can extract pyinstaller archive

!!! Rust nightly is recommended

use this command to switch to the nightly (it may not compile, if it is stable)

rustup default nightly

Build

/path/to/pyrev> cargo build --release [--target your_target_os]

You can use build script to build release to your target OS and copy it to default path (.cargo/bin/).

For Windows:

PS D:\path\to\pyrev> .\build.bat

If you use WSL, you can use the follow command in windows terminal (not in WSL) to build for linux:

PS D:\path\to\pyrev> .\build.bat --wsl

For Linux:

/path/to/pyrev> ./build.sh

If you only want to build and test all tests and doc-test, you also type command cargo make

Usage

PS D:\path\to\pyrev> pyrev help
A Python bytecode reverse engineering tool.

Usage: pyrev.exe [OPTIONS] [name] [COMMAND]

Commands:
  test         test by your given python code
  pyc          decompile pyc files
  pyinstaller  extract and analyze PyInstaller archives
  help         Print this message or the help of the given subcommand(s)

Arguments:
  [name]  Optional name

Options:
  -f, --file <FILE>    specify bytecode files
  -o, --output <FILE>  set name of output file which contains the decompiled result
  -h, --help           Print help
  -V, --version        Print version

You can not specify the -f/--file option, and the program will read the bytecode from stdin.

PS D:\path\to\pyrev> echo 'a.b.c(); print()' | python -m dis | pyrev
Try to decompile [Temp file]
  1| a.b.c()
  2| print()

Test

PS D:\path\to\pyrev> ls test/

    Directory: D:\Rust-test\pyrev\test

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----           2024/4/15    17:42                pyc_test
-a---           2024/4/13    13:41            980 async.py
-a---           2024/4/12     2:30          14174 async.txt
-a---            2024/3/4    17:46            122 attr.py
-a---           2024/4/12     2:30           1742 attr.txt
-a---           2024/4/13     0:14            112 branch.py
-a---            2024/4/6     0:55            768 class.py
-a---           2024/4/12     2:30           7118 class.txt
-a---            2024/4/3    14:45            185 container.py
-a---           2024/4/12     2:30           2200 container.txt
-a---            2024/4/6     0:12            264 def.py
-a---           2024/4/12     2:30           5411 def.txt
-a---           2024/3/27    18:25            414 demo.py
-a---           2024/4/12     2:30           3150 demo.txt
-a---            2024/4/3    14:44            320 except.py
-a---           2024/4/12     2:30           4392 except.txt
-a---            2024/4/3    14:41            121 for.py
-a---           2024/4/12     2:30           1803 for.txt
-a---            2024/4/3    14:42            117 import.py
-a---           2024/4/12     2:30           1399 import.txt
-a---            2024/3/2     1:10            376 op.py
-a---           2024/4/12     2:30           8564 op.txt
-a---           2024/3/19    16:04            119 with.py
-a---           2024/4/12     2:30           3116 with.txt
-a---           2024/3/18    18:16            108 yield.py
-a---           2024/4/12     2:30           2391 yield.txt

You can run like pyrev --file/-f test/import.txt and compare the result with import.py whom generate import.txt

PS D:\path\to\pyrev> pyrev --file ./test/for.txt
[INFO] Try to decompile test/for.txt
  1| arr = [1, 3, 5, 7, 9]
  2| for (i, v) in enumerate(arr):
  3|     line = i + 1
  4|     print(line, v)
  5| print('end')
  6| print('Test')

You can also run the run-all script to run all .txt files in test/ dict

Windows:

PS D:\path\to\pyrev> .\run-all.bat [--release]

Linux:

/path/to/pyrev> ./run-all.sh [--release]

You can add your custom test file to test/ dict and run the get-dis script to generate the .txt file Windows:

PS D:\path\to\pyrev> .\get-dis.bat
This script will delete all .txt files in test/
And get the new python bytecode from python files in test/ and save them as .txt files
Deleting test\attr.txt
Deleting test\class.txt
Deleting test\container.txt
Deleting test\def.txt
Deleting test\demo.txt
Deleting test\except.txt
Deleting test\for.txt
Deleting test\import.txt
Deleting test\op.txt
Deleting test\with.txt
Deleting test\yield.txt
Try run: python -m dis test\attr.py > attr.txt
Try run: python -m dis test\class.py > class.txt
Try run: python -m dis test\container.py > container.txt
Try run: python -m dis test\def.py > def.txt
Try run: python -m dis test\demo.py > demo.txt
Try run: python -m dis test\except.py > except.txt
Try run: python -m dis test\for.py > for.txt
Try run: python -m dis test\import.py > import.txt
Try run: python -m dis test\op.py > op.txt
Try run: python -m dis test\with.py > with.txt
Try run: python -m dis test\yield.py > yield.txt
Done!

Linux:

/path/to/pyrev> ./get-dis.sh
(output)

Document

run the update-doc script to generate doc

You can double-click the index.html in doc/ to open in browser

Todo List

  • if-else (unsound)
  • for
  • while
  • async
  • generator
  • assertion
  • try-except
  • doc comment
  • pyc decompile plugin (unsound)
  • pretty console output plugin
  • pyinstaller archive extractor

About

A Python bytecode reversing tool built in pure Rust

Resources

License

Stars

Watchers

Forks

Packages

No packages published