40

Having recently watched/read a presentation given by Dave Kennedy at DEF CON 20 [PDF], I'd like to know how to decompile a Python script compiled with PyInstaller.

In his presentation, he is creating a basic reverse shell script in Python, and converts it to an EXE with PyInstaller.

My question is how do you take a PyInstaller created EXE and either completely, or generally, retrieve the logic/source code from the original Python script(s)?

1
  • The purpose of generating an EXE with PyInstaller is so that the systems you run it on do not require the existence of a Python interpreter or any 3rd party modules you may be using. It makes your Python script more portable, but does not hide the code / logic from a reverse engineer.
    – Mick
    Commented Apr 2, 2019 at 15:46

5 Answers 5

37
  1. extract EXE's appended data (block starting with PYZ, until the end of the file)
  2. extract wanted files with PyInstaller's archive viewer
  3. decompyle .PYCs - I personally recommend Uncompyle2 for that.
3
10

The presentation at hack.lu 2012 titled "A Critical Analysis of Dropbox Software Security" discussed reversing of the Dropbox desktop client which used a similar implementation but with an added twist of customized Python interpreter with changed bytecode.

Presentation review: http://blog.csnc.ch/2012/12/asfws-a-critical-analysis-of-dropbox-software-security/
Link to the slides: http://archive.hack.lu/2012/Dropbox%20security.pdf

10

PyInstaller publishes it's source so you see exactly how it packs the python code in the executable...

A more general approach would be to use a tool like binwalk on the exe as a first step.

4
  • I'm not sure binwalk is the right tool for this job. It'd show you to the compressed sections of the executable, but the output would likely have a lot other false positives as well unless you point it to look for only compressed sections... which defeats the purpose of using it on this type of file, IMHO.
    – mrduclaw
    Commented Mar 23, 2013 at 9:09
  • 2
    @mrduclaw: my experience with binwalk is that it's a good tool to do a highlevel scan on unknown, binary, files to see what might be in there. Especially if we know what we're looking for but don't know in which file it is. I didn't mean to propose binwalk as a complete solution (modified my answer to indicate it's a first step)
    – Remko
    Commented Mar 23, 2013 at 10:01
  • FYI, the link to binwalk seems flag as malicious website as of June 2020.
    – Karsun
    Commented Jun 10, 2020 at 1:52
  • 1
    @Karsun false positive on a binary on my website, I've reported this to google and it seems to be ok again now (thanks for letting me know)
    – Remko
    Commented Jun 15, 2020 at 8:50
8

This process should get you as close to the original source as possible.

Basically what tools like pyinstaller and py2exe do is package libraries and dependencies all together so you can run the 'stand-alone' EXE without having to download them or prepare the machine with a python interpreter.

When you launch the EXE - it is unpackaged in memory. This includes the .pyc files (python code that is converted to bytecode). pyREtic is a tool that allows you to grab those from memory and convert it back to source.

https://github.com/MyNameIsMeerkat/pyREtic

pyREtic

Reverse Engineer Obfuscated Python Bytecode This toolkit allows you to take a object in memory back to source code, without needing access to the bytecode directly on disk. This can be useful if the applictions pyc's on disk are obfuscated in one of many ways.

4

The one stop solution for all pyinstaller exe things. Use this program to reverse engineer a pyinstaller generated exe file.

https://sourceforge.net/projects/pyinstallerexerebuilder/

Not the answer you're looking for? Browse other questions tagged or ask your own question.