mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 06:45:22 +00:00
[GH-ISSUE #2296] [Feature] Decompile static Python bytecode (.pyc) files into labeled source inference #758
Open
opened 2026-10-15 18:28:03 +00:00 by bsakaguchi
·
3 comments
No Branch/Tag specified
main
codex/procedure-reference-stacked
release-please--branches--main--components--rea-agents
release-please--branches--main--components--rea-agents--release-notes
codex/kuna-independent-retry
codex/byte-search-overlay-coverage
codex/open-failure-target-receipt
codex/kuna-xref-evidence
codex/ghidra-ambiguous-procedure-recovery
codex/function-source-bundle
codex/trace-function-integration-prototype
codex/snapshot-source-closure
codex/recorded-evidence-array-pages
codex/evidence-recovery-redesign
codex/trace-feature-address-scope
codex/call-discovery-scope
codex/ghidra-literal-candidate-evidence
codex/decompile-directory-independent-retry
codex/retry-provenance-base
codex/value-flow-capability-experiment
codex/ghidra-containing-instruction
cursor/readme-discord-button-ef9f
dependabot/github_actions/actions/setup-node-7.1.0
dependabot/github_actions/actions/upload-artifact-7.0.2
dependabot/npm_and_yarn/npm-minor-and-patch-d8d97ce6df
codex/kuna-1989
fix/8559-native-ui-fixture-ownership
fix/8555-go-verifier-mcp-ownership
codex/provider-capability-recovery
fix/8642-rizin-target-stdin
codex/ghidra-memory-effect-scope
codex/ghidra-annotation-entry-selector
codex/ghidra-readonly-recovery
codex/ghidra-regex-verifier-recovery
codex/evidence-discovery-view-guidance
fix/8545-bulk-append-overflow
fix/8428-navigation-refusal-alternatives
codex/address-context-recovery
codex/matching-member-limitations
codex/unknown-scope-contract
codex/evidence-view-guidance
feat/8373-native-trace-views
codex/ghidra-snapshot-verifier-binding
codex/elf-export-visibility
codex/evidence-view-recovery
codex/native-reference-cli-help
codex/provider-candidate-observation-scope
codex/kuna-session-verification
codex/ghidra-switch-lifetime-guidance
codex/pseudocode-paging-discovery
codex/clarify-evidence-view-support
codex/kuna-xrefs-selector-recovery
codex/context-capacity-recovery
codex/evidence-closure-large-links
codex/same-function-evidence-identity
codex/ghidra-verifier-inspected-jdk
codex/audit-guided-workflows
codex/crash-prompt-retained-dossiers
codex/analysis-view-error-recovery
codex/kuna-verifier-target-selection
codex/ghidra-selected-project-call-coverage
codex/docs-native-analysis-scope
codex/ghidra-java-socket-boundary
codex/ghidra-retained-snapshot-verifier
codex/ghidra-search-inventory-facts
fix/8284-zero-argument-parameter-bindings
fix/8198-ui-action-handler-offset
fix/8257-elf-entry-label-identity
fix/8304-deferred-output-schema-projection
fix/8277-call-path-computed-target-uncertainty
fix/pr-8089-conflicts
fix/ci-static-duplicate-export
dependabot/npm_and_yarn/lint-staged-17.6.0
dependabot/github_actions/actions/download-artifact-8.0.2
dependabot/npm_and_yarn/write-file-atomic-8.0.0
dependabot/npm_and_yarn/canonicalize-5.1.0
dependabot/github_actions/actions/cache/restore-6.1.0
dependabot/npm_and_yarn/toon-format/toon-4.4.0
dependabot/github_actions/actions/deploy-pages-5.0.1
codex/review-fixes-pr-2403
codex/review-fixes-pr-2400
codex/process-terminal-width
codex/test-brittleness-cleanup
verify/7167-browser-connect-macos
fix/7167-browser-connect
feat/native-matching-allowance-setting
feat/browser-scenario-dry-run
test/managed-caller-parameters-20261024
codex/parser-fortythird-boundaries
fix/6926-pinvoke-platform-decorations-20261023
fix/6889-har-body-encoding-20261023
fix/6888-sqlite-schema-budget-20261023
fix/dependency-security-gates-6708
cursor/evidence-overwrite-rebase-b4ac
feat/4057-verify-native-exports
fix/windows-acl-observer-overhead-20261022
cursor/erlang-beam-restack-4476
cursor/pe-certificate-review-bf32
fix/6116-javascript-application-fs-errors
fix/6061-unmapped-runtime-script-unknown
feat/browser-scenario-summary
fix/pe-certificates
codex/verify-3407
cursor/rebase-5699
cursor/rebase-5352
cursor/rebase-5600
cursor/fix-cli-schema-omission-10a8
codex/audit-hopper-shutdown-reasons-20261021
fix/demangle-swift-omitted-record
fix/nib-boolean-value-types
cursor/cancellation-partial-observation-a5ac
fix/ib-object-limit-reasons
fix/electron-fuse-limit-advice
fix/kuna-doctor-dangling-cache
fix/fixed-budget-refusal-advice
fix/js-ipc-listener-dedup
fix/js-return-member-provenance
fix/dmg-integrity-retry-advice
fix/ida-doctor-readiness
fix/kuna-version-probe-output-drain
fix/legacy-swift-runtime-name-matching
fix/dylib-lazy-load-commands
fix/browser-scenario-startup-cancel
fix/swift-nested-punycode-classification
fix/compare-unselected-scopes
fix/objc-method-budget-coverage
fix/dmg-mounted-root-observations
audit/ci-tests-20261019-round2
release/6.7.0
fix/wabt-cleanup-retry-resolution
fix/electron-fuse-elf-pe-architecture
fix/native-plist-descriptor-ownership
fix/kuna-caller-cleanup-ownership
experiment/atomic-codemode-20261016
review/first-contributor-3776
fix/call-resolution-full-read-cycles
fix/member-mutation-selection-repeat
experiment/atomic-re-tools-20261015
perf/member-mutation-lazy-origins
perf/static-network-mutation-index
fix/hopper-startup-lifecycle
audit/3050-windows-proof-20261015
feat/windows-window-capture-2183
audit/3049-windows-proof-20261015
audit/3735-macos-fixtures-20261015
fix/batch-decompile-null-pseudocode
fix/kuna-inventory-honors-jobs
experiment/browser-codemode-tool-design-20261015
fix/hopper-clean-runtime-argv
codex/review-2049-27f1b367
review-fixes/pr-2787-routing
fix/3360-scoped-this-emitters
fix/3367-replaced-global-effects
fix/3838-compact-any-value-items
test/hopper-download-probe-20261015
codex/windows-runtime-creation-red-green-20261015
codex/windows-readonly-root-red-green-20261015
codex/windows-root-share-red-green-20261015
codex/exp-1685-win-mcp-startup
codex/bug-sweep-20261015
investigate/2190-windows-package-phases
investigate/3543-macos-cli-deadline
perf/3281-reverse-tools-feedback-quality
fix/3406-hopper-doctor-fixture
fix/3341-wrapper-require-test-context
fix/3301-owned-uninstall-fixtures
fix/3164-compiler-input-ownership
fix/pcap-cleanup-stdout-newline-20261014
perf/interface-builder-summary
codex/review-fixes-pr-1977
fix/ghidra-effective-jvm-platform
fix/docs-turkish-rust-link-20261013
fix/main-maintenance-ci-20261010
fix/recover-binary-session-process-effects
codex/review-fixes-pr-2457
codex/ci-required-cancellation-gate
fix/main-format-baseline-20261013
fix/setup-preserve-entry-fields
cursor/restore-main-checks-1ffc
fix/ghidra-bridge-hashmap-import
codex/shared-ci-jadx-json-default-20261013
codex/shared-ci-ghidra-test-groups-20261013
codex/shared-ci-java-fixture-format-20261013
codex/fix-intrinsic-invocation-boundaries
test/release-preflight-reusable-jobs
test/js-parameter-provenance-expectation
fix/linux-hopper-verification-current
test/2419-ghidra-elf-probe-size
followup/pr-1544-native-ida
codex/fold-pr-2230-contribution
docs/readme-responsible-use
fix/issue-2064
fix/issue-2050
fix/issue-2053
fix/issue-1968
fix/issue-1945
experiment/codemode-bridge-20261011
fix/tool-effects-negative-wording-1904-20261012
fix/1842-electron-interop-provenance
feat/recover-javascript-multi-input
refactor/website-i18n-prep
fix/nativeaot-pe-virtual-extent
fix/browser-verifier-ci-hang
fix/pe-resources-input-selection
docs/beginner-friendly-guides
docs/beginner-setup-guide
fix/javascript-analysis-worker-1563
fix/1649-ghidra-duplicate-names
fix/javascript-export-keys-integration-1369
test/maintenance-boundary-contracts-20261011
review/javascript-export-keys-1369
review/process-live-progress-1483
test/javascript-1495-growth-ratio
fix/ci-escape-timing
docs/normalized-terminal-geometry-1450
release/6.3.0
archive/release-6.3.0-pr1381
release/6.2.0
fix/electron-preload-dynamic-override
fix/javascript-self-referential-bundler-edges
release/6.1.0
cursor/grok-client-cherry-pick-0b56
feat/signature-posture
feat/dyld-shared-cache
feat/artifact-integrity-policy
feat/pkg-inventory
release/6.0.0
chore/sync-release-5.0.0
release/5.0.0
cursor/cloud-agent-node-787e
fix/javascript-xhr-open-endpoints
review/pr-711-realpath-fallback-wording
cleanup/replay-confinement
codex/test-suite-performance
codex/issue-foundations
codex/address-open-issues-2026-07-20
agent/javascript-vite-rollup-esbuild-adapters
agent/process-cleanup
agent/triage-integration
agent/unknown-commands-registry
feat/mcp-identity-metadata
morlvps/issue_cleanup
codex/installer-redesign
morl/roadmap-investigation-core
morl/roadmap-investigation-docs
release-please--branches--main--components--rea
rea-agents-6.8.0
rea-agents-6.7.0
rea-agents-6.6.0
experiment/atomic-codemode-wait-runtime-20261016
rea-agents-6.5.0
rea-agents-6.4.0
rea-agents-6.3.0
rea-agents-6.2.0
rea-agents-6.1.0
rea-agents-6.0.0
rea-agents-5.0.0
rea-agents-4.1.0
rea-agents-4.0.1
rea-agents-4.0.0
rea-agents-3.2.1
rea-agents-3.2.0
rea-agents-3.1.0
rea-agents-3.0.0
rea-agents-2.7.0
rea-agents-2.6.0
rea-agents-2.5.1
rea-agents-2.5.0
rea-agents-2.4.0
rea-agents-2.3.0
rea-agents-2.2.0
rea-agents-2.1.0
rea-agents-2.0.0
rea-agents-1.7.0
rea-agents-1.6.0
rea-agents-1.5.0
rea-agents-1.4.0
rea-agents-1.3.0
rea-agents-1.2.0
rea-agents-1.1.0
rea-agents-1.0.0
rea-agents-0.5.0
rea-agents-0.4.0
rea-agents-0.3.0
rea-0.2.1
rea-0.2.0
Labels
Clear labels
area: bridge
area: bridge
area: build
area: build
area: build
area: cli
area: domain
area: evidence
area: mcp
area: native
area: providers
area: runtime
area: server
area: setup
area: tests
bug
design
documentation
enhancement
enhancement
enhancement
experiment
help wanted
i18n
invalid
P0: critical
P1: high
P2: medium
P2: medium
P2: medium
P3: low
performance
provider-request
pull-request
Mirrored from GitHub Pull Request
question
roadmap
triage
No labels
area: bridge
area: bridge
area: build
area: build
area: build
area: cli
area: domain
area: evidence
area: mcp
area: native
area: providers
area: runtime
area: server
area: setup
area: tests
bug
design
documentation
enhancement
enhancement
enhancement
experiment
help wanted
i18n
invalid
P0: critical
P1: high
P2: medium
P2: medium
P2: medium
P3: low
performance
provider-request
pull-request
question
roadmap
triage
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set.
Reference
morluto/rea#758
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @coygeek on GitHub (Oct 12, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2296
Before submitting
Area
Native analysis or decompilation
Current limitation
REA
mainhas no Python bytecode support.parseExecutableHeaderinsrc/domain/binaryTarget.tsrecognizes only ELF, MZ, and Mach-O magic, soopen_binaryon a.pycfails with the genericunsupported binary format(observed withrea-agents@6.1.0on a.pyccompiled by CPython 3.14.7; the same code path is present atmainaeee5074d1). There is no hint of another route.#367 ("Add JVM and Python bytecode providers") is closed as completed by PR #449, but that PR only added
src/domain/bytecodeProvider.ts, which held schemas, extension-based family detection, and path-based provenance classification. It never read bytecode content and was never wired to a tool. Commitc93422a898removed it on 2026-10-07 as abandoned test-only scaffolding.Version coverage is the hard constraint. pycdc's opcode tables stop at Python 3.13, decompyle3 covers 3.7 to 3.8, and uncompyle6 stops at 3.8, so a 3.14
.pyc(magic2b0e0d0a) is outside all three.Use cases
.pycfrom a distributed tool, malware sample, or CTF challenge and needs the most plausible source, with an explicit statement of which parts the decompiler could not reconstruct.Desired outcome and success criteria
A target-free CLI command and MCP tool, similar in shape to
inspect_wasm_artifact, that takes one absolute.pycpath and returns header evidence parsed by REA, plus decompiled source from a caller-configured local engine labeled as inference.unsupported_targetnaming its magic and version, and none returns empty or partial source as complete success.unsupported_targetand from malformed input.open_binaryon a.pycreturns a constraint naming the new tool, as WASM does withwasm_requires_static_inspection.Expected interaction with targets
Read existing files or captured data
Target and scope details (optional)
Input is one explicitly selected local
.pycfile. REA parses the header itself and runs a caller-supplied local decompiler as an owned subprocess on a private read-only copy. The decompiler may run its own helper subprocesses (for example, compiling candidate source with a matching interpreter to check bytecode equivalence), but the target's bytecode is never imported or executed and no network access is needed.Out of scope: extracting bytecode from PyInstaller-frozen executables or other packagers (a separate follow-up, because it adds a container format, marshalled archive parsing, and encrypted-archive scope questions), wheel and zipapp inventory, dynamic Python analysis, hosted decompilation services, bundling or installing engines, and defeating obfuscation or encryption.
Verification available so far
I can suggest a sample or manual check
Verification details (optional)
Compile a small module with CPython 3.14 (
python3 -I -c 'import py_compile; py_compile.compile("sample.py", cfile="sample.pyc")') and callopen_binaryon the result: REA 6.1.0 returnstarget_unavailable/unsupported binary format. The same file is outside pycdc's tables, which end atbytes/python_3_13.cppandMAGIC_3_13inpyc_module.h. Fixtures compiled with 3.8, 3.11, and 3.14 from the same source give a version matrix with known ground truth.Alternatives considered
syssec-utd/pylingual, GPL-3.0-only, v0.0.1 released 2026-09-21) claims coverage of 3.6 through 3.15 and has a CLI,pylingual [-o OUT_DIR] [-c CONFIG] [-v VERSION] [--timeout S] FILES, that writes.pyfiles whose header comments record per-code-object equivalence results; it has no machine-readable output. It needs Python 3.12 or later withtorchandtransformers. By default it downloads models from the Hugging Face Hub at the unpinned revisionmain, and its equivalence check can makeuvx --pythondownload interpreters on demand (or usepyenvfor 3.6 and 3.7). It has the broadest coverage, but it conflicts with an offline default unless REA can require a pinned config, cached models, and pre-installed interpreters.zrax/pycdc, GPL-3.0, C++, no releases) prints source to stdout and needs no network or models, but stops at 3.13.rocky/python-xdis(GPL-2.0) disassembles bytecode across versions (README: 1.0 to 3.13) but does not decompile; it could supply disassembly evidence or a version check.bytecodeProvider.tsscaffold is not useful, because it never read bytecode content.Possible direction
Have REA own
.pycheader parsing and version routing, and keep the engine caller-supplied through an absolute-path setting, as WABT (REA_WABT_BIN_DIRECTORY) and ILSpy (REA_ILSPY_CMD_PATH) already are. This keeps GPL engines out of the MIT package. A later step could route by version across several engines, for example pycdc up to 3.13 and a model-based engine for 3.14 and later. Open questions for maintainers: whether PyLingual can run fully offline from a pinned local config with pre-cached models (for example withHF_HUB_OFFLINE=1) and pre-installed interpreters, which is unverified; whether its equivalence-check subprocesses fit REA's subprocess ownership and limit model; and whether the first slice should support one engine or several.References
github.com/morluto/rea@c93422a898@Joel-Flores123 commented on GitHub (Oct 12, 2026):
For pyinstaller you should look at pyinstextractor-ng, since the normal pyinstxtractor requires you to be running the same version of python as the binary you are extracting from. The ng fork allows you to extract using any supported python versions.
@Joel-Flores123 commented on GitHub (Oct 12, 2026):
Additionally thank you, I did not realize that PyLingual wasn't able to be used offline after downloading the models. I'll see to adding that feature.
@noorranktools commented on GitHub (Oct 15, 2026):
Concrete verified result, not just a survey finding: I tried
pycdc(zrax/pycdc, the one tool in the original survey whose opcode tables claim 3.7–3.13 coverage) against real targets this session and it actually works — with two caveats worth recording here for anyone else evaluating it as a REA backend.Setup: no C++ toolchain was present, so built from scratch:
winget install BrechtSanders.WinLibs.POSIX.UCRT(MinGW-w64, gcc 16.2),cmake -G "MinGW Makefiles",mingw32-make.Caveat 1 — the Release build is broken on Windows/MinGW:
-DCMAKE_BUILD_TYPE=Releaseproduces a binary thatSTATUS_ACCESS_VIOLATION-crashes on every input, including a trivially simple freshly-compiled "hello world".pyc— not a data problem, a real build-config bug in this toolchain combination.-DCMAKE_BUILD_TYPE=Debugworks correctly for the large majority of inputs. (First debugging step wasted time on a false lead: Git-Bash reported the Debug build as "segfaulting" on--helptoo, which turned out to be a console-handling artifact of that shell —gdb -batch -ex runand plain PowerShell both showed it running--helpcleanly. Worth knowing if anyone else hits what looks like a universal crash.)Caveat 2 — real, version-specific opcode gaps, as flagged in the original survey: hit
Unsupported opcode: LOAD_FAST_CHECK (237)andUnsupported opcode: MAKE_CELL (225)on two separate Python 3.12 targets — both Python 3.11+ features (stricter unbound-local checking, closure-cell creation) that this build's 3.12 table doesn't implement. One Python 3.10 target also hit an internalassert(!this->empty())in the AST block-handling partway through one function (a real decompiler limitation on some control-flow shape, not the build) — thoughpycdas(the disassembler half) still produced full output for that same file with no issue.Where it actually worked — real decompiled Python source, not just disassembly, for:
AESCipherclass — hashlib/Crypto.Random/AES-CBC implementation, fullencrypt/decrypt/_pad/_unpadlogic, near-perfect reconstruction with only minor artifacts aroundwith-statement teardown)__init__/model-loading logic, confirmed a hardcoded AES key literal in source form).pyc, via-c -v 3.10) that locally-mismatchedmarshal.loads()couldn't even parse —pycdcdoesn't use the running interpreter's own marshal module, so cross-version input was never the obstacle for it that it is for a stdlib-marshal-based approach. Recovered full source including a literal embedded RSA public key in PEM form, before hitting the assertion above partway through one function.This matches my understanding of where #2433 (pure extraction) and this issue (decompilation) currently sit: acquisition is solved, decompilation has a real, working option for a meaningful version range even though it's imperfect (opcode gaps, occasional internal assertion failures) — closer to "usable with explicit per-failure limitations recorded" than "doesn't exist yet." No code to share (ad hoc build/run, not written for upstreaming), but happy to share exact repro steps/inputs if useful for picking an engine.