Have fucked Python 2.7 bytecode? Let's unfuck
it.
unfuck
is a utility and library for unfuck
ing obfuscated Python 2.7 bytecode. It is essentially a reimplementation of the Python VM with taint tracking. Some of the things unfuck
can do:
unfuck
can either be used as a library or a command-line utility.
``` unfuck 0.2.0
USAGE:
unfuck [FLAGS] [OPTIONS]
FLAGS: --dry Dry run only -- do not write any files -g Enable outputting code graphs to dot format -h, --help Prints help information -q Disable all logging -V, --version Prints version information -v Enable verbose logging
OPTIONS:
--decompiler
ARGS:
strings-only
subcommand is
applied, this will be where the output strings file is placed
SUBCOMMANDS: help Prints this message or the help of the given subcommand(s) strings-only ```
To unfuck
a single file:
```
unfuck obfuscated.pyc deobfuscated.pyc ```
You can also provide additional flags to dump strings to a file, or dump dot
graphs that can be viewed in graphviz:
```
unfuck -g obfuscated.pyc deobfuscated.pyc
unfuck deobufscated.pyc ./strings.csv strings-only ```
unfuck
requires Python 2.7 in your system's PATH
. After ensuring it's present, you should be able to just cargo build
. If for some reason the correct interpreter cannot be found, try setting the PYTHON_SYS_EXECUTABLE
env var to your Python 2.7 interpreter path.
cargo install --force unfuck
NOTE: unfuck
was not originally designed with library usage in mind, and therefore brings its own multithreading platform (in this case, Rayon).
Usage is fairly straightforward:
```rust use std::convert::TryInto; use std::fs::File;
let mut pyccontents = vec![]; let pycfile = File::open("obfuscated.pyc")?; pycfile.readtoend(&mut pyccontents)?;
// magic/moddate are specific to the PYC header and are required to be // a valid PYC file let magic = u32::fromlebytes(pyccontents[0..4].tryinto().unwrap()); let moddate = u32::fromlebytes(pyccontents[4..8].tryinto().unwrap());
let pyccontents = &pyccontents[8..];
// Use a standard Python 2.7 opcode table
let deobfuscator = unfuck::Deobfuscator::
let deobfuscated_code = deobfuscator.deobfuscate()?;
let mut deobfuscatedfile = File::create("deobfuscated.pyc")?; deobfuscatedfile.writeall(&magic.tolebytes()[..])?; deobfuscatedfile.writeall(&moddate.tolebytes()[..])?; deobfuscatedfile.writeall(deobfuscatedcode.data.as_slice())?; ```
gabe_k, yrp