Magisk

Internal Details

File Structure

Paths in “Magisk tmpfs directory”

Magisk will mount a tmpfs directory to store some temporary data. For devices with the /sbin folder, it will be chosen as it will also act as an overlay to inject binaries into PATH. From Android 11 onwards, the /sbin folder might not exist, so Magisk will use /debug_ramdisk as the base folder.

# In order to get the current base folder Magisk is using,
# use the command `magisk --path`.
# Binaries like magisk, magiskinit, and all symlinks to
# applets are directly stored in this path. This means when
# this is /sbin, these binaries will be directly in PATH.
MAGISKTMP=$(magisk --path)

# Magisk internal stuffs
INTERNALDIR=$MAGISKTMP/.magisk

# /data/adb/modules will be bind mounted here as read-only.
# The original folder is not used directly due to the nosuid mount flag on /data.
$INTERNALDIR/modules

# The current Magisk installation config
$INTERNALDIR/config

# Symlink/mount to the pre-init storage directory
# Used to persist custom sepolicy.rule across reboots so it can be read during pre-init
$INTERNALDIR/preinit

# Internal tmpfs workspace used for constructing magic mount trees
$INTERNALDIR/worker

# Internal BusyBox directory containing busybox and its applet symlinks
$INTERNALDIR/busybox

# Internal device nodes, pipes, and sockets (magiskd socket, preinit block device, log pipe)
$INTERNALDIR/device

# Root directory patch/overlay files
# On system-as-root devices, / is not writable.
# All pre-init patched files are stored here and bind mounted.
$INTERNALDIR/rootdir

# Isolated devpts mount for root shells (if supported by the kernel)
$INTERNALDIR/pts

Paths in /data

Some binaries and files should be stored on non-volatile storages in /data. In order to prevent detection, everything has to be stored somewhere safe and undetectable in /data. The folder /data/adb was chosen because of the following advantages:

SECURE_DIR=/data/adb

# Folder storing general post-fs-data scripts
$SECURE_DIR/post-fs-data.d

# Folder storing general late_start service scripts
$SECURE_DIR/service.d

# Magisk modules
$SECURE_DIR/modules

# Magisk modules that are pending for upgrade
# Module files are not safe to be modified when mounted
# Modules installed through the Magisk app will be stored here
# and will be merged into $SECURE_DIR/modules in the next reboot
$SECURE_DIR/modules_update

# Database storing settings and root permissions
MAGISKDB=$SECURE_DIR/magisk.db

# All magisk related binaries, including busybox,
# scripts, and magisk binaries. Used in supporting
# module installation, addon.d, the Magisk app etc.
DATABIN=$SECURE_DIR/magisk

Magisk Booting Process

Pre-Init

magiskinit replaces init as the first program to run.

post-fs-data

This triggers on post-fs-data when /data is decrypted and mounted. The daemon magiskd is launched, Safe Mode is evaluated (if the device failed to reach boot-complete twice in a row, or if Safe Mode was triggered via key combo or the Magisk app, all modules and Zygisk are disabled), post-fs-data scripts and module system.prop files are processed, and enabled module files are magic mounted.

late_start

Later in the booting process, the class late_start will be triggered, and Magisk “service” mode will be started. In this mode, general and module service.sh scripts are executed.

boot-complete

When sys.boot_completed=1 is triggered, Magisk resets the bootloop counter, mounts/symlinks the writable preinit storage directory for future module installations, and finalizes Zygisk state.

Resetprop

Usually, system properties are designed to only be updated by init and read-only to non-root processes. With root you can change properties by sending requests to property_service (hosted by init) using commands such as setprop, but changing read-only props (props that start with ro. like ro.build.product) and deleting properties are still prohibited.

resetprop is implemented by distilling out the source code related to system properties from AOSP and patched to allow direct modification to property area, or prop_area, bypassing the need to go through property_service. Since we are bypassing property_service, there are a few caveats:

SELinux Policies

Magisk patches the stock sepolicy to ensure root and Magisk operations can be performed safely and reliably:

The full set of built-in policy rules can be found in native/src/sepolicy/rules.rs.