[PR #1556] [MERGED] feat(apktool): decode Android resource tables through a caller-supplied launcher #2969

Closed
opened 2026-10-17 21:12:22 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1556
Author: @3QL
Created: 10/10/2026
Status: ✅ Merged
Merged: 10/10/2026
Merged by: @morluto

Base: main ← Head: feat/apktool-resources


📝 Commits (5)

  • 1838fdb feat(apktool): decode Android resource tables through a caller-supplied launcher
  • be974c7 fix(apktool): own snapshots and bound decoded resource reads
  • 8e1e402 Merge remote-tracking branch 'origin/main' into HEAD
  • 16fd02e docs(apktool): describe owned resources and bounded projection
  • e6dc53d Merge remote-tracking branch 'origin/main' into HEAD

📊 Changes

47 files changed (+2208 additions, -2 deletions)

View changed files

📝 README.md (+1 -0)
📝 README_ar.md (+1 -0)
📝 README_de.md (+1 -0)
📝 README_es.md (+1 -0)
📝 README_fa.md (+1 -0)
📝 README_fr.md (+1 -0)
📝 README_id.md (+1 -0)
📝 README_ja.md (+1 -0)
📝 README_ko.md (+1 -0)
📝 README_pl.md (+1 -0)
📝 README_pt-BR.md (+1 -0)
📝 README_ru.md (+1 -0)
📝 README_th.md (+1 -0)
📝 README_tr.md (+1 -0)
📝 README_uk.md (+1 -0)
📝 README_vi.md (+1 -0)
📝 README_zh-TW.md (+1 -0)
📝 README_zh.md (+1 -0)
➕ docs/apktool-resource-analysis.md (+86 -0)
📝 docs/testing.md (+14 -0)

...and 27 more files

📄 Description

feat(apktool): decode Android resource tables through a caller-supplied launcher

Implements the Apktool stage of the Android roadmap #717 ("resource ID/XML/locale inspection through Apktool" — the unclaimed piece of the First milestone). With JADX (code), JEB (engine-grade decompilation), and this family (resources), the static Android triad is complete; acquisition and device observation are covered by the ADB family.

Summary

Add an apktool-provider family with two operations over the caller's apktool launcher (REA_APKTOOL_COMMAND, absolute, or apktool on PATH — the same selection pattern as the ADB binary; REA never installs Apktool or Java):

  • inspect_apktool_client — resolved launcher, selection source, version. Decodes nothing; a missing launcher reports capability_unavailable with the REA_APKTOOL_COMMAND remediation.
  • decode_android_resources — runs apktool d --no-src in a provider-owned workspace that is removed before the result returns (an unremovable workspace is named in the limitations, never silently abandoned), then projects:
    • the decoded AndroidManifest.xml text (bounded at 512 KiB, truncation reported),
    • apktool.yml metadata exactly as printed (versionName/versionCode keep their own quoting; SDK range; package_name read from the decoded manifest, not inferred),
    • string resources verbatim — default table or one locale (values-<locale>/strings.xml), bounded to 2,000 entries with coverage: "partial" beyond; escaped entities stay escaped; entries with nested markup are counted as unparsed instead of flattened,
    • every available string locale, and the decoded file count (capped at 100k, cap reported),
    • target.sha256/bytes — the APK is digested before decoding, so Evidence binds the observation to the exact input.

Smali production is skipped by design (--no-src): Java-source recovery belongs to the JADX family. Smali edits and rebuild are a follow-up lane with mutation authority.

Verification

  • 27 module/adapter/service tests with parser goldens taken from a real decode; provider behavior through #!/bin/sh launcher stubs (happy path, locale projection, missing tables noted rather than failed, apktool's own AndrolibException preserved as unsupported_target, missing launcher → capability gap, unreadable target → input refusal, cancellation before spawn).
  • Real-engine lane (npm run verify:apktool): apktool 2.7.0-dirty (Debian packaging) on Linux with OpenJDK 25, against a signed aapt2-built probe APK with two resource locales — launcher version, on-disk digest agreement with the reported target identity, metadata projection (1.2.3, SDK 24–34), manifest package agreement, and both string tables (default + de) projected through the locale option. CLI and MCP surfaces verified against the same launcher.
  • check:fast, docs:generate, docs:check, and 3,400+ tests across domain/services/adapters/composition pass.

Docs

  • New docs/apktool-resource-analysis.md (supply tools, semantics, budgets) and a verification record in docs/testing.md.
  • README analysis table gains an "Android resources" row in English and all 17 translations, following each language's conventions.

Towards #717. No engine, SDK, or tool installation; no new runtime dependencies.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1556 **Author:** [@3QL](https://github.com/3QL) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `feat/apktool-resources` --- ### 📝 Commits (5) - [`1838fdb`](https://github.com/morluto/rea/commit/1838fdbd8591641a6819c60ff4ac8fef485cfb77) feat(apktool): decode Android resource tables through a caller-supplied launcher - [`be974c7`](https://github.com/morluto/rea/commit/be974c7c90f8aa36e43613487d70bf4de15638ca) fix(apktool): own snapshots and bound decoded resource reads - [`8e1e402`](https://github.com/morluto/rea/commit/8e1e4029a45301864380c7c6627314f051ade93b) Merge remote-tracking branch 'origin/main' into HEAD - [`16fd02e`](https://github.com/morluto/rea/commit/16fd02ef9f4c44883131ddf7aa6414c964116582) docs(apktool): describe owned resources and bounded projection - [`e6dc53d`](https://github.com/morluto/rea/commit/e6dc53d3254b69a39a1a02991d3748927f2ced62) Merge remote-tracking branch 'origin/main' into HEAD ### 📊 Changes **47 files changed** (+2208 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `README.md` (+1 -0) 📝 `README_ar.md` (+1 -0) 📝 `README_de.md` (+1 -0) 📝 `README_es.md` (+1 -0) 📝 `README_fa.md` (+1 -0) 📝 `README_fr.md` (+1 -0) 📝 `README_id.md` (+1 -0) 📝 `README_ja.md` (+1 -0) 📝 `README_ko.md` (+1 -0) 📝 `README_pl.md` (+1 -0) 📝 `README_pt-BR.md` (+1 -0) 📝 `README_ru.md` (+1 -0) 📝 `README_th.md` (+1 -0) 📝 `README_tr.md` (+1 -0) 📝 `README_uk.md` (+1 -0) 📝 `README_vi.md` (+1 -0) 📝 `README_zh-TW.md` (+1 -0) 📝 `README_zh.md` (+1 -0) ➕ `docs/apktool-resource-analysis.md` (+86 -0) 📝 `docs/testing.md` (+14 -0) _...and 27 more files_ </details> ### 📄 Description # feat(apktool): decode Android resource tables through a caller-supplied launcher Implements the **Apktool stage of the Android roadmap #717** ("resource ID/XML/locale inspection through Apktool" — the unclaimed piece of the *First* milestone). With JADX (code), JEB (engine-grade decompilation), and this family (resources), the static Android triad is complete; acquisition and device observation are covered by the ADB family. ## Summary Add an `apktool-provider` family with two operations over the caller's apktool launcher (`REA_APKTOOL_COMMAND`, absolute, or `apktool` on PATH — the same selection pattern as the ADB binary; REA never installs Apktool or Java): - **`inspect_apktool_client`** — resolved launcher, selection source, version. Decodes nothing; a missing launcher reports `capability_unavailable` with the `REA_APKTOOL_COMMAND` remediation. - **`decode_android_resources`** — runs `apktool d --no-src` in a **provider-owned workspace that is removed before the result returns** (an unremovable workspace is named in the limitations, never silently abandoned), then projects: - the **decoded AndroidManifest.xml** text (bounded at 512 KiB, truncation reported), - **apktool.yml metadata** exactly as printed (versionName/versionCode keep their own quoting; SDK range; `package_name` read from the decoded manifest, not inferred), - **string resources verbatim** — default table or one `locale` (`values-<locale>/strings.xml`), bounded to 2,000 entries with `coverage: "partial"` beyond; escaped entities stay escaped; entries with nested markup are *counted as unparsed* instead of flattened, - every available **string locale**, and the decoded file count (capped at 100k, cap reported), - `target.sha256`/`bytes` — the APK is digested **before** decoding, so Evidence binds the observation to the exact input. Smali production is skipped by design (`--no-src`): Java-source recovery belongs to the JADX family. Smali edits and rebuild are a follow-up lane with mutation authority. ## Verification - **27 module/adapter/service tests** with parser goldens taken from a real decode; provider behavior through `#!/bin/sh` launcher stubs (happy path, locale projection, missing tables noted rather than failed, apktool's own `AndrolibException` preserved as `unsupported_target`, missing launcher → capability gap, unreadable target → input refusal, cancellation before spawn). - **Real-engine lane** (`npm run verify:apktool`): apktool **2.7.0-dirty** (Debian packaging) on Linux with OpenJDK 25, against a signed **aapt2-built probe APK** with two resource locales — launcher version, on-disk digest agreement with the reported target identity, metadata projection (1.2.3, SDK 24–34), manifest package agreement, and both string tables (default + `de`) projected through the locale option. CLI and MCP surfaces verified against the same launcher. - `check:fast`, `docs:generate`, `docs:check`, and 3,400+ tests across domain/services/adapters/composition pass. ## Docs - New `docs/apktool-resource-analysis.md` (supply tools, semantics, budgets) and a verification record in `docs/testing.md`. - README analysis table gains an **"Android resources"** row in English and all 17 translations, following each language's conventions. Towards #717. No engine, SDK, or tool installation; no new runtime dependencies. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:12:22 +00:00
Sign in to join this conversation.
No milestone
No project
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#2969
No description provided.