Less readable code. Evidence for every change.
Local tools to inspect, harden and verify code exposed to AI-assisted reverse engineering.
Inspect exposed client logic, apply hardening and verify the result locally. de-REA combines APK inspection and JavaScript packaging with isolated Linux ELF reconstruction checks. Use it with your existing coding AI.
Real IP Please APK · web-minimal profile · packaged readability and selected-function regression · View measured data
| Discover | Harden | Verify |
|---|---|---|
| Inspect shipped assets, names and local rules | Bundle scripts, compress formatting and mangle names | Compare functional outcomes in separate offline containers |
Local first: no account, no telemetry, zero npm runtime dependencies. The optional unattended model runner uses an explicit provider configuration and budget. Execution paths · Release capabilities
Prerequisites: Node 24.22.1 (see .nvmrc), npm, and a running Docker daemon capable of Linux/amd64 containers. Docker Desktop can provide that environment on macOS. Internet access is needed to install development dependencies and build the tool image; the smoke execution itself has no network or model dependency.
npm ci
npm run build
npm run container:build
node dist/packages/cli/src/index.js doctor --json
node dist/packages/cli/src/index.js demo --mode smoke --jsonThe final command returns one JSON envelope containing the run ID and absolute artifact paths. It uses no API key, makes no model request, and records zero model cost. It compiles and tests an independently implemented deterministic fixture; this is a framework acceptance test, not a reverse-engineering experiment.
Install the packaged CLI
npm pack
npm install --global ./de-rea-0.1.0-rc.2.tgz
de-rea --help --jsonInstall from zhcalvin/DeRea or the locally built tarball above; this release is distributed through the source repository. Installation uses the packaged files directly and leaves global AI settings untouched. The CLI runs locally without an account or telemetry.
With the owner's permission, we inspected an actual release APK of the open-source IP Please mobile game. The 423,980-byte APK contains a small Android WebView shell and 11 JavaScript assets; 10 retain readable source-like formatting. The key finding is concrete: shipping this client exposes the game's local decision rules to inspection.
The diagram separates scanner observations from a curated, source-assisted analysis of assets/booth.js. An independent implementation matched the original judge() outcome state and recorded citation/scheduling calls on 795/795 cases: 768 Boolean-domain combinations and 27 optional-text cases. This was one source-assisted feature check: the authoring AI inspected the source, then original and candidate ran in separate offline containers. The candidate received only its implementation and test inputs. Additional model API requests: 0.
REA separately parsed the selected module: 9,072 AST nodes, 6,183 semantic nodes and 5,317 relations, with 1,810 semantic unknowns retained in the analysis record. See the case study for source identity, test methodology and reproduction commands.
We then applied the actual web-minimal profile: bundle the scripts, compress them and mangle 329 top-level names. The transformed judge() passed the same 795/795 regression cases. The APK was rebuilt and signed with a new development key; its v2/v3 signatures and stored-resource alignment were verified.
| Observation | Original | web-minimal |
|---|---|---|
| APK bytes | 423,980 | 406,340 |
| JavaScript bytes, including 732 bytes originally inline | 754,673 | 688,867 |
| Source-like JavaScript files | 10 | 0 |
| Selected outcome regression | Reference | 795/795 |
The measured effect is a 4.16% smaller APK, 8.72% less JavaScript with 329 top-level names mangled and readable source formatting compressed. The citation string 放行了不合规旅客 and the public repository remain readable. These measurements cover packaged readability and behavior; model attack costs belong to a separate paired experiment. Before/after evidence
Android acceptance used a fresh Android 35 ARM64 emulator: both APKs installed and rendered the title; the modified build passed language selection and background/resume. The captured logs contained 0 matches for the specified uncaught JavaScript and fatal-exception patterns. This acceptance covers installation and those startup/lifecycle paths.
The feature check also needs the pinned de-rea-rea:6.7.0 image; prepare it using the container build command. APK repackaging uses the existing Android SDK apksigner tool. Transformation prerequisites
# From the source checkout; copy your authorized APK once for local reuse.
mkdir -p targets/local
cp ~/Desktop/app-release.apk targets/local/app-release.apk
node dist/packages/cli/src/index.js inspect --apk targets/local/app-release.apk --json
node scripts/check-ipplease-apk.mjs targets/local/app-release.apk
# Optional transformation; use a new output directory.
npm run container:web-build
node dist/packages/cli/src/index.js harden-apk --apk targets/local/app-release.apk --profile web-minimal --output .de-rea/ip-please-hardened --jsonThe APK copy and raw results stay in ignored local directories. The owner authorized this public-source example. For private projects, admit only approved material to the authoring AI, keep private tests and expected answers with the coordinator, and publish reviewed aggregates. Keep credentials and authoritative security checks outside distributed client code. Code-handling rules
The coordinator admits inputs, keeps private answers separate, runs the selected reconstruction path and verifies submissions offline. REA supplies analysis tools; de-REA supplies task admission, independent verification and comparison.
de-rea init --template jsonl-native --output ./evaluation --json
de-rea harden --config ./evaluation/de-rea.json --profile baseline --json
de-rea validate --config ./evaluation/de-rea.json --json
de-rea plan --config ./evaluation/de-rea.json --json
de-rea run --plan ./evaluation/plan.json --json
# Copy the runId returned above.
de-rea report --run <run-id> --format markdown --jsonFrom the source checkout, replace de-rea with node dist/packages/cli/src/index.js. The generated configuration uses the zero-cost mock runner. A reconstruction task consists of a public specification, examples, an ELF target and a private test suite with independently established expected responses. Task contract
--json emits a single versioned envelope on stdout; --events emits NDJSON and is mutually exclusive with --json. Commands never prompt. Exit codes are 0 for completed commands (including unsuccessful reconstruction), 2 for invalid input, 3 for missing capabilities, 4 for infrastructure failure, 5 for cancellation, and 6 for a stale or changed plan. Error reference
Run state defaults to ./.de-rea in the current directory. Set DE_REA_HOME to use a stable alternative, and use the same location for planning, status, cancellation, and reports. Reusing a plan returns its existing run. repeat explicitly creates a new plan; resume never silently repeats an uncertain model call.
Create matching baseline/candidate configs and an experiment protocol, then execute fresh, randomized paired rounds:
de-rea init --template paired-jsonl --output ./study --trials 3 --json
de-rea harden --config ./study/baseline.json --profile baseline --json
de-rea harden --config ./study/candidate.json --profile release-minimal --json
de-rea benchmark --baseline-config ./study/baseline.json --candidate-config ./study/candidate.json --json
# Use the campaignId returned above.
de-rea report --campaign <campaign-id> --format markdown --json
de-rea export --campaign <campaign-id> --output ./study-share --jsonThe default schedules 3 paired rounds / 6 synthetic trial slots with zero model API requests. benchmark writes a campaign report; report and export reload evidence without replaying trials. Reports retain incomplete pairs, independent attempt counts, Wilson intervals and separate invoice/estimated/reserved costs. Both sides' configured USD ceilings are shown together. Study and contribution guide
baseline records a development build. release-minimal applies compiler optimization and symbol stripping, checks functional regression, and records build identity and whole-process timing samples. Regression failure marks a build as an invalid candidate.
| Published evidence | Result | Measurement scope |
|---|---|---|
| Native C build regression | 196,048 → 38,952 bytes; both builds pass 40/40 cases | Artifact size, functional regression and timings including container startup |
| IP Please transformation | 423,980 → 406,340 bytes; 795/795 judge cases | JavaScript packaging, selected function and Android startup paths |
| Paired-study acceptance | 3 rounds, 6 unique fixture sessions; report reload and export pass | Synthetic study workflow and evidence preservation |
| Synthetic report | Deterministic fixture verified independently | Report format and framework acceptance |
| Native REA acceptance | ELF overview, MCP pseudocode, cancellation and cleanup | REA/Ghidra tool integration |
A model-resistance comparison uses independent trials under matching task/test hashes, model, tools, budget and permissions. Reports retain trial counts, per-category results, Wilson intervals and budget censoring. benchmark records a randomized, interleaved baseline/candidate order before serial execution. The current published evidence comprises the local acceptance records above; controlled paid-model campaigns are a separate experiment lane. Comparison recipe
| Path | Use and conditions |
|---|---|
| Existing coding AI | Local APK inspection and source-assisted feature checks; owner-approved source access |
mock |
Offline, zero-cost framework acceptance using the format-parser fixture; results labeled synthetic |
openai-responses |
Optional unattended ELF experiments; explicit credential, model snapshot, positive budget, dynamic-local tools and separate REA image. Transport/accounting acceptance uses injected HTTP fixtures. Configuration |
codex |
Disabled by a capability gate; planning returns RUNNER_CAPABILITY_UNSUPPORTED. Required controls |
Automated reconstruction accepts Linux/amd64 ELF, UTF-8 JSONL and C11 submissions built with a fixed template and preinstalled dependencies. business-transform and state-machine supply additional task/regression samples. Targets and candidates execute in constrained containers for self-owned samples and cooperative development; the verifier exposes only candidate files and request inputs.
Test results describe the admitted suite. A timeout records noncompletion within the configured budget. Reports keep invoice cost (costUsd), token-based estimates (modeledCostUsd) and reservations (reservedUsd) as separate fields. Accounting contract
For private software, follow the threat model. Keep raw artifacts local, then use export and review the derived report before publication.
npm run check
npm run test:integration
npm run test:e2e
npm run test:packageIntegration, end-to-end, and clean-package smoke tests require the prepared Docker image. test:package packs into artifacts/, installs offline into a new temporary directory, and verifies the installed synthetic smoke. Ordinary CI never receives model credentials or runs paid models. Contributing · Architecture · Security
Project code is licensed under the unmodified Apache License 2.0. External tools retain their own licenses; see third-party notices.