Wie funktioniert Magisk?

Magisk ist als „systemlose“ Root-Methode bekannt. Es ist im Wesentlichen eine Möglichkeit, das System zu modifizieren, ohne es tatsächlich zu modifizieren. Änderungen werden sicher in der Boot-Partition gespeichert, anstatt die echten Systemdateien zu ändern.

Ich habe mich umgesehen, aber keine ausreichende Erklärung dafür gefunden, wie es tatsächlich funktioniert. Wie wird der Root-Zugriff erlangt und aufrechterhalten? Was genau ist die Rolle der Boot-Partition und wenn sie sich in die Systempartition integriert, wie macht sie das?

Eine wirklich detaillierte Beschreibung, wie es funktioniert, fehlt überall, wo ich gesucht habe, also wäre es wirklich sehr zu schätzen.

Antworten (2)

Der größte Teil Ihrer Frage wird in der Magisk-Dokumentation behandelt . Ich werde eine meiner vorherigen Antworten auf eine andere Frage mit einigen unnötigen Details zitieren :)

VORAUSSETZUNGEN:

Um ein umfassendes Verständnis der Funktionsweise von Magisk zu haben, muss man grundlegende Kenntnisse über Folgendes haben:

  • Discretionary Access Control ( DAC )
  • Benutzerkennungen ( [ESR]UID),set-user-ID
  • Linux-Fähigkeiten (Prozess und Datei), die eine feinkörnige Kontrolle über Superuser-Berechtigungen bieten
  • Obligatorische Zugangskontrolle ( MAC )
  • SELinux auf Android
  • Namespaces bereitstellen, Androids Verwendung von Namespaces für Speicherberechtigungen
  • Halterung binden
  • Android-Startvorgang, Partitionen und Dateisysteme
  • Android init-Dienste (der allererste Prozess, der vom Kernel gestartet wird)
  • *.rc-Dateien
  • Partitionsstruktur boot(Kernel + DTB + Ramdisk), Device Tree Blobs , DM-Verity ( Android Verified Boot ), Full Disk Encryption / File Based Encryption ( FDE/FBE ) etc.

WAS IST ROOT?

Das Erlangen von Root-Rechten bedeutet, einen Prozess (normalerweise Shell) mit UID Null (0) und allen Linux-Fähigkeiten auszuführen, sodass der privilegierte Prozess alle Kernel-Berechtigungsprüfungen umgehen kann.
Superuser-Privilegien werden normalerweise durch Ausführen einer Binärdatei erlangt, die entweder:

So funktioniert suund sudofunktioniert unter Linux im traditionellen UNIX-DAC. Nicht privilegierte Benutzer führen diese Binärdateien aus, um Root-Rechte zu erhalten.

Dies ist die seltener verwendete Methode.

In beiden Fällen muss der aufrufende Prozess alle Capabilities in seinem Bounding Set haben (eine der 5 Capability-Kategorien, die ein Prozess haben kann), um echte Root-Privilegien zu haben.

WIE SCHRÄNKT ANDROID DEN ROOT-ZUGRIFF EIN?

Bis Android 4.3 konnte man einfach eine set-user-ID-root suBinärdatei ausführen, um seine Berechtigungen auf den Root-Benutzer zu erhöhen. Es gab jedoch eine Reihe von Sicherheitsverbesserungen in Android 4.3 , die dieses Verhalten unterbrachen:

  • Android hat auf Dateifunktionen umgestellt, anstatt sich auf die set-user-IDArt der Sicherheitslücken zu verlassen. Ein sichererer Mechanismus: Umgebungsfunktionen wurden auch in Android Oreo eingeführt.
  • System-Daemons und -Dienste können Dateifähigkeiten nutzen, um Prozessfähigkeiten zu erlangen (siehe unter Umwandlung von Fähigkeiten während der Ausführung ), aber Apps können dies auch nicht, weil Anwendungscode mit dem zygoteProzesssteuerungsattribut ausgeführt wird NO_NEW_PRIVS, set-user-IDwobei die Dateifähigkeiten ignoriert werden. SUID wird auch beim Mounten /systemund /datamit nosuidOption für alle Apps ignoriert.
  • Die UID kann nur umgeschaltet werden, wenn der aufrufende Prozess die SETUID/SETGID- Fähigkeit in seinem Begrenzungssatz hat. Android-Apps sind jedoch so konzipiert, dass sie mit allen Funktionen ausgeführt werden, die bereits in allen Sätzen mithilfe des Prozesssteuerungsattributs enthalten sind CAPBSET_DROP.
  • Beginnend mit Oreo wurde die Fähigkeit von Apps, UID/GID zu ändern, weiter unterdrückt, indem bestimmte Syscalls mit seccomp-Filtern blockiert wurden .

Da die eigenständigen suBinärdateien mit der Veröffentlichung von Jelly Bean nicht mehr funktionierten, wurde auf den su-Daemon-Modus umgestellt . Dieser Daemon wird während des Bootens gestartet und verarbeitet alle Superuser-Anforderungen, die von Anwendungen gestellt werden, wenn sie die spezielle suBinärdatei ( 1 ) ausführen . install-recovery.sh(befindet sich unter /system/bin/oder /system/etc/), der von einem vorinstallierten Init-Dienst ausgeführt wird flash_recovery(für Abenteurer nutzlos; Aktualisierungswiederherstellung nach einer OTA-Installation), wurde verwendet, um diesen SU-Daemon beim Booten zu starten.

Die nächste große Herausforderung stand bevor, als SELinux enforcingmit der Veröffentlichung von Android 5.0 streng eingestellt wurde. Der flash_recovery- Dienst wurde einem eingeschränkten SELinux-Kontext hinzugefügt : u:r:install_recovery:s0wodurch der unverfälschte Zugriff auf das System gestoppt wurde. Sogar die UID 0 war verpflichtet, eine sehr begrenzte Anzahl von Aufgaben auf dem Gerät auszuführen. Die einzige praktikable Option war also, einen neuen Dienst mit uneingeschränktem SUPER CONTEXT zu starten , indem die SELinux-Richtlinie gepatcht wurde. Das wurde gemacht (vorübergehend für Lollipop ( 2 , 3 ) und dann dauerhaft für Marshmallow) und das macht Magisk.

WIE MAGISK FUNKTIONIERT?

Das Flashen von Magisk erfordert normalerweise ein Gerät mit entsperrtem Bootloader, damit es boot.imgdynamisch von der benutzerdefinierten Wiederherstellung ( 4 ) geändert werden kann , oder ein vorab geändertes boot.img ( 5 ) kann geflasht/gebootet werden, z. B. von fastboot.
Als Randnotiz ist es möglich, Magisk auf einem laufenden ROM zu starten, wenn Sie irgendwie Root-Rechte erhalten, indem Sie einen Exploit in OS ( 6 ) verwenden . Die meisten dieser Sicherheitslücken wurden jedoch im Laufe der Zeit behoben ( 7 ) .
Auch aufgrund einiger Schwachstellen auf SoC-Ebene (z. B. Qualcomms EDL-Modus ) kann ein gesperrter Bootloader gehackt werden, um ein modifiziertes Boot-/Wiederherstellungs-Image zu laden, das das beschädigtKette des Vertrauens . Dies sind jedoch nur Ausnahmen.

Sobald das Gerät von gepatcht gestartet wird boot.img, wird ein voll privilegierter Magisk-Daemon (mit UID: 0, vollen Funktionen und uneingeschränktem SELinux-Kontext) von Anfang an des Startvorgangs ausgeführt. Wenn eine App Root-Zugriff benötigt, führt sie die Binärdatei von Magisk aus (/sbin/)su(weltweit zugänglich über DAC und MAC ), die die UID/GID nicht selbst ändert, sondern sich einfach über einen UNIX-Socket ( 8 ) mit dem Daemon verbindet und nach der Anfrage fragt app eine Root-Shell mit allen Fähigkeiten. Um mit dem Benutzer zu interagieren, um suAnfragen von Apps zu gewähren/zu verweigern, ist der Daemon mit der Magisk ManagerApp verbunden, die Eingabeaufforderungen der Benutzeroberfläche anzeigen kann. /data/adb/magisk.dbDer Daemon erstellt eine Datenbank ( ) mit erteilten/verweigerten Berechtigungen für die zukünftige Verwendung.

Bootvorgang:
Der Android-Kernel startet beim Booten initmit SELinux im permissiveModus (mit wenigen Ausnahmen ). initlädt /sepolicy(oder split policy ), bevor Dienste/Daemons/Prozesse gestartet werden, setzt sie enforcingund wechselt dann zu ihrem eigenen Kontext. Von hier aus initist es nach der Richtlinie nicht einmal erlaubt, in den zulässigen Modus zurückzukehren ( 9 , 10 ) . Auch die Richtlinie kann nicht einmal vom Root-Benutzer ( 11 ) geändert werden . Daher ersetzt Magisk /initdie Datei durch eine benutzerdefinierte Datei init, die die SELinux-Richtlinienregeln mit SUPER CONTEXT ( u:r:magisk:s0) patcht und die definiertDienst , um den Magisk-Daemon mit diesem Kontext zu starten. Dann wird das Original initausgeführt, um den Bootvorgang fortzusetzen ( 12 ) .

Systemloses Arbeiten:
Da die initDatei eingebaut ist boot.img, ist eine Änderung unvermeidlich und /systemeine Änderung wird unnötig. Dort systemlesswurde der Begriff geprägt ( 13 , 14 ) . Hauptanliegen war es, OTAs einfacher zu machen - das erneute Flashen des bootImages (und die Wiederherstellung) ist weniger mühsam als das erneute Flashensystem . Blockbasiertes OTA auf einer modifizierten /systemPartition schlägt fehl, da es die Verwendung von dm-verityzum kryptografischen Signieren der systemPartition ermöglicht .

System-as-root:
Auf neueren Geräten, die System-as-root verwenden , lädt der Kernel nicht ramdiskvon boot, sondern von system. Muss also [system.img]/initdurch Magisk ersetzt werden init. Auch Magisk modifiziert /init.rcund platziert seine eigenen Dateien in /rootund /sbin. Es bedeutet system.img, dass es geändert werden muss, aber der Ansatz von Magisk besteht darin, systemdie Partition nicht zu berühren.

Auf A/BGeräten während des normalen Starts skip_initramfswird die Option vom Bootloader in der Kernel-Cmdline übergeben, wie sie für die Wiederherstellung boot.imgenthalten ist ramdisk. Magisk patcht also die Kernel-Binärdatei, um das Booten in der Wiederherstellung immer zu ignorieren skip_initramfs, und platziert die Magisk- initBinärdatei in der Wiederherstellung ramdiskin boot.img. Beim Booten, wenn der Kernel zur Wiederherstellung bootet, wenn es keinen skip_initramfsBenutzer gibt, der absichtlich zur Wiederherstellung gebootet wurde, führt Magisk initeinfach recovery aus init. Andernfalls wird at von Magisk system.imggemountet , der Inhalt von wird dann kopiert, um alles zuvor Vorhandene zu bereinigen, Dateien werden in rootfs hinzugefügt/geändert , in gebunden gemountet und schließlich ausgeführt (/system_rootinitramdisk///system_root/system/system[/system]/init15 , 16 ) .

Allerdings haben sich die Dinge mit Q wieder geändert, jetzt /systemwird bei gemountet, /aber die hinzuzufügenden/zu ändernden Dateien wie /init, /init.rcund werden mit bind mounts ( 17 )/sbin überlagert .

Auf non-A/B system-as-rootGeräten muss Magisk zur Wiederherstellung installiert werden, ramdiskum den systemlosen Ansatz beizubehalten, da boot.imges keine ramdisk ( 18 ) enthält .

Module:
Ein zusätzlicher Vorteil des systemlessAnsatzes ist die Verwendung von Magisk Modules. Wenn Sie einige Binärdateien unter platzieren /system/*bin/oder einige Konfigurationsdateien (wie hostsoder dnsmasq.conf) oder einige Bibliotheken/Framework-Dateien (wie sie von Mods wie benötigt werden XPOSED) in /systemoder ändern möchten, können Sie dies tun, ohne die Partition tatsächlich zu berühren, indem Sie Magic Mount/vendor verwenden ( basierend auf Bindungshalterungen). Magisk unterstützt sowohl das Hinzufügen als auch das Entfernen von Dateien, indem es sie überlagert.

MagiskHide: ( 19 )
Eine weitere Herausforderung bestand darin, das Vorhandensein von Magisk zu verbergen, damit Apps nicht wissen können, ob das Gerät gerootet ist. Viele Apps mögen gerootete Geräte nicht und funktionieren möglicherweise nicht mehr. Google war einer der Hauptbetroffenen, also haben sie SafetyNet als Teil von Play Protect eingeführt , das als GMS (Play Services)-Prozess läuft und Apps (einschließlich ihrer eigenen Google Pay) und damit ihren Entwicklern mitteilt, dass das Gerät derzeit nicht manipuliert ist Zustand ( 20 ) .

Rooting ist einer der vielen möglichen temperierten Zustände, andere sind nicht verifizierter Boot, entsperrter Bootloader, CTS-Nichtzertifizierung, benutzerdefiniertes ROM, debugable Build, permissiveSELinux, ADB eingeschaltet, einige schlechte Eigenschaften, Vorhandensein von Lucky Patcher, Xposed usw. Magisk verwendet einige Tricks, um sicherzustellen, dass die meisten dieser Tests immer bestehen, obwohl Apps andere Android-APIs verwenden oder einige Dateien direkt lesen können. Einige Module bieten zusätzliche Verschleierung.

Abgesehen davon, dass Magisk seine Präsenz vor Googles SafeyNet verbirgt, können Benutzer mit Magisk auch root ( subinäre und alle anderen Magisk-bezogenen Dateien) vor jeder App verbergen, wobei wiederum Bind-Mounts und Mount-Namespaces verwendet werden. Dazu zygotemuss kontinuierlich nach neu geforkten VMs von Apps Ausschau gehalten werden.

Es ist jedoch eine schwierige Aufgabe, gerootete Geräte wirklich vor Apps zu verbergen, da sich neue Techniken entwickeln, um die Anwesenheit von Magisk zu erkennen, hauptsächlich von /procoder anderen Dateisystemen. Daher werden eine Reihe von Macken vorgenommen, um das Verstecken von Modifikationen vor der Erkennung richtig zu unterstützen . Magisk versucht, alle Spuren seiner Anwesenheit während des Bootvorgangs zu entfernen ( 21 ) .


Magisk unterstützt auch:

Das ist eine kurze Beschreibung der derzeit angebotenen Funktionen von Magisk (AFAIK).


WEITERLESEN:

Dies ist eine der am besten geschriebenen Antworten, die ich je hier gelesen habe. Nur eines: Was meinst du mit 'A/B-Geräten'? Ist dieser Begriff in einem der vorherigen Links erklärt?
@SteffenWinkler A/B-Geräte haben 2 Partitionsslots zum Booten: source.android.com/devices/tech/ota/ab
Faszinierend! Sollte Ihr erster Link hier sein?: topjohnwu.github.io/Magisk/details.html

Magisk bietet Root-Zugriff, indem es eine funktionierende „Root“-Binärdatei bereitstellt, die unter /sbin/magisk. Jede Anwendung, die versucht, diese Binärdatei auszuführen, ruft Magisk auf, um ihnen Root-Zugriff zu gewähren, der wiederum von der Magisk Manager-Anwendung verwaltet und gewartet wird.

Die /bootPartition ist eine separate Partition, die einige Daten speichert, die zum Booten des Systems erforderlich sind. Es umfasst die Initialisierung einiger Mechanismen auf sehr niedriger Ebene wie dem Linux-Kernel, Gerätetreibern, Dateisystemen usw., bevor das Android-Betriebssystem der oberen Schicht aufgerufen wird. Es ist so getrennt, dass Dinge auf Linux-Ebene darin gespeichert werden, während Dinge auf Android-Ebene (SystemUI, Einstellungen usw.) in der /systemPartition gespeichert werden. Das Modifizieren /bootzählt nicht als Modifizieren von/system , wobei letzteres normalerweise von DM-verity und AVB überprüft wird.

Und Magisk patcht und integriert sich in die /bootPartition , sodass es die Systempartition überhaupt nicht berührt. Es verwendet eine Technik namens "a bind mount" , um den Inhalt von Systemdateien zu ändern, die andere Programme sehen, ohne das zugrunde liegende Dateisystem unterhalb der Systempartition tatsächlich zu ändern (so dass "echte" Dateien intakt bleiben).