Pyarmor Static Unpack One-Shot: reading Pyarmor code without running it
✅ No execution ✅ Pyarmor 8.0 - 9.2.x (latest) ✅ Universal ✅ Statically convert obfuscated Python scripts to disassembly and (experimentally) source code.
At a glance
- What is it?
- This tool reverses Pyarmor's packaging statically, turning encrypted Python payloads into bytecode assembly and, experimentally, source, so an analyst can inspect a protected script on a machine where running it would be the risk.
- Who is it for?
- Pyarmor Static Unpack One-Shot fits a reverse engineer or malware analyst who needs to see what a Pyarmor-protected script actually does on a machine where executing it is unacceptable, since the decryption is static and the tool claims support for Pyarmor 8.0 through 9.2.x and Python 3.7 through 3.13.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem it addresses: Pyarmor output is not inspectable
Pyarmor is a popular tool to protect Python source code, and the way it works is the reason this project exists. It turns Python scripts into binary data, which can be regarded as an encrypted variant of pyc files, and those files are decrypted by a shared library, pyarmor_runtime, before the Python interpreter runs them. The consequence for an analyst is obvious once you say it out loud: to look inside the script with the usual tools, you have to run the code, because the running code is what gets the shared library to decrypt it. On a suspected malicious sample, that is exactly what you do not want. This project takes the decryption algorithm from the runtime and applies it statically, so the payload is turned back into bytecode assembly and, experimentally, source code without anything being executed.
It is a fork of Decompyle++ with an AST layer added
The tool is not written from scratch. The project states that it forked the Decompyle++ project, also known as pycdc, and added some processes to it, such as modifying the abstract syntax tree. That lineage explains the shape of the code base and also the project's own plan for it. The author is trying to design and implement a new pyc decompiler, and once that exists the tool can be rewritten on top of it. The current code base based on pycdc will be discarded, and after the new code becomes stable, expected in 2027, the project says it will reach version 1.0.0. The project status page is explicit that the project is already functioning well and there is no need to wait for 1.0.0, but that the public API is still subject to change until then.
Building it takes four cmake commands
The build is a plain CMake build of the pycdc directory that the fork lives in. You create a build directory, configure against the pycdc subdirectory, compile and install.
mkdir build
cd build
cmake ../pycdc
cmake --build .
cmake --install .Prebuilt binaries are also available on the releases page, which is the faster route for anyone who only wants to use the tool. The Python side has one dependency, pycryptodome, listed in the requirements file. The top level of the repository is small, with an oneshot/ directory holding the Python driver and the executable, the pycdc/ directory carrying the forked decompiler, and a requirements file. The releases carry rather theatrical names, v0.4.0 being The Funeral of Bronze Coffin and v0.3.0 being The Vampire Cemetery, with v0.2.2 called Devil's Clinic.
Running it is one command, with the runtime on the side
The tool is driven by a Python script called shot.py, and you point it at the directory holding your scripts.
python /path/to/oneshot/shot.py /path/to/scriptsBefore running it, the executable pyarmor-1shot, or pyarmor-1shot.exe on Windows, has to exist in the oneshot directory. The only thing you need to specify is the directory that contains all armored data and pyarmor_runtime, and the tool finds and handles them recursively as much as possible. When necessary, you can point at a specific pyarmor_runtime executable with the -r option, and the path may be a .pyd, .so or .dylib depending on the platform. Every file the tool generates has a .1shot. marker in its name, and with the -o option you can write the results into another directory instead of in place, with the folder structure left unchanged.
Where it refuses to walk, and what it cannot undo
The tool is careful about not wandering, and the exceptions are documented. Subdirectories are not touched if the folder name is exactly __pycache__ or site-packages, or if the directory directly contains a file named .no1shot, and symbolic links are not followed, to avoid a repeat or endless loop and to save time. The project says that if you really need those directories handled, you can run the script later in them and specify the runtime. There is a harder limit as well. Archives and executables generated by PyInstaller and similar tools have to be unpacked by other tools before decrypting, or you will encounter undefined behaviour. The version support is bounded too: the data must start with PY followed by six digits, and if it starts with PYARMOR instead, it was generated by Pyarmor 7 or earlier and is not supported.
Static and universal, with the test coverage caveat attached
The two headline features are static and universal, and both come with a qualification. Static means you do not need to execute the encrypted script, because the tool decrypts using the same algorithm as pyarmor_runtime, which the project calls useful when the scripts cannot be trusted. Universal means the project is trying to support Pyarmor 8.0 to 9.2.x, which it calls the latest, Python 3.7 to 3.13, on all operating systems, with as many obfuscating options as possible, but it adds in parentheses that it only has limited tests. You can run the tool in any environment, with no need to match the environment of the obfuscated scripts or the runtime. The project also states that it is intended for professional users, and that you should have a basic understanding of Python bytecode, since the tool is a decompiler like any other.
The author's own explanation of why it exists
The project overview includes a section titled Original Intention, and it is the most unusual part of the documentation. The author writes that there are not many code protection tools for Python that are publicly available, that Pyarmor is one of the most popular, and that when analysing some specific Pyarmor-protected scripts, the author found it not so difficult as had been imagined. The conclusion drawn is that just encrypting the code objects is not as irreversible as the project claims, and that Python bytecode based protection is much less secure than native code based protection. The author also states that the project does not make profits by cracking, that there were no other uses for the tool, and that it was published hoping to let people know that Pyarmor with default configuration is not as secure as they think. The project also guarantees that once the Pyarmor project changes the algorithm, the tool will not be updated to support the new algorithm.
What the tool cannot promise, and where it is heading
The warning banner in the project is the part to read before trusting any output. Disassembly results are accurate, but decompiled code can be incomplete and incorrect, and the project links an issue about that. So the reliable artefact is the bytecode assembly, and the reconstructed source is a draft for a human to check against it. The remaining plan before 1.0.0 is listed in the project status: rewriting the code base on the new pyc decompiler, which the project says will be more stable, maintainable and extendable; a wiki about the Pyarmor decryption algorithm, how it was analysed and implemented in the tool; an analysis tool for the native part of BCC Mode, described as the hardest obfuscating option in Pyarmor; and packaging and distribution for installation from package managers such as pip. The project says that after 1.0.0 there may not be much to do, and that it will be maintained with bug fixes as needed. The licence is GPL-3.0, and the last push to the repository was on 2026-10-01.
Editorial conclusion
Pyarmor Static Unpack One-Shot fits a reverse engineer or malware analyst who needs to see what a Pyarmor-protected script actually does on a machine where executing it is unacceptable, since the decryption is static and the tool claims support for Pyarmor 8.0 through 9.2.x and Python 3.7 through 3.13. It does not fit a user who wants readable source, because the project warns that disassembly results are accurate while decompiled code can be incomplete and incorrect, and it does not fit someone who has not done bytecode work before, since the tool is stated to be intended for professional users who already understand Python bytecode. Before you run it, confirm you own the scripts or have permission to analyse them, which the project asks for explicitly, and plan to treat the disassembly as the reliable artefact and the decompiled source as a draft, because the current code base is scheduled to be rewritten on a new decompiler, with version 1.0.0 expected in 2027.
Frequently asked questions
Does Pyarmor Static Unpack One-Shot execute the protected script?
No. The project states that you do not need to execute the encrypted script, because the tool decrypts using the same algorithm as pyarmor_runtime, which it calls useful when the scripts cannot be trusted.
How do I build and run the Pyarmor unpacker?
Build it with mkdir build, cd build, cmake ../pycdc, cmake --build . and cmake --install ., then run python /path/to/oneshot/shot.py /path/to/scripts. The pyarmor-1shot executable, or pyarmor-1shot.exe on Windows, must exist in the oneshot directory first, and prebuilt binaries are also on the releases page.
Which Pyarmor versions and Python versions are supported?
The project is trying to support Pyarmor 8.0 to 9.2.x and Python 3.7 to 3.13 on all operating systems, with as many obfuscating options as possible, though it notes it only has limited tests. Data starting with PYARMOR was generated by Pyarmor 7 or earlier and is not supported.
Can I trust the decompiled source output?
Not on its own. The project warns that disassembly results are accurate while decompiled code can be incomplete and incorrect, and points to an issue on the topic. The tool is also stated to be intended for professional users with a basic understanding of Python bytecode.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lil-house-pyarmor-static-unpack-1shot)Was this useful?