原文说明
/** * Called before the invocation of the method. * * <p>You can use {@link MethodHookParam#setResult} and {@link MethodHookParam#setThrowable} * to prevent the original method from being called. * * <p>Note that implementations shouldn't call {@code super(param)}, it's not necessary. * * @param param Information about the method call. * @throws Throwable Everything the callback throws is caught and logged. */ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {} /** * Called after the invocation of the method. * * <p>You can use {@link MethodHookParam#setResult} and {@link MethodHookParam#setThrowable} * to modify the return value of the original method. * * <p>Note that implementations shouldn't call {@code super(param)}, it's not necessary. * * @param param Information about the method call. * @throws Throwable Everything the callback throws is caught and logged. */ protected void afterHookedMethod(MethodHookParam param) throws Throwable {} /** * Shortcut for replacing a method completely. Whatever is returned/thrown here is taken * instead of the result of the original method (which will not be called). * * <p>Note that implementations shouldn't call {@code super(param)}, it's not necessary. * * @param param Information about the method call. * @throws Throwable Anything that is thrown by the callback will be passed on to the original caller. */ @SuppressWarnings("UnusedParameters") protected abstract Object replaceHookedMethod(MethodHookParam param) throws Throwable;
翻译及总结
beforeHookedMethod 会在调用原方法前执行,如果使用setResult则跳过原方法,并返回setResult参数中的值。
afterHookedMethod 会在调用原方法后执行,setResult可改变返回值
replaceHookedMethod 会完全替换原方法,即原方法不执行,且返回值可以直接return,setResult不生效。
代码验证
需要被Hook的代码
至于返回值为什么用Integer ,因为在测试replaceHookedMethod的时候,给 int 赋 null 会崩……而 final是为了顺便验证下这个关键字会不会影响hook。
private void test(){ Integer ret = hkBefore(100); Log.d(TAG, "hkBefore ret:" + ret); ret = hkBeforeSetResult(200); Log.d(TAG, "hkBeforeSetResult ret:" + ret); ret = hkAfter(300); Log.d(TAG, "hkAfter ret:" + ret); ret = hkAfterSetResult(400); Log.d(TAG, "hkAfterSetResult ret:" + ret); ret = hkReplace(500); Log.d(TAG, "hkReplace ret:" + ret); ret = hkReplaceReturn(600); Log.d(TAG, "hkReplaceReturn ret:" + ret); ret = hkReplaceSetResult(700); Log.d(TAG, "hkReplaceSetResult ret:" + ret); } public final Integer hkBefore(int a){ Log.d(TAG, "————————————————————————hkBefore print:" + a); return a; } public final Integer hkBeforeSetResult(int a){ Log.d(TAG, "————————————————————————hkBeforeSetResult print:" + a); return a; } public final Integer hkAfter(int a){ Log.d(TAG, "————————————————————————hkAfter print:" + a); return a; } public final Integer hkAfterSetResult(int a){ Log.d(TAG, "————————————————————————hkAfterSetResult print:" + a); return a; } public final Integer hkReplace(int a){ Log.d(TAG, "————————————————————————hkReplace print:" + a); return a; } public final Integer hkReplaceReturn(int a){ Log.d(TAG, "————————————————————————hkReplaceReturn print:" + a); return a; } public final Integer hkReplaceSetResult(int a){ Log.d(TAG, "————————————————————————hkReplaceSetResult print:" + a); return a; }
xposed模块
public class XMain implements IXposedHookLoadPackage { private final String TAG = "XposedMain"; @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { Log.d(TAG, "hook app: " + loadPackageParam.packageName); if (loadPackageParam.packageName.equals("com.bloguan.democity")) { Log.d(TAG, "hook "); XposedHelpers.findAndHookMethod("com.bloguan.democity.demo.DTest", loadPackageParam.classLoader, "hkBefore", int.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { int a = (int) param.args[0]; param.args[0] = a + 1; } }); XposedHelpers.findAndHookMethod("com.bloguan.democity.demo.DTest", loadPackageParam.classLoader, "hkBeforeSetResult", int.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { int a = (int) param.args[0]; param.args[0] = a + 1; param.setResult(a + 2); } }); XposedHelpers.findAndHookMethod("com.bloguan.democity.demo.DTest", loadPackageParam.classLoader, "hkAfter", int.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { int a = (int) param.args[0]; param.args[0] = a + 1; } }); XposedHelpers.findAndHookMethod("com.bloguan.democity.demo.DTest", loadPackageParam.classLoader, "hkAfterSetResult", int.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { int a = (int) param.args[0]; param.args[0] = a + 1; param.setResult(a + 2); } }); XposedHelpers.findAndHookMethod("com.bloguan.democity.demo.DTest", loadPackageParam.classLoader, "hkReplace", int.class, new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { return null; } }); XposedHelpers.findAndHookMethod("com.bloguan.democity.demo.DTest", loadPackageParam.classLoader, "hkReplaceReturn", int.class, new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { int a = (int) param.args[0]; return a + 1; } }); XposedHelpers.findAndHookMethod("com.bloguan.democity.demo.DTest", loadPackageParam.classLoader, "hkReplaceSetResult", int.class, new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { int a = (int) param.args[0]; param.args[0] = a + 1; param.setResult(a + 2); return a + 3; } }); Log.d(TAG, "hook success "); } } }
xposed模块安装过程就不赘述了,既然有此一问,说明xposed已经用上了。
执行结果
12-18 16:20:22.878 2054-2054/com.bloguan.democity D/TEST: ————————————————————————hkBefore print:101 12-18 16:20:22.883 2054-2054/com.bloguan.democity D/TEST: hkBefore ret:101 12-18 16:20:22.883 2054-2054/com.bloguan.democity D/TEST: hkBeforeSetResult ret:202 12-18 16:20:22.883 2054-2054/com.bloguan.democity D/TEST: ————————————————————————hkAfter print:300 12-18 16:20:22.884 2054-2054/com.bloguan.democity D/TEST: hkAfter ret:300 12-18 16:20:22.884 2054-2054/com.bloguan.democity D/TEST: ————————————————————————hkAfterSetResult print:400 12-18 16:20:22.884 2054-2054/com.bloguan.democity D/TEST: hkAfterSetResult ret:402 12-18 16:20:22.884 2054-2054/com.bloguan.democity D/TEST: hkReplace ret:null 12-18 16:20:22.884 2054-2054/com.bloguan.democity D/TEST: hkReplaceReturn ret:601 12-18 16:20:22.884 2054-2054/com.bloguan.democity D/TEST: hkReplaceSetResult ret:703
打印不算太乱吧 = =
结论即上面说的,具体流程各位可以自己细看。
发表评论