Update many details in docs

This commit is contained in:
topjohnwu 2019-03-28 05:25:20 -04:00
parent e784212283
commit 649ef53409
4 changed files with 43 additions and 75 deletions

View File

@ -1,5 +1,5 @@
# Magisk Documentations
(Updated on 2019.2.3)
(Updated on 2019.3.28)
- [Installation](install.md)
- [Prerequisite](install.md#prerequisite)
@ -19,10 +19,6 @@ The followings are for developers
- [Magic Mount](details.md#magic-mount)
- [Simple Mount](details.md#simple-mount)
- [Miscellaneous](details.md#Miscellaneous)
- [Deployment](deploy.md)
- [Systemless](deploy.md#systemless)
- [System Only](deploy.md#system-only)
- [Exploits](deploy.md#exploits)
- [Magisk Tools](tools.md)
- [Developer Guides](guides.md)
- [Magisk Modules](guides.md#magisk-modules)
@ -32,3 +28,7 @@ The followings are for developers
- [Boot Scripts](guides.md#boot-scripts)
- [Remove Files](guides.md#remove-files)
- [Remove Folders](guides.md#remove-folders)
- [Deployment](deploy.md)
- [Systemless](deploy.md#systemless)
- [System Only](deploy.md#system-only)
- [Exploits](deploy.md#exploits)

View File

@ -2,19 +2,9 @@
(Note: This is not a user tutorial for installing Magisk, this is an explaination of how Magisk can be installed, and a guide for developers to properly deploy Magisk in various different situations)
## Systemless
When a user flashes a Magisk zip in custom recoveries or have boot images patched in Magisk Manager, Magisk is installed in this way. This is the only officially supported method to install Magisk on a device. The systemless method installs Magisk into a boot image's ramdisk CPIO, sometimes require additional patches to the kernel.
When a user flashes a Magisk zip in custom recoveries or have boot images patched in Magisk Manager, Magisk is installed in the systemless fashion. This is the only officially supported method to install Magisk on a device. The systemless method installs Magisk into a boot image's ramdisk CPIO, sometimes require additional patches to the kernel.
With the introduction of `magiskinit`, the systemless installation process has become extremely simple as nearly all setup and patches are done at runtime after the device is booted up. Replacing `init` in `rootfs` with our own implementation is required for rooting system-as-root devices systemless-ly - that is why `magiskinit` was created in the first place.
Here are some background knowledge about system-as-root devices:
- No recovery partition. Recovery and system shares the same kernel in boot, and the ramdisk in the boot image is actually the recovery's ramdisk.
- The root folder (`/`) and `/system` are both stored in the system partition.
- When the device boots up, a bootloader will set flags in cmdline so the kernel can decide where to mount `rootfs`: if booting in recovery mode, mount `rootfs` from ramdisk; if not, mount `rootfs` from system with dm-verity enabled.
To install anything systemless-ly, our only choice is to install Magisk files into the ramdisk in boot image. The soultion used in Magisk is to patch the kernel to always boot as recovery mode regardlessly, and we do the `rootfs` construction and booting ourselves. For more details about how `magiskinit` works, check the **Pre-Init** section of [Magisk Booting Process](details.md#magisk-booting-process).
Here are the bare minimum commands to install Magisk into a stock boot image. Be aware that the actual Magisk installation is far more complicated, the following commands will work but should be treat as proof-of-concepts.
Here are the bare minimum commands to install Magisk into a stock boot/recovery image. Be aware that the actual Magisk installation is a little more complicated, the following commands will work but should be treat as proof-of-concepts.
```
# Push 2 binaries, magiskboot and magiskinit to the device

View File

@ -1,80 +1,65 @@
# Magisk Details
## File Structure
### Paths in "sbin tmpfs overlay"
sbin tmpfs overlay is the key to hiding Magisk from detection. All Magisk binaries, applets, mirrors, mountpoints, loop devices, and other trivial stuffs are all located in the `tmpfs` mounted on `/sbin`. MagiskHide can just simply unmount `/sbin` and the bind mounts into `/system` and `/vendor` to hide all modifications easily.
sbin tmpfs overlay is the key to hiding Magisk from detection. All Magisk binaries, applets, mirrors, and other trivial stuffs are all located in the `tmpfs` mounted on `/sbin`. MagiskHide can just simply unmount `/sbin` and the bind mounts to hide all modifications easily.
```
# The actual Magisk binary
/sbin/magisk.bin
# Wrapper script to prevent stupid linker errors
/sbin/magisk
# Other binaries like magiskinit, and all symlinks to
# applets are also directly stored in /sbin, so they
# Binaries like magisk, magiskinit, and all symlinks to
# applets are directly stored in /sbin, so they
# are all in PATH for apps and shell to access them
# Other crazy stuffs are stored in this directory
# Magisk internal stuffs
MAGISKTMP=/sbin/.magisk
# Magisk BusyBox path
BBPATH=$MAGISKTMP/busybox
# The mountpoint of magisk.img
MOUNTPATH=$MAGISKTMP/img
# /data/adb/modules will be bind mounted here
$MAGISKTMP/modules
# The configuration used in last installation
$MAGISKTMP/config
# Mount mirrors for MagicMount
MIRRORDIR=$MAGISKTMP/mirror
# System mirror
SYSTEMMIR=$MIRRORDIR/system
$MIRRORDIR/system
# Vendor mirror, could be a symlink to $SYSTEMMIR/vendor
# if vendor is not a separate partition
VENDORMIR=$MIRRORDIR/vendor
# Mirror to magisk's persist binary directory
BINMIRROR=$MIRRORDIR/bin
$MIRRORDIR/vendor
# Database storing settings and root permissons
# Each user (in the case of multiuser) has a different path
MAGISKDB_MANAGER=$MAGISKTMP/db-<USER>/magisk.db
# Loop devices to mount ext4 images, the ending number will vary
MAGISKLOOP=$MAGISKTMP/block/loop<XX>
# Data mirror to workaround nosuid flag
$MIRRORDIR/data
```
### Paths in `/data`
Some binaries and files should be stored on non-volatile storages in `/data`. In order to prevent detection from crazy apps, everything has to be stored somewhere safe and undetectable in `/data`. The folder `/data/adb` was chosen because of the following advantages:
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:
- It is an existing folder on modern Android, so it cannot be used as an indication of the existence of Magisk.
- The permission of the folder is by default `700`, owner as `root`, so non-root processes are unable to enter, read, write the folder in any possible way.
- The folder is labeled with secontext `u:object_r:adb_data_file:s0`, and very few processes have the permission to do any interaction with that secontext.
- The folder is located in *Device encrypted storage*, so it is accessible as soon as data is properly mounted in FBE (File-Based Encryption) devices.
There are some drawbacks though (only applies to FBE setups):
- Since the folder is encrypted, it is inaccessible in custom recoveries without any form of decryption (very rare case but still exists).
- FBE is very finicky. If you wiped `/data` in TWRP (which wipes all encryption) and manually create folders that are meant to be encrypted without special treatment, it will result in bootloop.
The solution of both situations above is to use `/data/magisk` when `/data/adb` does not exist. Magisk will handle migration at boot and properly setup the files to the expected location.
```
SECURE_DIR=/data/adb
# Folder storing scripts that should be executed in post-fs-data mode
POSTFSDATA_DIR=$SECURE_DIR/post-fs-data.d
# Folder storing general post-fs-data scripts
$SECURE_DIR/post-fs-data.d
# Folder storing scripts that should be executed in service mode
SERVICE_DIR=$SECURE_DIR/service.d
# Folder storing general late_start service scripts
$SECURE_DIR/service.d
# Magisk image, storing modules
MAINIMG=$SECURE_DIR/magisk.img
# Magisk modules
$SECURE_DIR/modules
# The image to store updated modules when installing
# in Magisk Manager since contents in $MAINIMG are not
# safe to be modified live. This image will be merged to
# $MAINIMG in the next reboot
MERGEIMG=$SECURE_DIR/magisk_merge.img
# Magisk modules that are pending for upgrade
# Module files are not safe to be modified when mounted
# Modules installed in Magisk Manager 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
# This file will be bind mounted to $MAGISKDB_MANAGER
MAGISKDB=$SECURE_DIR/magisk.db
# All magisk related binaries, containing busybox,
@ -83,13 +68,8 @@ MAGISKDB=$SECURE_DIR/magisk.db
# This folder will be bind mounted to $BINMIRROR
DATABIN=$SECURE_DIR/magisk
# The location to store simple_mount files
SIMPLEMOUNT=$SECURE_DIR/magisk_simple
```
### Paths in `$MAINIMG`
Each folder in `$MAINIMG` is a Magisk module. There used to be a folder `.core`, which is no longer used since v18.0.
### Final Words
The file structure of Magisk is designed in a weird and overly complicated way. But all of these quirks are done to properly support hiding modifications from detection. These design choices are mostly what makes Magisk difficult to implement properly and maintain.
@ -97,13 +77,15 @@ The file structure of Magisk is designed in a weird and overly complicated way.
### Pre-Init
`magiskinit` will replace `init` as the first program to run. It is responsible for constructing rootfs on system-as-root devices: it parses kernel cmdline, sysfs, device tree fstabs, uevents etc., recreating **early-mount** and clones rootfs files from the system. On traditional devices, it will simply revert `init` to the original one and continue on to the following steps.
It then extracts `init.magisk.rc` and inject imports in `init.rc` for additional startup services, extracts `magisk` to `/sbin`, compile split sepolicy and patch `init` to always load `/sepolicy` instead of other sources (only on Treble devices), and patches `/sepolicy` with the additional rules. Finally, it will execute the original `init` to start the ordinary boot process.
### Startup
This triggers on `post-fs-data` when `/data` is properly decrypted (if required) and mounted. The command `/sbin/magisk --starup` is executed by `init`. The startup stage will remove all traces of Magisk in ramdisk, and do the extremely complicated initialization for sbin tmpfs overlay. After the setup is done, it will execute `/sbin/magisk --post-fs-data` to switch to the `magisk` binary located in `tmpfs` and start "post-fs-data" mode.
- Inject magisk services into `init.rc`
- Load sepolicy either from `/sepolicy`, precompiled sepolicy in vendor, or compile split sepolicy
- Patch sepolicy rules and dump to `/sepolicy` and patch `init` to always load `/sepolicy`
- Fork a new daemon and wait for early-init trigger
- Execute the original `init` to start the ordinary boot process
- The early-init daemon will construct `/sbin` `tmpfs` overlay and remove all traces of Magisk in ramdisk
### post-fs-data
In this mode, the daemons, `magiskd` and `magisklogd`, will be launched. `$MAINIMG` is resized / merged and mounted to `$MOUNTPOINT`, post-fs-data scripts are executed, and module files are magic mounted.
This triggers on `post-fs-data` when `/data` is properly decrypted (if required) and mounted. The daemon `magiskd` will be launched, post-fs-data scripts are executed, and 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, service scripts are executed, and it will try to install Magisk Manager if it doesn't exist.
@ -125,11 +107,6 @@ There is one additional trick you can use: if you place an empty file named `.re
If you want to replace files in `/vendor`, please place it under `$MODPATH/system/vendor`. Magisk will transparently handle both cases, whether vendor is a separate partition or not.
## Simple Mount
**(Note: this implementation is and will not be fully tested, your mileage may vary)**
Some files might have to be mounted earlier in the boot process like bootanimations. To replace it with Magisk, all you need to do is simply place the modified file into the corresponding path under `$SIMPLEMOUNT`. For example, your goal is to replace `/system/media/bootanimation.zip`; you only need to copy the new zip to `$SIMPLEMOUNT/system/media/bootanimation.zip` and you're done! Magisk will clone all the attributes from the target file to your replaced file before bind mounting, so you don't need to worry about it.
## Miscellaneous
Here are some tidbits in Magisk but unable to be categorized into any sections:

View File

@ -47,7 +47,7 @@ Note that to install TWRP, you will first download the TWRP recovery image, and
Be aware you are flashing to `ramdisk`, not `boot`!
### EMUI 9
For EMUI 9 devices, the `ramdisk` partition no longer exists. As a workaround, Magisk will be installed to the `recovery_ramdisk` partition. **This means that you HAVE TO boot to recovery every time you reboot. This also means that you CANNOT have Magisk and custom recoveries at the same time!** To boot to recovery, press **Power + Volume Up** when booting your device.
For EMUI 9 devices, the `ramdisk` partition no longer exists. As a workaround, Magisk will be installed to the `recovery_ramdisk` partition. **This means that you HAVE TO boot to recovery every time you reboot.** To boot to recovery, press **Power + Volume Up** when booting your device.
- If you plan to use custom recoveries, simply follow the instructions for custom recovery above.
Note that to install TWRP, you will first download the TWRP recovery image, and use
@ -56,3 +56,4 @@ Note that to install TWRP, you will first download the TWRP recovery image, and
- If you plan not to use custom recoveries, you will have to extract `RECOVERY_RAMDIS.img` from your firmware. Follow the instructions for boot image patching above, but use the `RECOVERY_RAMDIS.img` file instead of a boot image. To install the patched image back to your device, here is the fastboot command:
`fastboot flash recovery_ramdisk /path/to/patched_boot.img`.
Be aware you are flashing to `recovery_ramdisk`, not `boot` nor `ramdisk`!
- You can still install custom recoveries to the `erecovery_ramdisk` partition. Boot to erecovery mode to boot into custom recovery in this case