PyInstaller Extractor
Extrait le contenu (bytecode compilé, modules embarqués) d'un exécutable généré par PyInstaller, utilisé pour rétro-analyser des malwares écrits en Python. Extracts the contents (compiled bytecode, embedded modules) of a PyInstaller-generated executable, used to reverse Python-based malware.
↗ https://github.com/extremecoders-re/pyinstxtractorOverview
pyinstxtractor unpacks executables built with PyInstaller — a common way to bundle a Python script and interpreter into a single standalone Windows/Linux binary — recovering the original .pyc bytecode files and bundled modules. This is a frequent first step when analyzing Python-based malware or commodity RATs distributed as PyInstaller EXEs, since the compiled .pyc files can then be decompiled back to readable Python source.
Common Usage
Extract a PyInstaller executable’s contents
python pyinstxtractor.py malware.exe
Output goes into a directory named
ls malware.exe_extracted/
Full Analysis Workflow
Step 1: Extract the PyInstaller archive
python pyinstxtractor.py sample.exe
→ -> creates sample.exe_extracted/ containing .pyc files, DLLs, and PYZ-extracted modules
# Step 2: Identify the Python version used (needed for accurate decompilation)
# pyinstxtractor prints this during extraction, e.g. "Python version: 3.9"
Step 3: Fix the .pyc header if needed (pyinstxtractor output sometimes lacks the magic number header expected by decompilers) and decompile
python pycdc.py sample.exe_extracted/sample.pyc > sample_decompiled.py
Step 4: Review the recovered source for C2 URLs, persistence mechanisms, etc.
grep -Ei "http|socket|exec|eval" sample_decompiled.py
Tips
- The extracted main script is usually named after the original entry-point script referenced in the PyInstaller build (visible in the extraction log).
- Match the recovered
.pycmagic number/Python version to the correct decompiler (uncompyle6/decompyle3for Python ≤3.8,pycdc/pylingualfor newer versions) — mismatches produce garbled output. - PYZ-packed modules (the compressed archive of stdlib/third-party imports) are extracted alongside the main script and are worth scanning too — malware sometimes hides logic in a bundled “helper” module rather than the entry point.
Help / Man page
usage: pyinstxtractor.py [-h] filename
PyInstaller Extractor - extracts a PyInstaller generated executable
positional arguments:
filename the PyInstaller executable to extract
optional arguments:
-h, --help show this help message and exit
Output:
Creates a directory <filename>_extracted/ containing:
- the main script's compiled bytecode (.pyc, header may need fixing)
- PYZ-00.pyz_extracted/ (bundled Python modules, auto-extracted)
- bundled shared libraries / DLLs
- struct.pyc (used internally to help fix pyc headers)
Prints detected Python version and PyInstaller version during extraction.
Vue d’ensemble
pyinstxtractor décompacte les exécutables construits avec PyInstaller, une méthode courante pour empaqueter un script Python et son interpréteur en un seul binaire autonome Windows/Linux, en récupérant les fichiers bytecode .pyc d’origine et les modules embarqués. C’est souvent la première étape lors de l’analyse de malwares en Python ou de RATs commodity distribués sous forme d’exécutables PyInstaller, puisque les fichiers .pyc compilés peuvent ensuite être décompilés pour retrouver un code source Python lisible.
Utilisation courante
# Extraire le contenu d'un exécutable PyInstaller
python pyinstxtractor.py malware.exe
# La sortie est placée dans un répertoire nommé <filename>_extracted/
ls malware.exe_extracted/
Workflow d’analyse complet
# Étape 1 : extraire l'archive PyInstaller
python pyinstxtractor.py sample.exe
→ crée sample.exe_extracted/ contenant les fichiers .pyc, DLL et modules extraits du PYZ
# Étape 2 : identifier la version de Python utilisée (nécessaire pour une décompilation précise)
# pyinstxtractor l'affiche pendant l'extraction, par ex. "Python version: 3.9"
# Étape 3 : corriger l'en-tête .pyc si nécessaire (la sortie de pyinstxtractor manque parfois
# du nombre magique attendu par les décompilateurs) et décompiler
python pycdc.py sample.exe_extracted/sample.pyc > sample_decompiled.py
# Étape 4 : examiner le code source récupéré à la recherche d'URLs C2, de mécanismes de persistance, etc.
grep -Ei "http|socket|exec|eval" sample_decompiled.py
Conseils
- Le script principal extrait porte généralement le nom du script d’entrée original référencé dans le build PyInstaller (visible dans le journal d’extraction).
- Faites correspondre le nombre magique/la version Python du
.pycrécupéré avec le bon décompilateur (uncompyle6/decompyle3pour Python ≤3.8,pycdc/pylingualpour les versions plus récentes) : une incompatibilité produit une sortie illisible. - Les modules empaquetés en PYZ (l’archive compressée des imports stdlib/tiers) sont extraits aux côtés du script principal et méritent aussi d’être examinés : les malwares cachent parfois leur logique dans un module « helper » embarqué plutôt que dans le point d’entrée.
Aide / Page de manuel
usage: pyinstxtractor.py [-h] filename
PyInstaller Extractor - extracts a PyInstaller generated executable
positional arguments:
filename the PyInstaller executable to extract
optional arguments:
-h, --help show this help message and exit
Output:
Creates a directory <filename>_extracted/ containing:
- the main script's compiled bytecode (.pyc, header may need fixing)
- PYZ-00.pyz_extracted/ (bundled Python modules, auto-extracted)
- bundled shared libraries / DLLs
- struct.pyc (used internally to help fix pyc headers)
Prints detected Python version and PyInstaller version during extraction.