本篇博客主要讲述一下对startActivity进行hook,对于Android开发来说,跳转一个新的Activity页面,最常见的无非两种了,
方法一:
Intent intent = new Intent(MainActivity.this, NewActivity.class);
startActivity(intent);
方法二:
Intent intent = new Intent(MainActivity.this, NewActivity.class);
getApplicationContent().startActivity(intent);
对于hook startActivity在此列出三种方法:
1: 我们知道我们的Activity页面继承自Activity.java,此时衍生出了hook的第一种方法。
2: getApplicationContext.startActivity实际上调用的是ContextImp的startActivity方法,由此衍生出了hook的第二种方法
3: 上面两种情况,都会执行一段代码就是:ActivityManager.getService().startActivity …, 由此衍生出了第三种方法,而且是一劳永逸的方法。
对Activity的mInstrumentation字段进行hook
在Activity中有一个字段:mInstrumentation,我们调用的startActivity都会执行:
public class Activity extends ContextThemeWrapper {
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
}
}
此时我们可以替换掉mInstrumentation字段,然后执行我们自己的对象,
上图就是我们hook之后的startActivity的执行流程。
hook步骤:
- 获取Activity中的mInstrumentation字段的对象
- 将获取到的对象包装成自己的对象。
- 将包装好的对象反射复制给mInstrumentation字段。
/**
* hook Activity mInstrumentation
*/
private void hookActivityInstrumentation() {
//获取Activity中的mInstrumentation对象
Instrumentation mInstrumentation =
(Instrumentation) ReflexUtil.getFieldValue(Activity.class.getName(), this, "mInstrumentation");
//包装成自己的对象
Instrumentation proxy = new MyInstrumentation(mInstrumentation);
//将Activity中的对象替换成自