废话不多说,直接上代码 ,如有不明白的可以私信留言,一起进步
在Application 中调用即可(AndroidManifest 中已经有注册过的activity)
class App extends Application{
@Override
public void onCreate(){
HookStartActivityIml.getInstance(getApplicationContext()).init();
}
}
HookStartActivityIml.java 的具体实现
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
public class HookStartActivityIml {
private String EXTRA_TARGET_INTENT = "wdd_test";
private static HookStartActivityIml hookStartActivityIml= null;
private Context context;
private String activityClass;//占坑
public static HookStartActivityIml getInstance(Context context){
if (hookStartActivityIml==null){
synchronized (HookStartActivityIml.class){
if (hookStartActivityIml== null){
hookStartActivityIml = new HookStartActivityIml(context);
}
}
}
return hookStartActivityIml;
}
private HookStartActivityIml(Context context){
this.context = context;
try {
PackageManager packageManager = context.getPackageManager();
String packageName = context.getPackageName();
PackageInfo packageInfo = packageManager.getPackageInfo(packageName,PackageManager.GET_ACTIVITIES);
//activity信息
ActivityInfo[] activities = packageInfo.activities;
if (activities.length>0)
activityClass = activities[0].name;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
public void init(){
hookStartActivity();
hookActivityThread();
}
private void hookStartActivity(){
try {
Field enterField = null;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
Class activityManagerClass = Class.forName("android.app.ActivityManager");
//Field IActivityManagerSingleton
enterField = activityManagerClass.getDeclaredField("IActivityManagerSingleton");
} else {
Class activityManagerNative = Class.forName("android.app.ActivityManagerNative");
enterField = activityManagerNative.getDeclaredField("gDefault");
}
enterField.setAccessible(true);
//Singleton<IActivityManager>的实例,因为IActivityManagerSingleton是静态的
Object singletonObject = enterField.get(null);
Class singletonClass = Class.forName("android.util.Singleton");
Field mInstanceField = singletonClass.getDeclaredField("mInstance");
mInstanceField.setAccessible(true);
// 获取singletonObject中变量mInstance的值即IActivityManager类型的实例
final Object mIActivityManagerObject = mInstanceField.get(singletonObject);
//IActivityManager 是接口,通过动态代理来处理
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class iActivityManagerInterface = Class.forName("android.app.IActivityManager");
//生产IActivityManager的代理对象
Object mIActivityManagerProxy = Proxy.newProxyInstance(
classLoader, new Class[]{iActivityManagerInterface}, new InvocationHandler() {
@Override public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("startActivity".equals(method.getName())) {
Intent rawIntent = null;
int index = 0;
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof Intent) {
rawIntent = (Intent) args[i];
index = i;
break;
}
}
// 将需要被启动的Activity替换成StubActivity
Intent newIntent = new Intent();
newIntent.setClassName(context, activityClass);
//把这个newIntent放回到args,达到了一个欺骗AMS的目的
newIntent.putExtra(EXTRA_TARGET_INTENT, rawIntent);
//将原有的Bundle添加到新的intent上
if (rawIntent.getExtras()!=null)
newIntent.putExtras(rawIntent.getExtras());
args[index] = newIntent;
}
return method.invoke(mIActivityManagerObject, args);
}
});
//把我们的代理对象融入到framework
//IActivityManager 在源码中是AIDL
mInstanceField.set(singletonObject, mIActivityManagerProxy);
} catch (Exception e) {
e.printStackTrace();
}
}
private void hookActivityThread(){
try {
Class launchActivityClass = Class.forName("android.app.ActivityThread");
Field mCurrentActivityThreadFiled = launchActivityClass.getDeclaredField("sCurrentActivityThread");
// 获取ActivityThread的实例
mCurrentActivityThreadFiled.setAccessible(true);
Object currentActivityThreadObject = mCurrentActivityThreadFiled.get(null);
//获取H
Field mHFiled = launchActivityClass.getDeclaredField("mH");
//H的实例
mHFiled.setAccessible(true);
Handler hObject = (Handler) mHFiled.get(currentActivityThreadObject);
//获取callback
Field mCallbackField = Handler.class.getDeclaredField("mCallback");
mCallbackField.setAccessible(true);
// TODO 为什么不需要动态代理了?
mCallbackField.set(hObject, new Handler.Callback() {
@Override public boolean handleMessage(Message msg) {
Object obj = msg.obj;
switch (msg.what) {
case 100:
try {
Field intnetField = obj.getClass().getDeclaredField("intent");
intnetField.setAccessible(true);
Intent proxyIntent = (Intent) intnetField.get(obj);
Intent realinIntent = proxyIntent.getParcelableExtra(EXTRA_TARGET_INTENT);
if(realinIntent!=null){
proxyIntent.setComponent(realinIntent.getComponent());//替换
}
} catch (Exception e) {
e.printStackTrace();
}
break;
case 149:
case 159:
//恢复真身
//Object obj = msg.obj;
try {
if (Build.VERSION.SDK_INT < 28) {
try {
Field intnetField = obj.getClass().getDeclaredField("intent");
intnetField.setAccessible(true);
Intent proxyIntent = (Intent) intnetField.get(obj);
Intent realinIntent = proxyIntent.getParcelableExtra(EXTRA_TARGET_INTENT);
if(realinIntent!=null){
proxyIntent.setComponent(realinIntent.getComponent());//替换
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
Field mActivityCallbacksField = obj.getClass().getDeclaredField("mActivityCallbacks");
mActivityCallbacksField.setAccessible(true);
List mActivityCallbacks = (List) mActivityCallbacksField.get(obj);
if (mActivityCallbacks.size() > 0) {
String className = "android.app.servertransaction.LaunchActivityItem";
if (mActivityCallbacks.get(0).getClass().getCanonicalName().equals(className)) {
Object object = mActivityCallbacks.get(0);
Field intentField = object.getClass().getDeclaredField("mIntent");
intentField.setAccessible(true);
Intent intent = (Intent) intentField.get(object);
Intent targetIntent = intent.getParcelableExtra(EXTRA_TARGET_INTENT);
if (targetIntent != null) {
intent.setComponent(targetIntent.getComponent());
}
}
}
}
} catch(Exception e){
e.printStackTrace();
}
break;
}
return false;
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}