Skip to content

Magisk and KernelSU modules

A non-root APK is a separate app with a different package name. A root module instead replaces the installed app's base APK at runtime, so the patched app keeps the stock package, stock data, and Play Store identity.

Morphe Builder generates a minimal module from verified inputs. The ZIP contains the patched base.apk, a verified stock payload, package/version/architecture configuration, module.prop, lifecycle scripts, provenance, and optional update metadata. Module IDs and filenames include the target architecture.

Template and license decision

The builder does not copy or adapt j-hc/revanced-magisk-module. That project was reviewed because it solves a similar problem, but its scripts are GPL-3.0 and cover installation, native utilities, and system-app handling well beyond current requirements. Importing them would add code and licensing obligations without evidence the complexity is needed.

The template here is original minimal code, based only on publicly documented module formats:

No third-party source files or binaries are bundled. j-hc/revanced-magisk-module remains useful prior art under GPL-3.0, not copied code.

Shared module.prop and updateJson fields, the base.apk and stock/ payload layout, and some configuration key names are platform contracts or conventions, not copied code.

Runtime model

The module uses skip_mount plus lifecycle scripts rather than a system/ overlay, which keeps it invisible to the ordinary system-partition mount surface.

ScriptWhenWhat it does
customize.shinstallValidates architecture and permissions, compares installed stock version with the module target, installs matching stock when needed.
service.shevery bootWaits for boot, verifies the installed stock version, bind-mounts patched base.apk over the installed package's base path.
action.shuser actionToggles the mount.
uninstall.shuninstallRemoves the active mount.

On install, a version mismatch requires a signed stock/base.apk in the payload, which is then installed with pm install -r -d. A split-only module aborts without changing the installed app instead of guessing.

Warning: if Android rejects the update because the installed app has a different signer, the script uninstalls the package and then installs the payload. This removes all app data. Back up your data before installing a module over an app that was installed from a different source.

The same scripts run under both Magisk and KernelSU BusyBox ash. Under KernelSU, runtime status is recorded with the official ksud module config when available. No KernelSU metamodule or app-profile binary is needed, because the module does not modify system/ and carries no Zygisk payload.

A root module payload must retain the original stock package name. Non-root APKs using app.morphe.* package names are rejected for modules, because a different package cannot be bind-mounted over the installed stock app.

Payload

At least one verified stock representation is required:

PayloadUse
stock/base.apkMerged stock APK; needed for version-mismatch installation.
stock/splits/Original selected splits; needed for split-faithful recovery.
bothWhen the recovery and installation workflow needs both forms.

Original splits are accepted only when filename, size, and SHA-256 all match the verified source provenance. APK inputs are never modified.

Archive safety

Module ZIPs are built deterministically: entries are sorted, timestamps and Unix modes are fixed, and APK bytes are stored unchanged. Unsafe paths and duplicate entries are rejected, CRCs are verified, and every archived payload hash is compared against its source before publication.

Determinism matters because it makes "the module changed" a meaningful signal: two builds of the same inputs produce byte-identical archives.

Update metadata

When release URLs are supplied, the builder writes a Magisk/KernelSU-compatible update JSON beside the ZIP and adds updateJson to module.prop, so the root manager can offer in-app updates.

All release URLs must be HTTPS and credential-free.

Deferred device validation

Static generation does not prove root-manager behavior. Final validation must cover, on matching ARM64 and ARMv7 environments:

  • installation under Magisk and KernelSU
  • mount behavior after install
  • disable and action flows
  • uninstall
  • version-mismatch handling
  • persistence across reboots
  • the published update JSON

No module is publication-ready until those checks pass. Status is tracked in roadmap/ROADMAP.md and roadmap/COMPLETED.md.

Released under the MIT License.