Skip to content

Releases

v3.3.4-o1-test — LogBox + custom LKM fixes

Choose a tag to compare

@zsw125 zsw125 released this 05 Nov 04:54

v3.3.4-o1-test — LogBox scroll fix + modern custom LKM loading.

Fixes

  • LogBox auto-scroll: the app used fullScroll(FOCUS_DOWN) after every line; with a selectable TextView some ROMs turn that into "scroll to the focused view's top", so the log jumped upwards. It now records whether you are already near the bottom and scrolls explicitly to the real bottom (scrollTo), twice, so the first layout pass counts. Reading old lines no longer drags you away.
  • User-selected .ko (SukiSU 4.3.0 class): two loader defects.
    1. kallsyms_patch() / ksu_patch() rejected ELF modules with more than 64 section headers; SukiSU 4.3.0 ships 65, so the kallsyms path failed (KSU_LOADER relink (kallsyms r=-2 …)). The limit is now 512.
    2. The relink fallback was a silent no-op whenever O3P_CODEPATCH was unset: ksu_patch() returned at the KSU_CODEPATCH skip guard before rewriting any undefined symbol, so the module was written with unresolved symbols and insmod failed with No such file or directory (kernel -ENOENT). ksu_patch() now takes an explicit relink flag — the codepatch guard only applies to the patch-only call, symbol rewriting happens in relink mode, and KSU_PATCH … relink=%d is logged.

Verified on hardware (yingtian, O3 — not O1): with the rebuilt payload run directly from an adb shell and O3P_CUSTOM_KO pointing at the 614,424 B SukiSU 4.3.0 LKM, the log shows KSU_LOADER kallsyms found=251 missing=0, KSU_CODEPATCH skip, KSU_INSMOD_OUT:[rc=0, KSU_MODULE LIVE; /proc/modules lists kernelsu 503808 … Live and SELinux ends in Enforcing. The LogBox stayed pinned to the newest line across 50 appends and did not jump when a scrolled-up view received another line. The O1 profile itself remains untested on O1 hardware.
Carried over from v3.3.3

  • O1 gate fix: the relaxed 6.18.21-android17…-4k series match no longer shadows the verified yingtian/lhasa path (o1Gate = o1Dev != null && (o1Kernel || o1Series)).
  • Two-step confirmation before any payload run on a recognised O1 device.
  • Experimental O1 (XRING) profile for dijun / jinghu / violin; the analysed kernel is 6.18.21-android17-5-g1d099fcb35e0-abogki538445360-4k, other OS4.0.0.x builds in the same 6.18.21-android17…-4k series are accepted in relaxed mode.

Artifacts

  • APK release/test/o3root2-v3.3.4-o1-test.apk, 14,247,440 B, sha256 1a298929f203d718d5328a398a03603efd664f7612f5eaacf7dc46bfb5daafeb, versionCode 24 / 3.3.4-o1-test, includes the hidden console.
  • payload libo3p.so 1,496,668 B, sha256 fef5e065fb20e07b39ab4246eb1ef0d8e637f0a9cc77465c395e2432d9ebadeb.

Install

adb install -r release/test/o3root2-v3.3.4-o1-test.apk

Status / risk

  • The O1 profile is still static-analysis only; no O1 device has run it here. The relaxed gate uses the analysed O1 selinux_state address for any 6.18.21-android17…-4k build, so an unknown build can write to the wrong page → possible panic. Keep a recovery path.
  • Read docs/TESTING_O1.md before trying it; report the SELINUX_PROFILE kernel=… base=… src=… line, UIDNOW/KSU_* lines, and adb shell getprop ro.product.device.

Supersedes v3.3.3-o1-test (its tag/release was removed).

O3 Root v3.3

Choose a tag to compare

@zsw125 zsw125 released this 05 Nov 05:08

O3 Root v3.3 — stable release with the LogBox and custom-LKM fixes.

  • LogBox: the newest line now stays pinned at the bottom (explicit scrollTo instead of fullScroll, which jumped to the focused/selectable view); scrolling up by hand is no longer interrupted by new output.
  • Custom .ko: the loader accepts modern LKMs with more than 64 sections (SukiSU 4.3.0 has 65) and the relink fallback really rewrites undefined symbols instead of silently doing nothing when the codepatch is disabled. Verified on yingtian with the SukiSU 4.3.0 android17-6.18 LKM: KSU_LOADER kallsyms found=251 missing=0, KSU_INSMOD_OUT:[rc=0], KSU_MODULE LIVE.
  • O1 (XRING) profile is part of the stable build now: a recognised dijun / jinghu / violin device with the analysed kernel or another 6.18.21-android17…-4k OS4.0.0.x build is accepted (relaxed mode with a stronger warning), and running the payload requires the two-step confirmation dialog. Static analysis only — no O1 hardware has run it.
  • No root console in this build (that stays in the separate test APKs).
  • Payload unchanged from v3.3.4: libo3p.so 1,496,668 B, sha256 fef5e065fb20e07b39ab4246eb1ef0d8e637f0a9cc77465c395e2432d9ebadeb.
  • APK: 14,243,344 B, sha256 c98a9ced675abd5086da3c0bd05ff8fd836ae948e3bcaf1895a73414ad3bd21e (versionCode 20 / versionName 3.3).
  • Install: adb install -r release/o3root2-v3.3.apk (or the attached APK). Root/ KernelSU is boot-only; Shizuku must run in shell mode.
  • v3.2 remains available as the previous stable release; test builds v3.2.1-console and v3.3.4-o1-test are separate pre-releases.

v3.2.1-console (root console test build)

Choose a tag to compare

@zsw125 zsw125 released this 31 Oct 20:26

v3.2.1-console — test build with a hidden root console (pre-release)

Test build only. The stable v3.2 release is the normal download.

Everything from the stable v3.2 plus a root console:

  • Hidden entry: long-press the version row.
  • Three non-skippable confirmations: non-cancelable risk dialog, checkbox
    dialog, then type exactly I ACCEPT ROOT RISK.
  • One-shot token; ConsoleActivity refuses to start without it.
  • Commands run through the payload's rootd socket (@o3p_rootd, uid 0/2000),
    so the payload must have completed successfully in the current boot. No new
    privilege path — the console is a thin client of the root daemon.

Version

  • versionCode 18 (stable v3.2 is 17), versionName 3.2.1-console; the
    -console suffix marks the terminal feature. Installs over stable with a
    normal adb install -r (no -d needed).

Artifact

  • o3root2-v3.2.1-console.apk — 14,243,344 B, sha256
    9cba365a36344a3e6994100a6d3276b220f15bc4de7d7ce2bde74a6999674f8e

Verified on yingtian: upgrade from v3.2 (versionCode 17 → 18) installs and
shows v3.2.1-console; the three dialogs, token guard, and id running as
uid 0 through rootd ([exit 0], from the earlier beta build of the same code).

O3 Root v3.2

Choose a tag to compare

@zsw125 zsw125 released this 31 Oct 20:20

v3.2 — stable release

Changes

  • LogBox is now selectable and copyable. The log header gained a 复制
    (copy) action that copies the whole accumulated log; the text view itself is
    selectable, so a partial copy works too. Auto-scroll now follows the log only
    while the reader is within about one screen of the bottom, so scrolling back
    no longer fights the live output.
  • The exploit path, payload and built-in LKMs are unchanged from v3.1.1
    (libo3p.so sha256 e479e539…); this release only adds app-side build/UI
    code (BuildInfo, ClickCopyLog).

Test build

A separate pre-release, v3.2-beta1 (versionCode 16), adds a hidden root
console behind a long press of the version row with three non-skippable
confirmations. It is a test build — use the stable APK unless you are testing
that feature. Its APK is attached to the v3.2-beta1 pre-release, not here.

Artifact

  • o3root2-v3.2.apk — 14,239,248 B, sha256
    64bbc65420181babd69b826de7b86be99409963dd29253b72a2930d7a7ff6cfd
  • Requires Shizuku (shell mode) / ShizukuX; install over an older build with
    adb install -r.

Verified on yingtian (Xiaomi Pad 9 Pro Max, kernel 6.18.21): selectable log,
copy action, conditional auto-scroll, and no console entry on the stable build.

v3.1.1

Choose a tag to compare

@zsw125 zsw125 released this 31 Oct 19:33

v3.1.1 — the user-selected .ko now survives app restarts.

  • App v3.1.1 (versionCode 15): the picked module is stored as custom-ko.ko + custom-ko.meta (forced flag + label) in the app-specific files dir (Android/data/o3.st.root1/files), restored in onCreate, and re-validated — a stale or failing file is deleted (unless it was forced) and the UI returns to adaptive. Long-press the module row to clear the choice and use the built-in LKMs again.
  • Payload unchanged: libo3p.so 1,496,044 B, sha256 e479e539bf812f7fe0dc18734ec6f47727fc6f650b4a8d9fd45751a9c6500a2b.
  • Hardware-verified on yingtian (2026-11-01): persistence across force-stop and cold boot; forced 6.6.000-vermagic module (CUSTOM_KO force reason=kernel_series_mismatch → KSU_INSMOD_OUT:[rc=0] → KSU_MODULE LIVE); long-press clear; adaptive cold boot (KSU_BLOB v2 tag=3 matched=1 → origin=builtin → KSU_MODULE LIVE, SukiSU manager working). The automatic fallback branch still has no hardware trigger (the relink rewrites vermagic, so the forced module loads); it remains desktop-tested.
  • APK: 14,239,248 B, sha256 a013cbffbe43036e4b7ba3a55554332ab02d23e444103bd043d9e9ef4b9289d0.
  • Requires Shizuku in shell mode (uid=2000, u:r:shell:s0); root is boot-only. Full details in docs/AGENT_HANDOFF.md.

O3 Root v3.1

Choose a tag to compare

@zsw125 zsw125 released this 31 Oct 19:32

v3.1 — user-selected .ko with a compatibility check and adaptive fallback.

  • App v3.1 (versionCode 14): new "选择 .ko" picker. CustomKo validates the chosen file before the run (ELF, 64-bit LE ET_REL, AArch64, .modinfo with name=kernelsu…, kernel series match, ≤ 8 MB). Hard failures show a dialog with 仍然尝试 / 取消 / 退回自适应; a same-series-but-different-build module only warns. The choice lives for the app process (persistence lands in v3.1.1).
  • Payload: O3P_CUSTOM_KO selects the file; ko_validate() re-checks it, ksu_try_load() is shared with the built-in path, and a rejected/unreadable/failed module falls back to the embedded blob automatically. O3P_CUSTOM_KO_FORCE=1 covers the "仍然尝试" path for kernel_series_mismatch only.
  • Hardware-verified on yingtian (2026-11-01): custom tiann v3.3.1 LKM accepted with a warning and loaded (KSU_INSMOD_OUT:[rc=0], KSU_MODULE LIVE); a forced 6.6.000-vermagic module also loaded because the relink rewrites vermagic. The automatic fallback branch was not triggered on hardware.
  • Built-in LKMs unchanged: KernelSU v3.3.1, KernelSU-Next v3.4.2, SukiSU-Ultra v4.2.1-r2 (SukiSU v4.3.0 exists upstream; try it through the custom path).
  • APK: 14,235,152 B, sha256 6d9041a97bb1ea6811b6cc512f3d98bb0504be2b8db1e375b73f56e9879e4d73. Kept in git history at tag v3.1, not attached here.

Superseded by v3.1.1 (fixes persistence of the selection) — prefer that build.

v3.0

Choose a tag to compare

@zsw125 zsw125 released this 25 Oct 14:38

v3.0 — two-reap exploit, KernelSU without init patch.

  • Payload: stage 0 writes an 8-byte unaligned zero at selinux_state-7 (clears only enforcing, keeps initialized/policycap); stage 1 swaps task_cred. KernelSU is loaded through the runtime kallsyms loader with no init patch (KSU_CODEPATCH skip), then restores Enforcing — Wi-Fi stays healthy.
  • App v3.0 (versionCode 13): new payload embedded; the legacy Enforcing-rebound guard/recovery UI was removed (Enforcing is the normal end state now).
  • Verified cold boot on yingtian: KSU_INSMOD_OUT:[rc=0], KSU_MODULE LIVE, Enforcing, ping/nc OK, manager auto-opened, boot unchanged.
  • APK: 14,218,768 B, sha256 c80f499a6b06ddf92241aa8cb0aa8874767eccdd960e631b28dcff98e7c141dd.

Single-reap three-write attempt panicked repeatedly and is kept behind O3P_D3V3 for analysis only.

O3 Root v2.1

Choose a tag to compare

@zsw125 zsw125 released this 25 Oct 12:51

Shizuku-driven CVE-2026-98260 root + KernelSU runtime LKM loader (v2 container with tiann / KernelSU-Next / SukiSU, chosen by the installed manager).

  • Fixes the fresh-device deadlock: permission-aware probe, local PackageManager manager detection, probe-then-payload after granting, unique payload path.
  • Cold-boot verified on yingtian (OS4.0.16.0.XBMCNXM): uid=0 + full caps, KSU Live, manager auto-open, Permissive, network OK.
  • APK sha256 85c3516b84010af241dc95bbca345ebf1d8ed1f2c6ebd8cc0f82161371067178 (14,218,768 B).
  • Only for devices you own; see README / docs/SECURITY.md.