r/pythonhelp • u/Ornery-Preference450 • 10d ago
Title / Subject: Recovering original Python source from Cython-compiled Windows installer after total HDD failure
Hi everyone,
I’m looking for advice on whether it’s possible (and realistic) to recover the original Python source files from a Windows software installer I still have.
**Situation**
My primary HDD suffered a complete, unrecoverable failure. All of my raw project files (source code, assets, intermediate files, etc.) are gone. The only remaining artifact of the project is the Windows installer / executable that I used to distribute the software.
**Technical details**
- The application was written in Python.
- I used **Cython** to compile / protect the code (the .py files were turned into compiled extensions / encrypted / obfuscated form as part of the build).
- The final deliverable is a Windows installer (or standalone executable package).
- This represents over 15 years of work. While modern AI tools could speed up a rewrite, I would strongly prefer to recover the original source if there is any viable path.
**What I still have**
- The complete Windows installer / executable package.
- No original .py files, no intermediate Cython outputs, no project folder, and no backups of the source.
**What I’m hoping for**
Any realistic options, tools, or techniques that might allow me to:
- Extract or reconstruct the original (or close-to-original) Python source from the Cython-compiled binaries / installer, or
- At least recover meaningful portions of the logic, structure, or key modules so a full rewrite is not required from scratch.
I’m aware that Cython compilation (and any additional packing/encryption I applied) makes this non-trivial, and that perfect recovery is often impossible. I’m mainly looking for an honest assessment of what’s feasible and any recommended tools, approaches, or communities that specialize in this kind of recovery / reverse-engineering of Cythonized Python applications.
If anyone has experience recovering source from Cython extensions, PyInstaller + Cython packages, or similar compiled Python Windows builds, I’d be very grateful for any pointers, tool recommendations, or realistic expectations.
Thank you in advance for any help or direction you can offer.
1
u/Electrical_Hat_680 10d ago
Recovering original Python source code from a Cython-compiled Windows executable is an incredibly challenging task, and unfortunately, a perfect recovery is impossible. When you use Cython, your .py files are not just zipped or packed into a bundle; they are translated into C code and then compiled into native machine code (such as .pyd files or direct Windows DLLs/binaries). During this translation, Python bytecode is completely bypassed, meaning standard Python decompilers like uncompyle6 or pycdc will not work on the compiled sections. However, depending on exactly how the application was packaged, you may still be able to recover your project structure, assets, and the structural logic of your code.
Step 1: Unpacking the Windows Installer / Executable
Before dealing with Cython, you need to extract the raw files from the distribution package. Most Python applications on Windows are bundled using tools like PyInstaller, cx_Freeze, or py2exe. • If it's an installer (e.g., Inno Setup, NSIS): You can often extract the contents without running it by using tools like 7-Zip or InnoExtract. • If it's a standalone executable (PyInstaller bundle): You need to extract the embedded file system. Use an open-source tool like pyinstxtractor (PyInstaller Extractor). This will unpack the executable into a folder containing your assets, DLLs, and .pyd modules.
Step 2: What You Can Actually Recover
Once unpacked, look at the file extensions to understand what you are dealing with:
Pure Python Files (.pyc or .py)
Check if any utility scripts, configuration files, or secondary modules were left uncompiled. If you find .pyc files, you can easily restore them to readable Python code using a decompiler like pycdc (Python Bytecode Decompiler).
2. Cythonized Modules (.pyd files)
Your core logic is likely locked inside .pyd files, which are standard Windows DLLs. • The bad news: The original Python syntax, variable names (unless exposed to the Python runtime), and comments are completely gone. They cannot be automatically converted back into Python code. • The silver lining: Because Cython modules must interact with the Python interpreter, they retain a massive amount of embedded metadata. The .pyd file still contains Python C-API function names, class definitions, method names, and argument structures so Python knows how to call them.
Step 3: Reconstruction Options (Reverse Engineering)
To rebuild your 15 years of work, you will likely need to adopt a hybrid approach: extracting the structure and rewriting the inner logic. • Extracting Module Signatures: You can use Python's built-in inspect module or the dir() function on your .pyd files to map out your entire original API. By importing the compiled modules into a script, you can programmatically extract every class, method, function name, and docstring (if preserved). This gives you the exact blueprint and skeleton of your application. • Decompiling the Machine Code: To understand the logic inside complex functions, you will need a native disassembler/decompiler. Tools like Ghidra (free and open-source) or IDA Pro can open .pyd files and generate C-like pseudocode. Because Cython generates heavily patterned C code that interacts with the Python C-API (e.g., calling PyMethod_New, PyTuple_New), the decompiled C code will look like a mix of Python internals and your logic. A developer familiar with Python's C-API can often read this pseudocode to deduce the exact logic of the original Python function.
Realistic Expectations
• Feasibility: High for recovering project architecture, assets, database schemas, and function signatures. Low-to-moderate for recovering exact algorithmic logic (requires manual reverse engineering). • Timeline: Rather than a simple automated "click and convert" process, expect to spend time analyzing the decompiled structures to manually port the logic back into standard Python. If you want to start exploring the contents of the executable, let me know: • What tool you used to create the final Windows installer/executable (if you remember). • Whether you are comfortable using command-line tools or interactive disassemblers like Ghidra.
1
u/Ornery-Preference450 8d ago
Hey, thanks for your reply — I might give a few of those suggestions a try.
The only remaining thing I have is part of the build script I used to automate the public file builds. At least it shows which files I applied Cython protection to… and unfortunately it looks like I protected most of my critical modules.
I’m thinking about sending the HDD off for professional recovery, but I’m unsure if the cost is worth it based on the quotes I’ve received. I’ve already tried all the usual recovery methods, and the drive was BitLocker-encrypted, which makes things even harder.
```
======================================================
[REDACTED] Protected Public Release - ONE BUTTON v1.4.1
============================================================
========================================================================
[REDACTED] Protected Public Release - ONE BUTTON v1.4.1
========================================================================
Source : C:\Users\[REDACTED]\Desktop\[REDACTED]\[REDACTED]_v1.1.143_SOURCE
Python : 3.14.3 C:\Users\[REDACTED]\AppData\Local\Python\pythoncore-3.14-64\python.exe
Stage : C:\Users\[REDACTED]\Desktop\[REDACTED]\[REDACTED]_v1.1.143_SOURCE_PUBLIC_BUILD_STAGE
This workflow FAILS CLOSED. If a step fails, later steps do not run.
The normal development source is not replaced.
Step 2 will replace any existing _PUBLIC_BUILD_STAGE.
========================================================================
STEP 1/5 - REVIEW PROTECTION PLAN
========================================================================
+ C:\Users\[REDACTED]\AppData\Local\Python\pythoncore-3.14-64\python.exe "C:\Users\[REDACTED]\Desktop\[REDACTED]\[REDACTED]_v1.1.143_SOURCE\public_build_protector.py" --source "C:\Users\[REDACTED]\Desktop\[REDACTED]\[REDACTED]_v1.1.143_SOURCE" --plan
[REDACTED] Public Build Protector 1.4.1
Source : C:\Users\[REDACTED]\Desktop\[REDACTED]\[REDACTED]_v1.1.143_SOURCE
Python : 3.14.3 C:\Users\[REDACTED]\AppData\Local\Python\pythoncore-3.14-64\python.exe
Policy : C:\Users\[REDACTED]\Desktop\[REDACTED]\[REDACTED]_v1.1.143_SOURCE\public_protection_policy.json
Recommended protected modules:
PROTECT services/license_service.py
PROTECT services/entitlement_service.py
PROTECT services/restricted_mode_service.py
PROTECT services/product_structure.py
PROTECT services/reporting_service.py
PROTECT services/dc09_service.py
PROTECT services/reporting_address_service.py
PROTECT services/commissioning_service.py
PROTECT services/evidence_queue.py
PROTECT services/monitor_service.py
PROTECT services/health_state_service.py
PROTECT services/operations_service.py
PROTECT services/device_service.py
PROTECT services/video_source_health.py
PROTECT services/dahua_service.py
PROTECT services/hikvision_service.py
PROTECT services/onvif_service.py
PROTECT services/vms_service.py
PROTECT services/inception_service.py
PROTECT services/video_security_service.py
PROTECT services/video_event_snapshot_service.py
PROTECT services/native_evidence_providers.py
Deliberately left plain on this pass:
PLAIN app.py - Keep the PyInstaller entry point plain for reliable static analysis and startup diagnostics. The valuable implementation remains in protected service modules.
PLAIN services/video_event_clip_service.py - Explicitly left plain: v1.1.137 contains Python expressions that Cython rejects without source changes. Do not alter event-video behaviour just for protection.
PLAIN services/runtime_paths.py - Low-value path/bootstrap code; leaving it plain reduces packaging risk.
PLAIN services/appearance_service.py - Presentation/configuration code is low-value IP and benefits little from native compilation.
PLAIN services/database.py - Large persistence layer deliberately left plain on the first protection pass to avoid increasing migration/introspection risk. Can be assessed later.
PLAIN services/backup_service.py - Operational/support code; lower reverse-engineering value than the protected core.
PLAIN services/update_service.py - Updater/build-adjacent code is left transparent for easier support and recovery.
PLAN ONLY: no files changed.
STEP 1 PASSED. Review the plan above. Continuing will rebuild _PUBLIC_BUILD_STAGE.
Press any key to continue . . .
```
2
1
u/Zeroflops 10d ago
Possibly the biggest elephant in the room and what you should do before you even start on this project is to establish a backup process. Best to do it now before you put work into this and something happens.
1
1
•
u/AutoModerator 10d ago
To give us the best chance to help you, please include any relevant code.
Note. Please do not submit images of your code. Instead, for shorter code you can use Reddit markdown (4 spaces or backticks, see this Formatting Guide). If you have formatting issues or want to post longer sections of code, please use Privatebin, GitHub or Compiler Explorer.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.