[機器翻譯]Magisk 開發人員指南

原始文章連結在此


Magisk

開發人員指南

Magisk 模組

Magisk 模組是放在 /data/adb/modules 中的資料夾,其結構如下:
/data/adb/modules
├── .
├── .
|
├── $MODID                  <--- 資料夾以模組的ID命名
│   │
│   │      *** 模組識別碼 ***
│   │
│   ├── module.prop         <--- 此檔案儲存模組的中繼資料
│   │
│   │      *** 主要內容 ***
│   │
│   ├── system              <--- 如果 skip_mount 不存在,將安裝此資料夾
│   │   ├── ...
│   │   ├── ...
│   │   └── ...
│   │
│   │      *** 狀態標誌 ***
│   │
│   ├── skip_mount          <--- 如果存在,Magisk 將不會掛載 System 資料夾
│   ├── disable             <--- 如果存在,該模組將被停用
│   ├── remove              <--- 如果存在,則在下次重新啟動時將模組移除
│   │
│   │      *** 可選檔案 ***
│   │
│   ├── post-fs-data.sh     <--- 該腳本將在 post-fs-data 中執行
│   ├── service.sh          <--- 此腳本將在 late_start 服務中執行
|   ├── uninstall.sh        <--- Magisk 刪除模組時將執行此腳本
│   ├── system.prop         <--- 此檔案中的屬性將由 resetprop 載入為系統屬性
│   ├── sepolicy.rule       <--- 要修補的其他自訂 Sepolicy 規則
│   │
│   │      *** 自動生成,請勿手動建立或修改 ***
│   │
│   ├── vendor              <--- $MODID/system/vendor 的符號連結
│   ├── product             <--- $MODID/system/product 的符號連結
│   │
│   │      *** 允許任何其他檔案/資料夾 ***
│   │
│   ├── ...
│   └── ...
|
├── another_module
│   ├── .
│   └── .
├── .
├── .

module.prop

module.prop 嚴格的格式
id=<string>
name=<string>
version=<string>
versionCode=<int>
author=<string>
description=<string>
  • id必須符合以下正規表示式:^[a-zA-Z][a-zA-Z0-9._-]+$
    例如:✓ a_module,✓ a.module,✓ module-101,✗ a module,✗ 1_module,✗ -a-module
    這是模組唯一識別碼。模組發佈後,您不應修改它。
  • versionCode 必須為整數這用於比較版本
  • 上面未提到的其他字串可以是任何單行字串。
  • 確保使用 UNIX (LF) 換行符類型,而不要使用 Windows (CR+LF) 或 Macintosh (CR)

Shell腳本(*.sh

請閱讀「Boot 腳本」部分,以了解 post-fs-data.sh 和 service.sh 之間的差異對於大多數模組開發人員來說,如果只需要執行啟動腳本,那麼 service.sh 應該足夠好。
在模組的所有腳本中,請使用 MODDIR=${0%/*} 來取得模組的基本目錄路徑。不要把腳本中的模組路徑寫死。

system.prop

該檔案採用與 build.prop 相同的格式。每行包含 [key]=[value]

sepolicy.rule

如果您的模組需要一些其他的分隔符修補程式,請將這些規則新增到此檔案中。模組安裝程式腳本和 Magisk 的守護行程將確保將此檔案複製到 magiskinit 可以讀取 pre-init 的位置,以確保正確插入這些規則。
該檔案中的每一行都將被視為策略宣告。要詳細了解政策宣告的格式,請查看 magiskpolicy 的檔案。

system 資料夾

您希望 Magisk 為您取代/插入的所有檔案都應放在此資料夾中。請閱讀「Magisk 掛載」部分,以了解 Magisk 如何掛載檔案。

Magisk 模組安裝程式

Magisk 模組安裝程式是打包在 zip 檔案中的 Magisk 模組,可以在 Magisk Manager 或第三方還原(如TWRP)中刷入。安裝程式與 Magisk 模組具有相同的檔案結構(請檢查上一部分以了解更多訊息)。最簡單的 Magisk Module Installer 只是一個打包為 zip 檔案的 Magisk Module,此外還包含以下檔案:
  • update-binary:下載最新的 module_installer.sh 並將該腳本重新命名/複製為 update-binary
  • updater-script:此檔案應僅包含字串 #MAGISK
預設情況下,update-binary 將檢查/設定環境,載入公用程式功能,將模組安裝程式 zip 解壓縮到將要安裝模組的位置,最後執行一些瑣碎的任務和清理工作,這些工作和清理應滿足大多數簡單模組的需求。
module.zip
│
├── META-INF
│   └── com
│       └── google
│           └── android
│               ├── update-binary      <--- 您下載的 module_installer.sh
│               └── updater-script     <--- 應該只包含“#MAGISK”字串
│
├── customize.sh                       <--- (多個選項,稍後會有更多詳細訊息)
│                                           該腳本將由 update-binary 來源
├── ...
├── ...  /* 模組的其餘檔案 */
|

客製化

如果您需要自訂模組安裝過程,則可以選擇在安裝程式中建立一個名為 customize.sh 的新腳本提取所有檔案並套用預設權限和安全性本文後,將透過腳本 update-binary 來源(不執行!)來生成該腳本如果您的模組包含基於 ABI 的其他檔案,或者您需要為某些檔案(例如 /system/bin 中的檔案設定特殊的權限/安全性本文,則此功能非常有用
如果您需要更多的自訂,並且希望自己做所有事情,請在 custom.sh 中宣告 SKIPUNZIP=1,以跳過提取操作並套用預設權限/安全性本文步驟。請注意,這樣做您的 custom.sh 將負責自行安裝所有內容。

customize.sh 環境

Magisk 的內部 busybox 路徑 $BBPATH 新增在的前面 PATH為了方便起見,可以使用以下變數和shell函數:
變數
  • MAGISK_VER(字串):目前安裝的 Magisk 的版本字串(例如 v20.0)
  • MAGISK_VER_CODE(整數):目前安裝的 Magisk 的版本代號(例如 20000)
  • BOOTMODE(布林):如果模組已安裝在 Magisk Manager 中,則回報 true
  • MODPATH (路徑):模組檔案的安裝路徑
  • TMPDIR (路徑):放置暫存檔案的地方
  • ZIPFILE (路徑):模組的 zip 安裝檔
  • ARCH(字串):裝置的 CPU 架構。值可以是 arm,arm64,x86,或 x64
  • IS64BIT(布林):如果 $ARCH 是 arm64 或 x64,則回報 true
  • API(整數):裝置的API層級(Android版本)(例如,21 對應於 Android 5.0)
功能
ui_print <訊息>
     列印 <訊息> 到 console
     避免使用“echo”,因為它不會顯示在第三方還原的 console 中 abort <訊息>
     列印錯誤訊息 <訊息> 到 console 並停止安裝
     避免使用“exit”,因為它會跳過停止安裝的清理動作
set_perm <目標> <擁有者> <群組> <權限> [context]      如果未設定 [context],則預設值為 "u:object_r:system_file:s0"      該函數是以下命令的簡寫: chown owner.group target chmod permission target chcon context target set_perm_recursive <目錄> <擁有者> <群組> <目錄權限> <檔案權限> [context]      如果未設定 [context],則預設值為 "u:object_r:system_file:s0"      對於 <目錄> 中的所有檔案,它將調用:
set_perm file owner group filepermission context      對於 <目錄> 中的所有目錄(包括自身),它將調用: set_perm dir owner group dirpermission context
容易更換
您可以在變數名稱 REPLACE 中宣告要直接取代的資料夾列表模組安裝程式腳本將提取此變數並為您建立 .replace 檔案。宣告範例:
REPLACE="
/system/app/YouTube
/system/app/Bloatware
"
上面的列表將導致建立以下檔案:$MODPATH/system/app/YouTube/.replace 和 $MODPATH/system/app/Bloatware/.replace

筆記

  • 使用 Magisk Manager 下載模組時,update-binary 強制用最新的 module_installer.sh 腳本取代舊有腳本,以確保所有安裝程式都使用最新的腳本。不要試圖在 update-binary 新增任何自訂邏輯,因為這毫無意義。
  • 由於歷史原因,請勿在模組安裝程式中新增名為 install.sh 的檔案該特定檔案先前已使用過,將被分別對待。
  • 不要在 custom.sh 的結尾調用 exit。 模組安裝程式將要完成

遞交模組

您可以將模組遞交給 Magisk-Module-Repo,以便使用者可以直接在 Magisk Manager 中下載您的模組。
  • 按照上一節中的說明為您的模組建立有效的安裝程式。
  • 建立 README.md(檔案名稱應該完全相同),包含模組的所有訊息。如果您不熟悉 Markdown 語法,那麼 Markdown 備忘單將很方便。
  • 使用您的個人 GitHub 帳戶建立儲存庫,然後將模組安裝程式上傳到儲存庫
  • 透過此連結建立遞交請求:遞交

模組技巧

刪除檔案

如何在不修改系統的前提下刪除檔案?實際使檔案消失很複雜(可能,不值得付出努力)。用偽檔案取代它應該已經足夠好了!建立一個具有相同名稱的空檔案,並將其放置在模組內的相同路徑中,它將用偽檔案取代您的目標檔案。

刪除資料夾

與上述相同,實際上使資料夾消失是不值得的。將其取代為空資料夾應該足夠了!對於模組開發人員來說,一個方便的技巧是將要刪除的資料夾新增到其中的REPLACE列表中customize.sh如果您的模組沒有提供相應的資料夾,它將建立一個空資料夾,並自動新增.replace到該空資料夾中,以便虛擬資料夾可以正確取代其中的一個/system

Boot 腳本

在 Magisk 中,您可以以兩種不同的模式執行啟動腳本:post-fs-data 模式和 late_start service 模式。
  • post-fs-data 模式
    • 這個階段是封鎖中。Boot過程在執行完成之前已暫停,或者已過10秒。
    • 腳本在安裝任何模組之前執行。這允許模組開發人員在安裝模組之前動態調整其模組。
    • 此階段發生在 Zygote 啟動之前,這幾乎意味著 Android 中的所有內容
    • 僅在必要時在此模式下執行腳本!
  • late_start service 模式
    • 此階段為非阻塞。您的腳本與 Boot 過程並行執行。
    • 建議執行大多數腳本的階段!
在 Magisk 中,還有兩種腳本:通用腳本模組腳本
  • 通用腳本
    • 放在 /data/adb/post-fs-data.d 或 /data/adb/service.d 中
    • 僅在腳本可執行時執行(執行權限,chmod +x script.sh
    • post-fs-data.d 中的腳本以 post-fs-data 模式執行,而 service.d 中的腳本以 late_start 服務模式執行。
    • 啟用僅核心模式時,仍將執行
    • 模組應該新增一般的腳本,因為它違反了封裝
  • 模組腳本
    • 放置在模組的資料夾中
    • 僅在啟用模組後執行
    • post-fs-data.sh 執行在 post-fs-data 模式下,而 service.sh 執行在 late_start 服務模式下。
    • 啟用僅核心模式(停用所有模組)時將不執行
    • 需要啟動腳本的模組應使用模組腳本而不是通用腳本
Magisk 的內部 busybox 路徑 $BBPATH 已新增到 PATH 的前面。 這意味著您在腳本中調用的所有命令都始終使用 busybox,除非未包含 applet。 這樣可以確保您的腳本始終在可預測的環境中執行,並且始終具有完整的命令集,無論其執行的是哪個 Android 版本。

根目錄覆蓋系統

由於 在 root 使用者系統裝置中是唯讀的,因此 Magisk 提供了一個覆蓋系統,使開發人員可以修補檔案/新增新的 rc 腳本。附加檔案應放在 ramdisk 的 overlay.d 的資料夾中,它們具有以下限制:
  • 在 init.rc 之後,將會讀取及連接overlay.d中的所有 *.rc 檔案。
  • 允許取代現有檔案。
    例如您可以透過新增檔案 overlay.d/res/random.png 來取代 /res/random.png
  • 不存在的檔案將被忽略(下一節將詳細說明例外)。
    例如如果 /new_file 不存在,則 overlay.d/new_file 將被忽略
  • 允許 overlay.d/sbin 中的其他檔案複製到Magisk的sbin疊加層中。
    例如 overlay.d/sbin/libfoo.ko 將被複製到 /sbin/libfoo.ko。

這個網誌中的熱門文章

[雜物] 自製的 Magisk 字型模組與一堆無趣的小玩意兒

[筆記][Void glitch] 捕捉謎之場所阿爾宙斯的最低必要條件

[蒐集] 刷機資源蒐集與記錄