Xposed を使用して、アプリから実行時にシステム メソッドを呼び出したいと考えています。放送受信機が正しい方法だと思います。
そのメソッドを呼び出すことができるように、ブロードキャスト レシーバーを適切なコンテキストでセットアップするにはどうすればよいですか? クラスにある種のプロキシ インスタンスが必要ですか? 短いサンプルコードがいいでしょう:)
Xposed を使用して、アプリから実行時にシステム メソッドを呼び出したいと考えています。放送受信機が正しい方法だと思います。
そのメソッドを呼び出すことができるように、ブロードキャスト レシーバーを適切なコンテキストでセットアップするにはどうすればよいですか? クラスにある種のプロキシ インスタンスが必要ですか? 短いサンプルコードがいいでしょう:)
私もこれを試しました。これを行うには、リフレクションを使用できます。
例:
com.your.package.app.XModuleBridge 内
public static abstract class HandleHook {
public abstract void before(Object paramObj);
public abstract void after(Object paramObj);
}
public boolean unhook(Object key) {
return false;
}
/* handle must be instance of HandleHook */
public Object hook(Method method, Object handle) {
return null;
}
Xposedモジュールで。
/* bridge = Class object of XModuleBridge */
XposedBridge.hookMethod(bridge.getDeclaredMethod("hook",
Method.class, Object.class), new XC_MethodHook() {
{
System.out.println(">>>>> some log ");
}
@Override
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
param.setResult(hookMethod(param));
}
});
XposedBridge.hookMethod(
bridge.getDeclaredMethod("unhook", Object.class),
new XC_MethodHook() {
{
System.out.println(">>>>> some log ");
}
@Override
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
XC_MethodHook.Unhook hook = hookedMethod
.remove(param.args[0]);
if (hook != null) {
hook.unhook();
}
param.setResult(true);
}
});
--
private Object hookMethod(XC_MethodHook.MethodHookParam param) {
final Object[] args = param.args;
// TODO check args.
XC_MethodHook.Unhook unhook = XposedBridge.hookMethod((Method) args[0],
new XC_MethodHook() {
private Object call = args[1];
{
System.out.println(">>>>> some log ");
}
@Override
protected void beforeHookedMethod(MethodHookParam param)
throws Throwable {
call.getClass()
.getDeclaredMethod("before", Object.class)
.invoke(call, param);
}
@Override
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
call.getClass()
.getDeclaredMethod("after", Object.class)
.invoke(call, param);
}
});
Object key = new Object();
hookedMethod.put(key, unhook);
return key;
}
使用法:
XModuleBridge bridge = new XModuleBridge();
Method method = null;
try {
method = textView.getClass().getDeclaredMethod("append",
CharSequence.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Object hooked = bridge.hook(method, new HandleHook() {
@Override
public void before(Object paramObj) {
/* paramObj is instance of XC_MethodHook.MethodHookParam */
/* reflect paramObj in ParamConverter.
or cast to XC_MethodHook.MethodHookParam*/
ParamConverter param = new ParamConverter(
paramObj);
System.out.println(">>>>>>> 1" + param.args[0]);
param.args[0] = "changed.";
System.out.println(">>>>>>> 2" + param.args[0]);
}
@Override
public void after(Object paramObj) {}
});
// ...
bridge.unhook(hooked);
各アプリには異なる Class オブジェクトの異なる xposed モジュール インスタンスがあることがわかったため、実行時にすべてのアプリのメソッドをフックする方法がわかりません。それらは互いにオブジェクトを共有しません。(パフォーマンスが悪い場合は、データベースまたはディスク ファイルを使用したくない)