mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 06:45:22 +00:00
[GH-ISSUE #4306] [Feature] Report per-slice LC_ENCRYPTION_INFO status and ciphertext ranges in inspect_macho #1709
Closed
opened 2026-10-16 21:09:18 +00:00 by bsakaguchi
·
1 comment
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#1709
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 16, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4306
Before submitting
Area
Native analysis or decompilation
Current limitation
Have
inspect_machoreport each Mach-O slice'sLC_ENCRYPTION_INFOorLC_ENCRYPTION_INFO_64command (cryptoff,cryptsize,cryptid) as an interpreted encryption status, and state in its limitations that bytes in a range whosecryptidis nonzero are ciphertext, not program code. The request covers detection and reporting ininspect_machoonly. Decrypting such binaries is out of scope under REA's DRM boundary.An analyst inspecting an iOS app executable, or an iOS app installed on a Mac, needs to know whether the
__TEXTbytes REA disassembles are the program or still encrypted. REA does not say. Measured with REA 6.5.0 (npx -y rea-agents@6.5.0, tagrea-agents-6.5.0, commit3b79af28e80785afce9f5998d8f03289402a1847) on macOS 27.0.1 (26A434) arm64 with Xcode 27.0 (27A266a) and Node.js v26.10.0:clang -o enc m.c -Wl,-encryptableproduces anLC_ENCRYPTION_INFO_64command withcryptoff 16384,cryptsize 16384andcryptid 0(otool -l enc). Changing thecryptidword to 1 (fixtureenc1) is the state the SDK header calls encrypted.rea inspect-macho ./enc1 --jsonlists the command only as raw otool text fields,{"cmd": "LC_ENCRYPTION_INFO_64", "cmdsize": 24, "cryptoff": 16384, "cryptsize": 16384, "cryptid": 1, "pad": 0}, and its limitations are the two generic import/export and vtool notes. Nothing states that the range is encrypted. The otool parser keeps unrecognized commands as raw fields by design (otool.ts).inspect_machoreports load commands only for the slice it selects (docs/native-investigation.md), so the encryption state of the other slices in a universal file is not reported at all.lipo -create plain_x86 enc1 -o fat_enc,rea inspect-artifact ./fat_enc --jsonreports theslices/arm64entry withencrypted: false(MachOSliceArtifactReader.ts). That field describes container-entry encryption that blocks reading and extraction (ArtifactExtraction.ts), and the slice bytes are readable, so the value is consistent with its meaning; the artifact graph simply has no place to record the slice's Mach-O protection state.cryptidor any encryption load command.Use cases
No response
Desired outcome and success criteria
inspect_machoreturns a normalized encryption entry for every slice, not only the selected one: the command kind,cryptoff,cryptsizeandcryptidas recorded, the file range in both slice-relative and container coordinates, the segments and sections the range overlaps, and a status. The status isencryptedwhencryptidis nonzero,not-encryptedwhen it is zero, andabsentwhen the slice has no such command. A malformed command, or a range outside the slice, is reported as such and is never treated asabsent.encryptedslice adds a limitation stating that the bytes in the range are ciphertext and that disassembly, decompilation, strings and references derived from them do not describe program code.encryptedflag unchanged, because setting it would block reading and extraction of readable slice bytes. Where the inventory describes a Mach-O slice, it may add the slice's load-command encryption status as a separate fact, so the two meanings stay distinct.Acceptance criteria
printf 'int main(void){return 0;}\n' > m.c && clang -o plain m.c && clang -o enc m.c -Wl,-encryptable, then makeenc1by copyingencand setting the 32-bitcryptidword, 16 bytes into theLC_ENCRYPTION_INFO_64command, to 1, then re-signing withcodesign -f -s - enc1(the script below does this). Confirm withotool -l enc1 | grep -A5 LC_ENCRYPTION_INFO.plainreports statusabsent;encreportsnot-encryptedwithcryptoff,cryptsizeandcryptidequal tootool -l;enc1reportsencryptedplus the ciphertext limitation, and its range maps to the same__TEXTsections thatotool -lplaces inside the file range.lipo -create plain_x86 enc1 -o fat_enc, whereplain_x86comes fromclang -arch x86_64 -o plain_x86 m.c,inspect_machoreportsabsentfor x86_64 andencryptedfor arm64 whichever slice it selects, andextract_artifactstill extracts both slices offat_encunchanged.Expected interaction with targets
Read existing files or captured data
Target and scope details (optional)
Affected area
inspect_machonormalization, its schema and limitations, and optionally a separate slice-protection fact ininspect_artifact.Non-goals
ITSAppUsesNonExemptEncryptionis anInfo.plistkey that declares whether the app uses encryption algorithms; it says nothing about whether the executable is encrypted, and the two must not be conflated.Verification available so far
I can suggest a sample or manual check
Verification details (optional)
No response
Alternatives considered
No response
Possible direction
No response
References
encryption_info_command_64(macOS 10.9+) with fieldscmd,cmdsize,cryptid,cryptoff,cryptsizeandpad(encryption_info_command_64), and the 32-bitencryption_info_command(macOS 10.6+) with the same fields exceptpad(encryption_info_command). The pages carry no field descriptions. The macOS 27.0 SDK headermach-o/loader.hdefines them:cryptoff"file offset of encrypted range",cryptsize"file size of encrypted range",cryptid"which enryption system, 0 means not-encrypted yet" (spelling as in the header)./System/Applications,/System/Applications/Utilities,/usr/binor/usr/libexeccarries either command, so the acceptance criteria use self-built fixtures. Building a 32-bitLC_ENCRYPTION_INFOfixture would need a hand-built header, because the current toolchain targets only 64-bit Apple platforms.d52a488, which also leavesMachOSliceArtifactReader.tsunchanged and adds no encryption handling tootool.tsorNativeMachoInspection.ts.@chordpli commented on GitHub (Oct 20, 2026):
I'd like to take this one. Below is the approach I plan to follow.
Current state (from reading
main, not yet reproduced at runtime)inspect_machorunsotool -lonly for the selected slice (NativeMachoInspection.ts), so other slices of a universal file have no load-command data at all.readMachoImage(MachoLoadCommandReader.ts) already walks every slice's load commands natively, but fails the whole image on the first malformed command or unsupported slice. Adding encryption decoding there would let one badcryptoffregressinspect_artifact/extract_artifact, dylib resolution and the Electron fuse reader.Plan
MachoLoadCommandReader.ts, and rebuildreadMachoImageon them with its current strict policy and error precedence (behavior-preserving, with a multi-defect characterization test).LC_ENCRYPTION_INFO(_64)plusLC_SEGMENT(_64)on top of those readers. One bad slice does not hide the others.encrypted/not-encrypted/absentas in the issue, plusmalformedandunknown, both always with a reason.absentonly when the load-command walk completed. Word size comes from the Mach-O magic.cmdsizemust be 20/24 and match the image width. More than one encryption command ismalformed, with all raw commands kept.cryptid != 0withcryptsize == 0isencryptedwith an empty range and a limitation.encryptedflag ininspect_artifact, the optional inventory fact,machoSliceSchema/trace_dylib_resolutionoutput, and anything that decrypts.clang -Wl,-encryptablefixtures from this issue, built at test time (including the otool section cross-check andextract_artifactonfat_enc), plus synthesized byte tests for the edge cases above.Decisions
sameRegularFileState) beforelipo/otooland after the last read, returningAnalysisArtifactChangedErroron change. The file is not re-hashed, matching whatinspect_machodoes today; the PR will state this as a limitation. Happy to add a streaming sha256 check if you prefer.Related in-flight work I'll rebase onto rather than duplicate: #5254 (exact
arm64e.x1slice names) and #5170 (64-bit load-command alignment) touch the same reader; slice matching here uses CPU type/subtype and offset, so it stays correct either way.If any of this conflicts with how you'd like it done, let me know before I open the PR.
@Anvith433, since #4313 builds on this: the per-slice status, the VM ranges and the unexamined marker above are meant to be consumed directly, so #4313 doesn't need to re-decode load commands. Let me know if you need a different shape.