Android端末をルート化すると、システムの深部に変更を加えることができるようになります。その中でも「Magisk」は、システムパーティションを直接改変せずに、システムレベルの変更を可能にする革新的なツールです。今回は、Magiskの仕組みを解説し、実際に独自のMagiskモジュールを作成する方法について詳しく紹介します。

Magiskとは?

Magiskは「Magic Mask」の略で、Androidシステムへの変更をシステムパーティションに直接手を加えることなく実現するシステムレスルート化ツールです。開発者のJohn Wu氏によって開発され、現在は多くのAndroidエンサジアストに利用されています。

従来のルート化との違い

従来のルート化方法(例:SuperSU)は、システムパーティションを直接改変していました。これには以下の問題がありました:

  • OTAアップデートが適用できない
  • セキュリティ検出(SafetyNet)に引っかかる
  • システムの整合性を失う可能性がある

一方、Magiskは「システムレス」というアプローチを採用しています。システムレスとは、システムパーティションに直接変更を加えるのではなく、起動プロセスの早い段階で「オーバーレイ」を行うことで変更を実現する方法です。

Magiskの仕組み

Mount Namespaceとは

Magiskの核心となるのは「Mount Namespace」という技術です。これはLinuxカーネルの機能で、異なるプロセスで異なるファイルシステムビューを持つことができるようにするものです。

Magiskの動作原理

Magiskの基本的な仕組みは以下のステップで構成されています:

  1. 初期起動:デバイス起動時、初期RAMディスク(initramfs/boot.img)内のinitプロセスが実行される
  2. Magisk Initの挿入:MagiskがRAMディスク内のinitを改変し、Magisk Initを先に実行
  3. ルートファイルシステムのマウント:Magisk Initがシステムパーティションをマウント
  4. オーバーレイの作成:tmpfsによる仮想的なファイルシステムを作成
  5. マージ:オリジナルのシステムファイルと、モジュールによる変更をマージ
  6. 新しいMount Namespaceの作成:変更されたファイルシステムビューを持つnamespaceを作成
  7. 元のinitの実行:変更されたビューでオリジナルのinitプロセスを実行

注意点: Magiskは、実際にはシステムパーティションを変更することなく、メモリ上でのファイルシステムの見え方を変えています。そのため、OTAアップデートが可能でありながら、システムレベルの変更が実現できるのです。

Magisk Moduleの構造

Magiskモジュールは、基本的に以下のディレクトリ構造を持ちます:

module_name/
├── META-INF/                 # ZIPインストール関連ファイル
├── system/                   # オーバーレイするファイルを配置
├── module.prop               # モジュール情報
├── post-fs-data.sh          # early startup script
├── service.sh               # late startup script
└── uninstall.sh             # アンインストール時に実行

特に重要なのはmodule.propファイルで、このファイルには以下の内容を記述します:

id=モジュールID
name=モジュール名
version=バージョン
versionCode=バージョンコード(数字)
author=作者名
description=モジュールの説明

独自Magiskモジュールの作成

では、実際に簡単なMagiskモジュールを作成してみましょう。今回は、システムサウンドを変更するシンプルなモジュールを作成します。

必要なもの

  • テキストエディタ
  • ZIP作成ツール
  • 基本的なシェルスクリプトの知識
  • 変更したいサウンドファイル(.ogg形式)

ステップバイステップのモジュール作成

1ディレクトリ構造の作成

まず、必要なディレクトリとファイルを作成します:

mkdir -p custom_sounds/META-INF/com/google/android
mkdir -p custom_sounds/system/media/audio/ui
touch custom_sounds/module.prop
touch custom_sounds/META-INF/com/google/android/update-binary
touch custom_sounds/META-INF/com/google/android/updater-script

2module.propの作成

module.propファイルに以下の内容を記述します:

id=custom_sounds
name=Custom System Sounds
version=v1.0
versionCode=1
author=あなたの名前
description=システムサウンドをカスタマイズするモジュール

3update-binaryスクリプトの作成

これはインストーラスクリプトで、Magiskのテンプレートをそのまま使用できます:

#!/sbin/sh
TMPDIR=/dev/tmp
MOUNTPATH=/dev/magisk_img

# Default permissions
umask 022

# Initial cleanup
rm -rf $TMPDIR 2>/dev/null
mkdir -p $TMPDIR

# Extract utility script
unzip -o "$3" 'common/*' -d $TMPDIR >&2
chmod -R 755 $TMPDIR/common

# Load utility functions
. $TMPDIR/common/util_functions.sh

require_new_magisk
ui_print "******************************"
ui_print "Custom System Sounds Module"
ui_print "******************************"

# Extract module files
ui_print "- Extracting module files"
unzip -o "$3" -d $MOUNTPATH >&2

# Set permissions
ui_print "- Setting permissions"
set_perm_recursive $MOUNTPATH/system 0 0 0755 0644

ui_print "- インストール完了"
exit 0

4updater-scriptの作成

このファイルは単純なものでOKです:

#MAGISK

5サウンドファイルの配置

変更したいサウンドファイルを適切なディレクトリに配置します。例えば、通知音を変更する場合:

cp 新しい通知音.ogg custom_sounds/system/media/audio/ui/Notification.ogg

システム内の元のファイルパスと同じ構造でファイルを配置することが重要です。

6ZIPファイルの作成

すべてのファイルをZIP形式にパッケージ化します:

cd custom_sounds
zip -r ../custom_sounds.zip .

7モジュールのインストール

作成したZIPファイルをMagiskマネージャーからインストールします:

  1. Magiskアプリを開く
  2. 「モジュール」タブを選択
  3. 「モジュールからインストール」ボタンをタップ
  4. 作成したZIPファイルを選択
  5. インストール完了後、再起動

より高度なモジュール開発

上記の例は非常にシンプルですが、より高度なモジュールを作成する場合は以下のスクリプトも活用できます:

post-fs-data.sh

このスクリプトはファイルシステムがマウントされた直後、データパーティションが復号化された後に実行されます。SELinuxはまだ「Enforcing」モードではないタイミングです。

#!/system/bin/sh
# モジュールのIDを取得
MODID=${0%/*}
# 特定のシステムファイルのパーミッションを変更する例
chmod 644 /system/build.prop

service.sh

このスクリプトはブートプロセスの最終段階で実行されます。システムサービスがすべて起動した後のタイミングです。

#!/system/bin/sh
# モジュールのIDを取得
MODID=${0%/*}
# バックグラウンドサービスを開始する例
nohup /system/bin/my_custom_service &

警告: モジュール開発では、システムに重大な変更を加える可能性があります。必ずバックアップを取り、自己責任で行ってください。また、誤ったモジュールはブートループ(起動エラーの繰り返し)を引き起こす可能性があります。

デバッグと開発のコツ

ログの確認方法

Magiskモジュールのデバッグには、ログの確認が役立ちます:

# Magiskのログを確認
adb shell cat /cache/magisk.log

# 自分のスクリプト内でログを出力
echo "デバッグ情報" >> /cache/magisk_debug.log

よくある問題とその解決策

  • ブートループ:Magiskマネージャーを使ってセーフモードで起動し、問題のあるモジュールを無効化
  • モジュールが機能しない:ファイルパスが正確かどうか確認し、パーミッションが適切に設定されているか確認
  • システムの整合性チェックに失敗:MagiskHideを使用して特定のアプリからMagiskを隠す

実際のユースケース

Magiskモジュールは様々な用途に使用できます:

  • システムアプリの削除:不要なシステムアプリを無効化または削除
  • バッテリー最適化:電力消費を抑えるシステム設定の変更
  • フォント変更:システムフォントのカスタマイズ
  • システムUI変更:通知音や起動音などの変更
  • ビルドプロップの編集:build.propファイルを通じてシステム設定を変更

まとめ

Magiskは、システムパーティションを直接改変することなく、システムレベルの変更を可能にする革新的なツールです。Mount Namespaceを活用した「システムレス」のアプローチにより、OTAアップデートやセキュリティチェックとの共存が可能になっています。

独自のMagiskモジュールを作成することで、Androidデバイスをより深くカスタマイズすることができます。今回紹介した基本的な構造とステップをマスターすれば、より複雑なモジュールも開発できるようになるでしょう。

システムの深部に変更を加える作業には常にリスクが伴いますが、Magiskの「システムレス」アプローチにより、そのリスクは従来のルート化手法よりも低減されています。自分だけのカスタマイズを楽しみながら、Androidの世界をより深く探求してみてください。

最後に: モジュール開発は、Android OSの仕組みを理解する絶好の機会です。自分のアイデアをモジュールとして形にすることで、プログラミングスキルも向上するでしょう。ぜひ挑戦してみてください!