XposedはJNIライブラリをロードします

2142 ワード

プロジェクト開発では、JNIライブラリを使用して特定の機能を提供することがよくありますが、xposed開発では、このようなニーズもありますが、xposedの条件下でsoをロードするのは容易ではありません.
最初の問題はプロセス間であり、xposedプログラムが実行されている間、xposedモジュールはプライマリパッケージと同じプロセスではないため、JNIライブラリを直接次のコードでロードすることはできません.
init {
    System.loadLibrary("xpjni")
}

そうすれば、xposedプロセスがアクセスできる空間では、このsoが見つからないため、UnsatisfiedLinkErrorしか得られません.
では、System.loadという別のロード方法を使用できますか?次のコードがあります.
init {
    System.load("/data/app/com.rarnu.xpjni.demo-1/lib/arm/libxpjni.so")
}

このようなコードは一部の携帯電話で動作することができるが、一部の携帯電話ではUnsatisfiedLinkErrorが得られているが、具体的なエラー情報は変わった.
java.lang.UnsatisfiedLinkError: dlopen failed: 
"/data/app/com.rarnu.xpjni.demo-2/lib/arm/libxpjni.so" 
is 32-bit instead of 64-bit

エラーメッセージを見ると、64ビットのプロセス内に32ビットのライブラリがロードされているため、ここではプロセスのビット数を先に判断する必要があるタイミングの問題があり、64ビットのデバイスではデフォルトのxposedプロセスも64ビットである.次の2つのソリューションがあります.
シナリオ1:arm 64-v 8 aアーキテクチャのライブラリをコンパイルし、ロード時に64ビットのライブラリをロードする
init {
    System.load("/data/app/com.rarnu.xpjni.demo-1/lib/arm64/libxpjni.so")
}

これにより64ビットのデバイスに適応できます.特定のビット数判定は、dalvik.system. VMRuntimeクラスを反射し、そのうちのis64Bitメソッドを呼び出すことができる.
シナリオ2:JNIライブラリのロードタイミングを変更し、初期化時のロードをhookから指定32ビットパケットのロード時に変更してロードする.
override fun handleLoadPackage(loadPackageParam: XC_LoadPackage.LoadPackageParam) {
    if (loadPackageParam.packageName == "com.rarnu.xpjni.demo") {
            System.load("/data/app/com.rarnu.xpjni.demo-1/lib/arm/libxpjni.so")
    }
}

自分のプログラムは32ビットのJNIライブラリしかないので、32ビットのアプリケーションとしてロードされ、自身がロードされたときにJNIライブラリをロードすれば、スムーズに32ビットのライブラリにロードできます.このときデバイスが64ビットであっても32ビットのライブラリに正常にロードできます.
ロードが完了したら、簡単な関数呼び出しをするか、JNI_を実装します.OnLoadでテストできますが、最終的には次のような効果が得られます.
E/XposedModule: jni library path => /data/app/com.rarnu.xpjni.demo-2/lib/arm/libxpjni.so
E/XpJNI_Native: JNI_Load
E/XposedModule: jni library loaded
E/XposedModule: jni call => 300

本明細書で使用するコードエンジニアリングはgithub(スタンプ)にアップロードされていますが、不明な点があれば、コードを直接見ましょう.