[PR #1777] [MERGED] fix(apktool): run Windows batch launchers through cmd.exe #4810

Closed
opened 2026-10-31 00:55:17 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1777
Author: @kaoru0822-kitauji
Created: 10/11/2026
Status: ✅ Merged
Merged: 10/11/2026
Merged by: @morluto

Base: main ← Head: fix/apktool-windows-batch-launcher


📝 Commits (1)

  • e14a3d5 fix(apktool): run Windows batch launchers through cmd.exe

📊 Changes

6 files changed (+291 additions, -51 deletions)

View changed files

📝 docs/apktool-resource-analysis.md (+8 -0)
📝 src/apktool/ApktoolConfiguration.test.ts (+76 -0)
📝 src/apktool/ApktoolConfiguration.ts (+76 -8)
📝 src/apktool/ApktoolProvider.ts (+24 -6)
📝 src/ghidra/GhidraLauncher.ts (+26 -37)
➕ src/process/WindowsBatchCommand.ts (+81 -0)

📄 Description

Fixes #1774.

Problem

On Windows, REA_APKTOOL_COMMAND pointed at a .bat/.cmd launcher could never start. These include Chocolatey's apktool.bat and the java -jar wrapper scripts that REA's remediation text recommends. Since the CVE-2024-27980 fix, Node refuses to run batch files without a shell and throws EINVAL. The probe then reported version_unresolved ("did not report a usable version"), which points at the launcher instead of the spawn. The decode run used REA's native Windows spawner with CRT argument quoting, which cmd.exe does not parse safely.

Change

  • New src/process/WindowsBatchCommand.ts: Ghidra's existing conservative batch call, moved out of GhidraLauncher. It builds a ComSpec-validated cmd.exe /d /e:on /v:off /s /c "…" call: no AutoRun, no delayed expansion, every token quoted. Tokens containing " % ^ ! & | < > or newlines are rejected rather than escaped.
  • Ghidra: now calls the shared helper. It keeps its GhidraLaunchError, its P0 wording and its 30,000-character limit. The existing Ghidra batch tests (exact cmd.exe argv, metacharacter rejection, ComSpec selection) pass unchanged.
  • apktool: apktoolInvocation wraps the launcher only when the platform is win32 and the path ends in .bat/.cmd. The --version probe and the apktool d decode both use it, with windowsVerbatimArguments. Native .exe launchers and POSIX run exactly as before.
  • Error reporting: a batch launcher path that cmd.exe would reinterpret now reports launcher_unsupported, which maps to the not_configured rejection code, with remediation. If REA's own decode paths contain those characters, decode returns capability_unavailable naming the cause.
  • Docs: docs/apktool-resource-analysis.md describes the Windows behavior.

Validation

  • New tests in src/apktool/ApktoolConfiguration.test.ts:
    • The exact cmd.exe invocation for a Chocolatey-style apktool.BAT, including a path with spaces.
    • Direct runs for a Windows .exe and a POSIX apktool.cmd name.
    • A metacharacter launcher reported as launcher_unsupported / not_configured before any spawn.
  • npm run test:focused on the apktool module/provider tests, the apktool CLI boundary tests, and the Ghidra launcher module/boundary tests passes (54 passed, 1 Windows-only skip). The provider tests decode with a real launcher stub on macOS.
  • npm run check:fast and npm run docs:check pass.

Not verified: a real Windows host with apktool 3.0.3 and Chocolatey's apktool.bat. I only have macOS here, so the Windows path is covered by argv-construction tests, not by an executed cmd.exe. The issue mentions other providers that use execFileOutput (for example adb). Those still run their launchers directly and are not changed here. A bare apktool resolved from PATH is also unchanged: Windows execFile does not apply PATHEXT, so a PATH-only apktool.bat still needs REA_APKTOOL_COMMAND.

🤖 Generated with Claude Code


🔄 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/1777 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/11/2026 **Status:** ✅ Merged **Merged:** 10/11/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/apktool-windows-batch-launcher` --- ### 📝 Commits (1) - [`e14a3d5`](https://github.com/morluto/rea/commit/e14a3d5672c1a1c6f9573789ff4a04199195d0c0) fix(apktool): run Windows batch launchers through cmd.exe ### 📊 Changes **6 files changed** (+291 additions, -51 deletions) <details> <summary>View changed files</summary> 📝 `docs/apktool-resource-analysis.md` (+8 -0) 📝 `src/apktool/ApktoolConfiguration.test.ts` (+76 -0) 📝 `src/apktool/ApktoolConfiguration.ts` (+76 -8) 📝 `src/apktool/ApktoolProvider.ts` (+24 -6) 📝 `src/ghidra/GhidraLauncher.ts` (+26 -37) ➕ `src/process/WindowsBatchCommand.ts` (+81 -0) </details> ### 📄 Description Fixes #1774. ## Problem On Windows, `REA_APKTOOL_COMMAND` pointed at a `.bat`/`.cmd` launcher could never start. These include Chocolatey's `apktool.bat` and the `java -jar` wrapper scripts that REA's remediation text recommends. Since the CVE-2024-27980 fix, Node refuses to run batch files without a shell and throws `EINVAL`. The probe then reported `version_unresolved` ("did not report a usable version"), which points at the launcher instead of the spawn. The decode run used REA's native Windows spawner with CRT argument quoting, which `cmd.exe` does not parse safely. ## Change - **New `src/process/WindowsBatchCommand.ts`:** Ghidra's existing conservative batch call, moved out of `GhidraLauncher`. It builds a `ComSpec`-validated `cmd.exe /d /e:on /v:off /s /c "…"` call: no AutoRun, no delayed expansion, every token quoted. Tokens containing `" % ^ ! & | < >` or newlines are rejected rather than escaped. - **Ghidra:** now calls the shared helper. It keeps its `GhidraLaunchError`, its P0 wording and its 30,000-character limit. The existing Ghidra batch tests (exact `cmd.exe` argv, metacharacter rejection, ComSpec selection) pass unchanged. - **apktool:** `apktoolInvocation` wraps the launcher only when the platform is `win32` and the path ends in `.bat`/`.cmd`. The `--version` probe and the `apktool d` decode both use it, with `windowsVerbatimArguments`. Native `.exe` launchers and POSIX run exactly as before. - **Error reporting:** a batch launcher path that `cmd.exe` would reinterpret now reports `launcher_unsupported`, which maps to the `not_configured` rejection code, with remediation. If REA's own decode paths contain those characters, decode returns `capability_unavailable` naming the cause. - **Docs:** `docs/apktool-resource-analysis.md` describes the Windows behavior. ## Validation - New tests in `src/apktool/ApktoolConfiguration.test.ts`: - The exact `cmd.exe` invocation for a Chocolatey-style `apktool.BAT`, including a path with spaces. - Direct runs for a Windows `.exe` and a POSIX `apktool.cmd` name. - A metacharacter launcher reported as `launcher_unsupported` / `not_configured` before any spawn. - `npm run test:focused` on the apktool module/provider tests, the apktool CLI boundary tests, and the Ghidra launcher module/boundary tests passes (54 passed, 1 Windows-only skip). The provider tests decode with a real launcher stub on macOS. - `npm run check:fast` and `npm run docs:check` pass. Not verified: a real Windows host with apktool 3.0.3 and Chocolatey's `apktool.bat`. I only have macOS here, so the Windows path is covered by argv-construction tests, not by an executed `cmd.exe`. The issue mentions other providers that use `execFileOutput` (for example adb). Those still run their launchers directly and are not changed here. A bare `apktool` resolved from `PATH` is also unchanged: Windows `execFile` does not apply `PATHEXT`, so a PATH-only `apktool.bat` still needs `REA_APKTOOL_COMMAND`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 00:55:17 +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#4810
No description provided.