Principe d'implémentation interne de Magisk

insérez la description de l'image ici

Après Android10, le système Android restreint la modification de la partition système.Le résultat est que même si vous compilez le système Android vous-même, même si vous avez des privilèges root élevés, vous ne pouvez toujours pas monter la partition système et modifier son contenu.Il existe plusieurs messages qui disent qu'il peut être utilisé mount -o rw,remount /, mais cela ne résout pas le vrai problème du développeur. Cela signifie que la racine universelle traditionnelle a des limites.Afin de résoudre ce problème, l'auteur de Magisk a confirmé ce problème Top John Wudans un tweet , et a confirmé que la cause du problème est que Google l'a introduit après Android 10 EXT4 共享块, et ce bloc partagé et autres partitions La différence est qu'il n'y a pas du tout de concept d'espace libre, il n'y a donc aucun moyen de le bloquer en lecture et en écriture. Afin de résoudre ce problème, l'équipe Magisk a découvert que le chemin du fichier lors de la lecture du fichier peut être redirigé pour atteindre l'objectif de modification, ce qui semble être similaire à notre crochet, et cela s'appelle Systemless (pas de partition système) Top John Wuet ce concept La solution racine étendue est également appelée racine sans système. .

Structure du fichier Magisk

Le système Magisk comprend le logiciel de contrôle de niveau supérieur, les fichiers binaires exécutables de niveau inférieur et certains fichiers de configuration ou de données associés. Il nous sera plus facile de comprendre la composition fonctionnelle et la pensée architecturale de Magisk de bas en haut.

Tout d'abord, Magisk montera un répertoire tmpfs pour stocker des données temporaires. Sous Android 11, ce répertoire est sbin. À partir d'Android 11, le dossier /sbin peut ne pas exister, donc Magisk créera au hasard un dossier sous /dev et l'utilisera comme dossier racine de Magisk.

La raison de le placer sous sbin ou dev est la suivante : le répertoire /sbin ou /dev est illisible sans l'autorisation su, les applications tierces ne peuvent donc pas le détecter.

magisk --pathNous pouvons imprimer le répertoire actuellement utilisé par Magisk en utilisant le shell adb :

Trouver le répertoire magisk

blueline:/ # magisk --path
/dev/bNpnxq

Liste de fichiers

Ensuite, regardons quels fichiers se trouvent dans ce répertoire et comment les interpréter ;

blueline:/dev/bNpnxq # ls -al
total 720
drwx------  3 root    root       200 2022-12-24 21:41 .
drwxr-xr-x 24 root    root      6200 2022-12-25 01:40 ..
drwxr-xr-x  8 root    root       180 2022-12-24 21:41 .magisk
lrwxrwxrwx  1 root    root        10 1970-02-17 10:04 magisk -> ./magisk64
-rwxr-xr-x  1 root    root    154452 1970-02-17 10:04 magisk32
-rwxr-xr-x  1 root    root    247168 1970-02-17 10:04 magisk64
-rwxr-xr-x  1 u0_a206 u0_a206 328240 2022-12-24 21:41 magiskpolicy
lrwxrwxrwx  1 root    root         8 1970-02-17 10:04 resetprop -> ./magisk
lrwxrwxrwx  1 root    root         8 1970-02-17 10:04 su -> ./magisk
lrwxrwxrwx  1 root    root        14 1970-02-17 10:04 supolicy -> ./magiskpolicy

On peut voir qu'à l'exception de magiskpolicy, d'autres appartiennent au groupe d'utilisateurs root.

Les commentaires ci-dessous sont très clairs, il suffit de regarder directement le code.

# 想要获取 Magisk 正在使用的当前Base文件夹,请使用命令 `magisk --path`。
# 像 magisk、magiskinit 这样的二进制文件和所有指向小程序的符号链接都直接存储在这个路径中。 
# 这意味着当这是 /sbin 时,这些二进制文件将直接位于 PATH 中。
MAGISKBASE=$(magisk --path)

# Magisk 内部文件
MAGISKTMP=$MAGISKBASE/.magisk

# Magisk 的 BusyBox 目录。 
# 在此文件夹中存储 busybox 二进制文件和指向其所有小程序的符号链接。 
# 此目录的任何用法已弃用,请直接调用 /data/adb/magisk/busybox 并使用 BusyBox 的 ASH 独立模式。
# 将来会删除此路径的创建。
$MAGISKTMP/busybox

# /data/adb/modules 将mount在这里。 原始文件夹未被使用(由于 nosuid 挂载标志)。
$MAGISKTMP/modules

# 当前的 Magisk 安装配置
$MAGISKTMP/config

# 分区镜像
# 应用在访问系统文件的时候会优先访问该目录下的文件,以达到狸猫换太子的目的
# 例如 system,system_ext,vendor,data......
$MAGISKTMP/mirror

# Magisk 内部创建block设备来挂载镜像,和mirror对应,对应关系可通过ls -al列出
$MAGISKTMP/block

# Root 目录补丁文件
# 位于 system-as-root 设备上,/ 不可写。
# 所有预初始化补丁文件都放在这里并mount
$MAGISKTMP/rootdir

Voici /dev/bNpnxq/.magisk/mirrorla liste des fichiers répertoriés, correspondant au nœud de périphérique du bloc

blueline:/dev/bNpnxq/.magisk/block # ls -al
total 0
d--------- 2 root root      160 2022-12-24 21:41 .
drwxr-xr-x 8 root root      180 2022-12-24 21:41 ..
brw------- 1 root root 253,   8 2022-12-24 21:41 data
brw------- 1 root root 259,   4 1970-02-17 10:04 metadata
brw------- 1 root root 253,   7 2022-12-24 21:41 product
brw------- 1 root root 253,   5 2022-12-24 21:41 system_ext
brw------- 1 root root 253,   4 2022-12-24 21:41 system_root
brw------- 1 root root 253,   6 2022-12-24 21:41 vendor
blueline:/dev/bNpnxq/.magisk/block # cd ../mirror/
blueline:
####################################
/dev/bNpnxq/.magisk/mirror # ls -al
total 24
d---------  7 root   root    220 2022-12-24 21:41 .
drwxr-xr-x  8 root   root    180 2022-12-24 21:41 ..
drwxrwx--x 50 system system 4096 2022-12-24 21:41 data
lrwxrwxrwx  1 root   root      9 2022-12-24 21:41 metadata -> /metadata
lrwxrwxrwx  1 root   root     19 2022-12-24 21:41 persist -> /mnt/vendor/persist
drwxr-xr-x 14 root   root   4096 2009-01-01 08:00 product
lrwxrwxrwx  1 root   root     17 1970-02-17 10:04 sepolicy.rules -> ./metadata/magisk
lrwxrwxrwx  1 root   root     20 2022-12-24 21:41 system -> ./system_root/system
drwxr-xr-x  9 root   root   4096 2009-01-01 08:00 system_ext
drwxr-xr-x 26 root   root   4096 2009-01-01 08:00 system_root
drwxr-xr-x 20 root   shell  4096 2009-01-01 08:00 vendor

Configuration et modules (répertoire /data/adb)

Ne soyez pas confus par le nom du répertoire. Bien que adb soit en fait un répertoire d'application de Magisk, certains fichiers de données et de configuration de Magisk sont stockés dans ce répertoire, et les modules installés sont également stockés ici. La raison pour laquelle l'utilisation de ce répertoire a son avantages de :

  • Ce répertoire existe pour tout appareil fabriqué en usine et les applications tierces ne peuvent pas détecter Magisk en fonction de celui-ci.
  • L'autorisation par défaut de ce répertoire est 700 et le propriétaire est root, de sorte que les applications tierces ne peuvent pas entrer, lire et écrire.
  • Le contexte de sécurité de ce répertoire est u:object_r:adb_data_file:s0, que peu de processus possèdent.
  • Ce répertoire se trouve dans le stockage Device Encrypted (DE), il peut donc être utilisé lorsque le périphérique FBE (File-Based Encryption) est en mode de démarrage direct ou après avoir déverrouillé l'écran de verrouillage.

Ce répertoire contient les fichiers suivants (il est plus facile à comprendre avec le processus de démarrage de Magisk) :

SECURE_DIR=/data/adb

# 存储一些 post-fs-data 后需要执行的脚本的文件夹
$SECURE_DIR/post-fs-data.d

# 存放通用 late_start 服务脚本的文件夹
$SECURE_DIR/service.d

# Magisk 模块目录
$SECURE_DIR/modules

# 待升级的 Magisk 模块
# 因为模块文件在挂载时修改是不安全的
# 通过 Magisk 应用程序安装的模块将存储在这里,并在下次重启时合并到 $SECURE_DIR/modules
$SECURE_DIR/modules_update

# 数据库存储应用设置和root授权日志
MAGISKDB=$SECURE_DIR/magisk.db

# 所有与 magisk 相关的二进制文件,包括 busybox、scripts和 magisk 二进制文件。 用于支持模块安装、addon.d、Magisk应用程序等。
DATABIN=$SECURE_DIR/magisk

Processus de démarrage de Magisk

Le démarrage de Magisk est divisé en les étapes suivantes : Pre-Init, post-fs-data, late_start, Resetprop, ces processus de démarrage nous pouvons correspondre au démarrage du système Android, laissez-moi vous expliquer en détail ci-dessous :

Étape de pré-initialisation

Remplacez init par magiskinit et exécutez :

  • Montez d'abord la partition souhaitée. Sur un périphérique système traditionnel en tant que racine, basculez root sur /system ; sur un périphérique 2SI (en utilisant sans système), redirigez le fichier init vers magiskinit et exécutez-le (le principe est que nous redirigerons l'init d'origine lors de l'étape de démarrage du patch) pour monter la partition souhaitée.
  • Injecter le service magisk dans init.rc
  • Pour les appareils utilisant des politiques de sécurité monolithiques (globales), lisez la politique de sécurité à partir de /sepolicy ; pour les autres appareils, utilisez FIFO pour détourner les nœuds selinuxfs, définissez LD_PRELOAD pour accrocher security_load_policy et aidez au piratage des appareils 2SI, et démarrez le démon jusqu'à ce que init essaie de lire sepolicy.
  • Règles de sepolicy des correctifs. Si vous utilisez la méthode "hijacking", chargez la sepolicy corrigée dans le noyau, puis relâchez le piratage init et quittez le démon.
  • Exécutez l'initialisation d'origine pour effectuer le processus de démarrage suivant

étape post-fs-data

post-fs-dataLe processus est déclenché après le déchiffrement et le montage de /data. Tout d'abord, le processus démon sera démarré magiskdet post-fs-datale script sera exécuté. A ce moment, le fichier du module sera monté.

stade late_start

Plus tard dans le processus de démarrage, la classe late_start est déclenchée pour démarrer le mode "service" de Magisk. Les scripts de service seront exécutés dans ce mode.

À ce stade, Magisk est entièrement démarré, et ce qui précède est l'application. Il n'est responsable que de certaines modifications de configuration et de l'affichage de l'état, et appelle les services et programmes précédemment démarrés à exécuter. C'est probablement le processus.

Modifier les propriétés (Resetprop)

Normalement, seul init peut modifier les propriétés du système, et les processus non root peuvent uniquement lire et ne peuvent pas modifier. Lorsqu'il y a root, vous pouvez envoyer une requête via le property_service fourni par init (par exemple, adb peut utiliser la commande setprop) pour effectuer la modification, mais vous ne pouvez pas modifier et supprimer les propriétés en lecture seule (propriétés commençant par ro., telles que ro.build. product), sauf si le code source du système est modifié.

resetprop permet de modifier directement la propriété area (prop_area) en extrayant et patchant le code source lié à la propriété système dans AOSP, et n'a plus besoin de modifier la propriété système via property_service (en fait, cette fonction est similaire au principe de la mprop open source sur Github). Cependant, c'est précisément parce que property_service est contourné que les précautions suivantes sont nécessaires :

  • Correctif pour les événements déclencheurs : étant donné que property_service est contourné, l'événement d'action on property:foo=bar enregistré dans le script *.rc ne sera pas déclenché lorsque la propriété change (c'est ce qu'on appelle un déclencheur de propriété dans le langage init). Mais Mgisk a pris cela en considération, donc par défaut resetprop sera le même que setprop lors de la définition d'une propriété, et il déclenchera un événement (en supprimant d'abord la propriété, puis en définissant la propriété via property_service). Si vous ne souhaitez pas déclencher d'événements d'action, vous pouvez utiliser le paramètre -n pour le désactiver.

  • L'implémentation conserve également les modifications après le redémarrage : les propriétés persistantes (les propriétés commençant par persist., telles que persist.sys.usb.config) sont stockées à la fois dans prop_area et dans /data/property. Par défaut, lors de la suppression d'une propriété persistante, elle ne sera pas supprimée du stockage persistant, ce qui signifie que la propriété persistante sera restaurée au prochain redémarrage ; getprop ne lira pas la propriété persistante du stockage persistant. Mais pour resetprop, vous pouvez utiliser le paramètre -p , de sorte que lors de la suppression, la propriété sera supprimée de prop_area et /data/property en même temps, et lors de la lecture, elle sera également lue à partir de prop_area et du stockage persistant.

Politique SELinux

Magisk garantit que les opérations Magisk peuvent être effectuées en toute sécurité en corrigeant la sepolicy d'origine. Le nouveau domaine magisk est hautement privilégié, et magiskd et tous les shells root s'exécuteront dans ce domaine. magisk_file est un nouveau type de fichier qui permet l'accès par domaine (contexte de fichier illimité), et le fichier magisk suivant utilise le contexte magisk_file.

blueline:/data/adb # ls -Zl
total 52
drwxr-xr-x 3 root root u:object_r:magisk_file:s0     3488 2022-12-24 21:41 magisk
-rw------- 1 root root u:object_r:adb_data_file:s0  40960 2022-12-27 02:22 magisk.db
drwxr-xr-x 2 root root u:object_r:system_file:s0     3488 2022-12-24 21:41 modules
drwxr-xr-x 2 root root u:object_r:adb_data_file:s0   3488 2022-12-24 21:41 post-fs-data.d
drwxr-xr-x 2 root root u:object_r:adb_data_file:s0   3488 2022-12-24 21:41 service.d

Avant Android 8.0, tous les domaines clients activés par su pouvaient se connecter directement à magiskd et se connecter au démon pour obtenir un accès distant au shell racine. Magisk doit également publier certains ioctls pour que le shell racine fonctionne correctement.

Cependant, dans Android 8.0 et versions ultérieures, afin d'éviter l'assouplissement des règles dans le bac à sable Android, Magisk implémente un nouveau modèle SELinux. les binaires magisk sont marqués avec le type de fichier magisk_exec, et les processus exécutant les binaires magisk (y compris la commande su) lors de l'exécution dans le domaine du client su sont transférés vers magisk_client (en utilisant une règle type_transition).

Les règles limitent strictement les processus du domaine magisk pour être autorisés à appartenir au type de fichier magisk_exec. Les connexions socket directes à magiskd ne sont plus autorisées ; le seul moyen d'accéder au démon est via un processus magisk_client. Cela garantit l'intégrité du bac à sable, en séparant les règles spécifiques à Magisk des autres règles. Magisk64 comme suit :

blueline:/dev/bNpnxq # ls -lZ
total 720
lrwxrwxrwx 1 root    root    u:object_r:system_file:s0                            10 1970-02-17 10:04 magisk -> ./magisk64
-rwxr-xr-x 1 root    root    u:object_r:system_file:s0                        154452 1970-02-17 10:04 magisk32
-rwxr-xr-x 1 root    root    u:object_r:magisk_exec:s0                        247168 1970-02-17 10:04 magisk64
-rwxr-xr-x 1 u0_a206 u0_a206 u:object_r:app_data_file:s0:c206,c256,c512,c768  328240 2022-12-24 21:41 magiskpolicy
lrwxrwxrwx 1 root    root    u:object_r:system_file:s0                             8 1970-02-17 10:04 resetprop -> ./magisk
lrwxrwxrwx 1 root    root    u:object_r:system_file:s0                             8 1970-02-17 10:04 su -> ./magisk
lrwxrwxrwx 1 root    root    u:object_r:system_file:s0                            14 1970-02-17 10:04 supolicy -> ./magiskpolicy

Des règles plus détaillées peuvent magiskpolicy/rules.cppêtre trouvées dans .

Je suppose que tu aimes

Origine blog.csdn.net/zhonglunshun/article/details/128791807
conseillé
Classement