题意:代理抽象就是说,对于一个抽象类的实例化参数,我们需要进行hook他的结果的操作,这种匿名类或者对象往往有很多构造函数的参数是我们无法构造的,或者传入空可能需要和正常的处理方式相悖,增加复杂度。(说了这么多,还是上代码直接)
目录:
1、代理接口
2、代理抽象类
3、其它
public class TestModel { public int code; public String msg; }
public interface ITest { void onExecuted(TestModel paramT); }
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ((Button)findViewById(R.id.btnTest2)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ITest testInter = new ITest() { @Override public void onExecuted(TestModel paramT) { Toast.makeText(getBaseContext(), paramT.msg, Toast.LENGTH_LONG).show(); } }; Test2(testInter); } }); } public void Test2(ITest test){ TestModel model = new TestModel(); model.msg = "success"; test.onExecuted(model); } }
findAndHookMethod("com.android.testabstract.MainActivity", lpparam.classLoader, "onCreate", Bundle.class, new XC_MethodHook() { @Override protected void afterHookedMethod(final MethodHookParam param) throws Throwable { super.afterHookedMethod(param); final Object pthis = param.thisObject; // 拿到对象用于下一步调用 hookInterface(lpparam.classLoader, pthis); } }); private void hookInterface(final ClassLoader classLoader, final Object pthis){ new Thread(new Runnable() { @Override public void run() { try { Class<?> class_ITest = classLoader.loadClass("com.android.testabstract.ITest"); Object obj_proxy = Proxy.newProxyInstance(classLoader, new Class<?>[]{class_ITest}, new InvocationHandler() { @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { // 这里接可以拿到,接口执行的方法和执行的参数了。 Log.i("testProxy", "method " + method.getName()); Log.i("testProxy", "objects.length " + (objects != null ? objects.length : "null")); return null; } }); XposedHelpers.callMethod(pthis, "Test2", obj_proxy); } catch (NoClassDefFoundError fe){ Log.i("testProxy", "fe " + fe.getMessage()); fe.printStackTrace(); } catch (Exception e){ Log.i("testProxy", "e " + e.getMessage()); e.printStackTrace(); } } }).start(); }
public abstract class TestAb<T> { public final void onExecuted(T paramT, Exception paramException) { onSuccess(paramT); } protected abstract void onSuccess(T paramT); }
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ((Button)findViewById(R.id.btnTest)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { TestAb<TestModel> testAb = new TestAb<TestModel>() { @Override protected void onSuccess(TestModel paramT) { Toast.makeText(getBaseContext(), paramT.msg, Toast.LENGTH_LONG).show(); } }; Test(testAb); } }); } public void Test(TestAb testAb){ TestModel model = new TestModel(); model.msg = "success"; testAb.onExecuted(model, null); } }
private void hookFail(final Object pthis){ new Thread(new Runnable() { @Override public void run() { try { TestAb<TestModel> test = new TestAb<TestModel>() { @Override protected void onSuccess(TestModel paramT) { Log.i("testAbProxy", "paramT " + paramT.msg); } }; XposedHelpers.callMethod(pthis, "Test", test); } catch (NoClassDefFoundError fe){ Log.i("tt===tt", "fe " + fe.getMessage()); fe.printStackTrace(); } catch (Exception e){ Log.i("tt===tt", "e " + e.getMessage()); e.printStackTrace(); } } }).start(); }
// 定义实现抽象的对象。下面用到 public class TestTestAb extends TestAb<TestModel> { public TestTestAb(){ } @Override protected void onSuccess(TestModel paramT) { Log.i("tt===tt", "hooked msg " + paramT.msg); } }
// 定义hook代码 private void hookTest2(final Object pthis){ new Thread(new Runnable() { @Override public void run() { try { // 这里针对art,直接这样使用,dalvik可能就不一样了 String path = "/data/app/com.android.testxpabs-1/base.apk"; if(!new File(path).exists()){ path = "/data/app/com.android.testxpabs-2/base.apk"; } PathClassLoader pathClassLoader = new PathClassLoader(path, pthis.getClass().getClassLoader()); Class<?> class_ = pathClassLoader.loadClass("com.android.testxpabs.TestTestAb"); Object obj_ = class_.newInstance(); Class<?> class_TestModel = pathClassLoader.loadClass("com.android.testabstract.TestModel"); findAndHookMethod("com.android.testxpabs.TestTestAb", pathClassLoader, "onSuccess", class_TestModel, new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { Log.i("tt===tt", "hook replace " + param.args[0]); return null; } }); // 把当前APK加入 XposedHelpers.callMethod(pthis, "Test", obj_); } catch (NoClassDefFoundError fe){ Log.i("testAbProxy", "fe " + fe.getMessage()); fe.printStackTrace(); } catch (Exception e){ Log.i("testAbProxy", "e " + e.getMessage()); e.printStackTrace(); } } }).start(); }
这样执行就没问题了,同时对于实现类我们也是可以hook的了。
对于这种实现方式,是不是眼熟呀。。。看看其他
源码见附件
[公告]看雪论坛2020激励机制上线了!发帖不减雪币了!如何获得积分快速升级?
最后于 2小时前 被supperlitt编辑 ,原因: