- C++ 84.5%
- Python 14.9%
- CMake 0.5%
No-op prologue/bookkeeping opcodes:
- MAKE_CELL_A: closure cell initialization (Python 3.11+)
- COPY_FREE_VARS_A: copies free vars into frame at function entry (3.11+)
- RETURN_GENERATOR: marks a function as a generator (3.12)
Stack/call opcodes:
- YIELD_VALUE_A: generator yield with stack-depth operand (3.12)
- CALL_FUNCTION_EX_A / INSTRUMENTED_CALL_FUNCTION_EX_A: func(*args, **kwargs)
- LOAD_SUPER_ATTR_A: super().attr access (3.12 specialization)
- LOAD_FROM_DICT_OR_DEREF_A: closure variable load (3.12)
Comprehension opcodes:
- SET_ADD_A: set comprehension element append
- MAP_ADD_A: dict comprehension key/value append
- DICT_UPDATE_A: in-place dict merge (like SET_UPDATE_A for dicts)
Other opcodes:
- LOAD_ASSERTION_ERROR: pushes AssertionError class (used in assert stmts)
- DICT_MERGE_A: merges **kwargs mapping into accumulator dict
- CALL_INTRINSIC_1_A: Python-internal intrinsic functions (pass-through)
- POP_JUMP_IF_NONE_A / POP_JUMP_IF_NOT_NONE_A: None-checking conditional jumps
- LOAD_FAST_CHECK_A / LOAD_FAST_AND_CLEAR_A: variants of LOAD_FAST
Bug fixes:
- Restore accidentally-removed 'case Pyc::LOAD_ATTR_A:' label that was
clobbered when inserting the DICT_MERGE_A handler
- Handle NODE_TUPLE (and other unexpected node types) inside f-string
(NODE_JOINEDSTR) value lists by wrapping them in { } instead of
emitting 'Unsupported node type' and marking cleanBuild=false
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
||
|---|---|---|
| .github/workflows | ||
| bytes | ||
| scripts | ||
| tests | ||
| .gitignore | ||
| ASTNode.cpp | ||
| ASTNode.h | ||
| ASTree.cpp | ||
| ASTree.h | ||
| bytecode.cpp | ||
| bytecode.h | ||
| bytecode_ops.inl | ||
| CMakeLists.txt | ||
| data.cpp | ||
| data.h | ||
| FastStack.h | ||
| LICENSE | ||
| pyc_code.cpp | ||
| pyc_code.h | ||
| pyc_module.cpp | ||
| pyc_module.h | ||
| pyc_numeric.cpp | ||
| pyc_numeric.h | ||
| pyc_object.cpp | ||
| pyc_object.h | ||
| pyc_sequence.cpp | ||
| pyc_sequence.h | ||
| pyc_string.cpp | ||
| pyc_string.h | ||
| pycdas.cpp | ||
| pycdc.cpp | ||
| README.markdown | ||
Decompyle++
A Python Byte-code Disassembler/Decompiler
Decompyle++ aims to translate compiled Python byte-code back into valid and human-readable Python source code. While other projects have achieved this with varied success, Decompyle++ is unique in that it seeks to support byte-code from any version of Python.
Decompyle++ includes both a byte-code disassembler (pycdas) and a decompiler (pycdc).
As the name implies, Decompyle++ is written in C++. If you wish to contribute, please fork us on github at https://github.com/zrax/pycdc
Building Decompyle++
-
Generate a project or makefile with CMake (See CMake's documentation for details)
- The following options can be passed to CMake to control debug features:
Option Description -DCMAKE_BUILD_TYPE=DebugProduce debugging symbols -DENABLE_BLOCK_DEBUG=ONEnable block debugging output -DENABLE_STACK_DEBUG=ONEnable stack debugging output
- The following options can be passed to CMake to control debug features:
-
Build the generated project or makefile
- For projects (e.g. MSVC), open the generated project file and build it
- For makefiles, just run
make - To run tests (on *nix or MSYS), run
make check JOBS=4(optionalFILTER=xxxxto run only certain tests)
Usage
To run pycdas, the PYC Disassembler:
./pycdas [PATH TO PYC FILE]
The byte-code disassembly is printed to stdout.
To run pycdc, the PYC Decompiler:
./pycdc [PATH TO PYC FILE]
The decompiled Python source is printed to stdout.
Any errors are printed to stderr.
Marshalled code objects:
Both tools support Python marshalled code objects, as output from marshal.dumps(compile(...)).
To use this feature, specify -c -v <version> on the command line - the version must be specified as the objects themselves do not contain version metadata.
Authors, Licence, Credits
Decompyle++ is the work of Michael Hansen and Darryl Pogue.
Additional contributions from:
- charlietang98
- Kunal Parmar
- Olivier Iffrig
- Zlodiy
It is released under the terms of the GNU General Public License, version 3; See LICENSE file for details.