Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,32 @@ Player — from one file, fully automatically. Releases are grouped by the BlueS

---

## v12 — Magisk is the SOLE root: scrub any competing su + Verify fails on one · 2026-06-02

Fixes Magisk reporting **"Abnormal State — a su binary not from Magisk has been detected"** on an instance
whose shared master `Root.vhd` still carried a **classic/engine `su`** at `/system/xbin/su` (the old
non-Magisk root method — e.g. left behind by the legacy live-E2E harness). The Magisk pipeline scrubbed
its own *bootstrap* su but never removed a pre-existing `/system/xbin/su`, and **Verify only swept for the
bootstrap su's hash**, so a competing su passed silently. (Git shows **no commit ever changed su handling**;
the v11 adb fix simply let the pipeline *complete*, so Magisk finally booted and flagged the leftover.)

- 🧹 **Prep + Clean now scrub `/system/xbin/su`** (and `daemonsu`) from the master, so Magisk's own su
(`/system/bin/su` → magisk, `/sbin/su` → magisk) is the only one. **Re-running Clean repairs an
already-rooted instance** — verified live: the stray su was removed and the instance returned to a clean
state.
- 🔎 **Verify now FAILS on ANY competing su.** It enumerates every su in the standard PATH dirs and flags
anything that isn't a symlink to magisk (new pure, unit-tested `Find-StraySu`). No more silent PASS with
a foreign su present.
- 🧪 **Live-E2E rewritten + de-footgunned.** `tests/Run-Live-E2E.ps1` used to root via the engine's
**legacy classic-su path** (`-Action AdbRoot`) — which *installs* a competing `/system/xbin/su` and is
not what the tool ships. It now drives the real `bsr_magisk.ps1 -Action Auto` pipeline, **asserts VERIFY
PASS + no competing su** (across a reboot), uses the correct package `io.github.huskydg.magisk`, and
reverts via Magisk **Undo**.
- ✅ **Tests:** `Run-Resolve-Tests.ps1` +7 `Find-StraySu` cases (38 total); `Run-Tests.ps1` (28) and
`Check-Embedded-Sync.ps1` green; re-embedded into `blueStackRoot.cmd`.

---

## v11 — adb robustness: immune to adb-version conflicts + live-bound port detection · 2026-06-02

Fixes a report where a **fully-booted** instance (Home visible, Magisk installed) still failed with
Expand Down
3,808 changes: 1,929 additions & 1,879 deletions blueStackRoot.cmd

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/BLUESTACKS_ROOTING_DEEP_DIVE.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ Per‑instance root = presence of `/data/adb/.bsr_root`. **Proven:** `Rvc64` (fl
| 2nd instance "couldn't launch" | shared master `Root.vhd` was `type="Normal"` (exclusive) | set master **Readonly** (Finalize) |
| Kitsune Mask leaked to unrooted instances | shared `/system` ⇒ `magiskd` ran everywhere | per‑instance gate (`bsr_boot.sh` + `/data/adb/.bsr_root`) |
| `did not become adb‑reachable` though the instance booted | a system `adb` (Android SDK **v1.0.41**) and BlueStacks `HD‑Adb` (**v1.0.36**) fight over the default 5037 server (*"server version doesn't match; killing…"*) → `getprop` fails forever | pin HD‑Adb to a **private** `ANDROID_ADB_SERVER_PORT=15037` (proven: 30/30 getprop OK with a v41 server on 5037; 0/12 on the shared port; full `Boot‑And‑Wait` end‑to‑end PASS) + add **live‑bound‑port** discovery (`Get-NetTCPConnection`) so a stale `status.adb_port` can't strand the boot wait |
| Magisk "Abnormal State — su not from Magisk" though Verify "passed" | a classic/engine `su` left at `/system/xbin/su` on the **shared master** (old non‑Magisk root / the legacy classic‑su live‑E2E); Prep/Clean never scrubbed it and Verify only swept the *bootstrap* su's hash | Prep + Clean now `rm /system/xbin/su` (+`daemonsu`); Verify enumerates **every** su and FAILS on any non‑Magisk one (`Find-StraySu`, unit‑tested); the live‑E2E now drives the **Magisk pipeline** (not classic su) and asserts no competing su — verified live (stray su scrubbed → VERIFY PASS) |

---

Expand Down
2 changes: 1 addition & 1 deletion docs/RUNBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ device after completion: **only Magisk's**. No DiskRW, no engine‑su, no daemon
|---|---|---|
| `bootstrap su not root` during **Data** | patch didn't apply, or `enable_root_access≠1`, or `bindmount` not hijacked | re‑run **Prep**; confirm `HD-Player.exe` = `84 C0 90 90` |
| Magisk app: *Magisk environment incomplete* | `/data/adb/magisk` not populated | re‑run **Data** (it populates it) |
| Magisk app: *Abnormal State — su not from Magisk* | a stray `/system/xbin/su` (old engine `Root`) | `bsr_engine.ps1 -Action Unroot -Vhd <Root.vhd>` (or re‑run **Clean**) |
| Magisk app: *Abnormal State — a su binary not from Magisk* | a **competing `/system/xbin/su`** on the shared master (an old non‑Magisk/classic root, e.g. a prior engine root or the legacy live‑E2E) — Magisk's own su are `/system/bin/su`→magisk + `/sbin/su`→magisk | **fixed in v12**: Prep/Clean now scrub `/system/xbin/su` and Verify FAILS on any non‑Magisk su. To repair an existing instance, **re‑run Clean** (it removes the stray su) and reboot |
| `su` returns nothing / `uid=2000` after Finalize | shell took BlueStacks' gated su; Magisk daemon down | check `/cache/magisk.log`; ensure `/data/adb/magisk/busybox` exists |
| Instance won't boot after edits | HD‑Player patch missing | restore `HD-Player.exe.bak`, re‑apply patch, retry |
| `instance '<x>' did not boot / become adb‑reachable within N s` — **but the instance is up** (Home visible, Magisk installed) | a **system `adb` of a different version** (e.g. Android SDK platform‑tools **v1.0.41**) keeps killing BlueStacks' **HD‑Adb v1.0.36** server on the shared port 5037 — *"adb server version doesn't match this client; killing…"* — so `getprop` calls fail | **fixed in v11**: the tool pins HD‑Adb to its own server port (`ANDROID_ADB_SERVER_PORT=15037`) so the two never collide, and also tries the **live‑bound** adb port, not just `bluestacks.conf`. Update the tool. (Diagnose: compare `adb version` on `PATH` vs `"…\BlueStacks_nxt\HD-Adb.exe" version`.) |
Expand Down
Loading
Loading