Xposed Frameworkは、Androidアプリの挙動をシステムレベルで変更できる強力なツールです。
でも、「JavaとKotlin、どっちで書けばいい?」「そもそもどうやってhookするの?」と悩む人も多いはず。
この記事では、Java/Kotlin両対応で、Xposedモジュールの作り方をわかりやすく丁寧に解説します!


1. Xposedとは?ざっくり解説

Xposedは、Androidのアプリやシステムのメソッドに「横から割り込む」ことで、動作を自由に書き換えられるフレームワークです。
root化された端末にモジュールをインストールすることで、システムそのものを改造することなく、機能を追加・変更できます。

2. 開発環境の準備

  • Android Studio(最新)
  • Xposed APIライブラリ
  • ターゲットアプリ(hook対象)
  • Magisk + LSPosed or EdXposed(実機 or エミュレータ)

3. 実際のhookの仕組み

hookの基本は「メソッド呼び出しの前後に処理を差し込む」ことです。
たとえば、アプリがToast.makeText()でメッセージを表示しようとしたとき、Xposedでそのメッセージを差し替えることができます。

4. hookされる側 & hookする側の具体例

📱 hookされる側(対象アプリ)

まず、ユーザーがボタンを押すとToastを表示するアプリのコードです。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = findViewById(R.id.button);
        btn.setOnClickListener(v ->
            Toast.makeText(this, "オリジナルのメッセージ", Toast.LENGTH_SHORT).show()
        );
    }
}
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val btn = findViewById

🛠 hookする側(Xposedモジュール)

上記のToastメッセージを、Xposedを使って強制的に別の文字列に書き換えるコードです。

public class HookMain implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        if (!lpparam.packageName.equals("com.example.targetapp")) return;

        XposedHelpers.findAndHookMethod(
            "android.widget.Toast", lpparam.classLoader, "makeText",
            Context.class, CharSequence.class, int.class,
            new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) {
                    param.args[1] = "Xposedで書き換えました!";
                }
            }
        );
    }
}
class HookMain : IXposedHookLoadPackage {
    override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
        if (lpparam.packageName != "com.example.targetapp") return

        findAndHookMethod(
            "android.widget.Toast",
            lpparam.classLoader,
            "makeText",
            Context::class.java,
            CharSequence::class.java,
            Int::class.javaPrimitiveType,
            object : XC_MethodHook() {
                override fun beforeHookedMethod(param: MethodHookParam) {
                    param.args[1] = "Kotlinでhookしました!"
                }
            }
        )
    }
}

5. 動作確認とデバッグ

  • Magisk + LSPosed環境を使って実機にインストール
  • 「モジュールが有効」になっているか確認
  • ログ出力は Logcat または XposedBridge.log() を活用

6. まとめ

Xposedを使えば、アプリを直接改造せずに機能を書き換えることができます。
JavaでもKotlinでもOKなので、自分に合った言語で始めてみましょう。
少しずつできることが増えてくると、カスタムROM並みに便利な仕組みが作れるようになりますよ!

Xposedの世界は奥が深いですが、一歩ずつなら誰でも踏み込めます。
ぜひ、あなたもモジュール開発にチャレンジしてみてくださいね!🚀