对于插件化项目, 在插件包中新增一个Activity, 主包不能直接启动这个Activity, 因为这个Activity事先没有Mainfest文件中声明,会直接报Activity Not Found异常。
基本思路是:
1)App发送要启动的NextActivity信息给AMS之前,把这个Activity 替换为一个在AndroidMainfest.xml中声明的MainActivity, 这样就可以绕过
AMS的检查了。在替换的过程中将原来的Activity信息放在Bundle中。
2)AMS 通知App 启动MainActivity时,我们不会启动MainActivity,在即将启动的时候,把MainActivity 替换为原来的Activity.
在App发送启动的Activity信息给AMS 之前,可以对ActivityManagerNative进行Hook, 将NextActivity 替换为已注册的MainActivity.
public static void hookActivityManagerNative(){
try{
Object gDefault = ReflectUtil.getStaticFieldObject("android.app.ActivityManagerNative","gDefault");
Object activityManager = ReflectUtil.getFieldObject("android.util.Singleton",gDefault,"mInstance");
Class> activityManagerInterface = Class.forName("android.app.IActivityManager");
Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class>[] {activityManagerInterface},
new DeceptionHookHandler(activityManager));
ReflectUtil.setFileObject("android.util.Singleton",gDefault,"mInstance",proxy);
}catch (Exception e){
e.printStackTrace();
}
}
static class DeceptionHookHandler implements InvocationHandler{
Object mBase;
public DeceptionHookHandler(Object object){
this.mBase = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理
if("startActivity".equals(method.getName())){
//替换原始Activity 为别的Activity
//找到第一个参数Intent
Intent raw = null;
int index=0;
if(args != null && args.length > 0){
for (int i=0;i
AMS 通知App进程启动MainActivity,对ActivityThread中H 类的mCallback 进行hook, 将 MainActivity 替换为 NextActivity
public static void hookActivityThreadHCallback(){
try{
Object currentActivityThread =ReflectUtil.getStaticFieldObject("android.app.ActivityThread","sCurrentActivityThread");
Handler mHandler = (Handler) ReflectUtil.getFieldObject("android.app.ActivityThread",currentActivityThread,"mH");
ReflectUtil.setFileObject(Handler.class,mHandler,"mCallback",new DeceptionHandlerCallback(mHandler));
}catch (Exception e){
e.printStackTrace();
}
}
static class DeceptionHandlerCallback implements Handler.Callback{
private Handler mH;
public DeceptionHandlerCallback(Handler mHandler){
this.mH = mHandler;
}
/**
* 启动目标Activity
*/
public void startTargetActivity(Message msg) {
try {
Object obj = msg.obj;
//获取Intent 变量
Intent intent = (Intent) ReflectUtil.getFieldObject(obj, "intent");
Intent targetIntent = intent.getParcelableExtra("extra_intent");
intent.setComponent(targetIntent.getComponent());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean handleMessage(Message msg) {
if(msg.what == 100){ //等于LAUNCH_ACTIVITY
startTargetActivity(msg);
}
mH.handleMessage(msg);
return true;
}
}
代码地址:https://github.com/xiongliang120/HookProject.git