因为我的是安卓10Vivo的手机,HookHookActivityThread不好使,
我的实现Hook方案是Instrumentation
###################################
public class HookActivityThread
{
public static void Hookatd() throws Exception{
// 先获取到当前的ActivityThread对象
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread");
currentActivityThreadMethod.setAccessible(true);
Object currentActivityThread = currentActivityThreadMethod.invoke(null);
// 拿到原始的 mInstrumentation字段
Field mInstrumentationField = activityThreadClass.getDeclaredField("mInstrumentation");
mInstrumentationField.setAccessible(true);
Instrumentation mInstrumentation = (Instrumentation) mInstrumentationField.get(currentActivityThread);
// 创建代理对象
Instrumentation evilInstrumentation = new EvilInstrumentation(mInstrumentation);
// 偷梁换柱
mInstrumentationField.set(currentActivityThread, evilInstrumentation);
}
public static class EvilInstrumentation extends Instrumentation {
private static final String TAG = "EvilInstrumentation";
// ActivityThread中原始的对象, 保存起来
Instrumentation mBase;
Intent intentm=null;//储存真实的插件Activity封装
public EvilInstrumentation(Instrumentation base) {
mBase = base;
}
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {
String testtxt ="\n执行了startActivity, 参数如下: \n" + "who = [" + who + "], " +
"\ncontextThread = [" + contextThread + "], \ntoken = [" + token + "], " +
"\ntarget = [" + target + "], \nintent = [" + intent +
"], \nrequestCode = [" + requestCode + "], \noptions = [" + options + "]";
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n "+testtxt);
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n exestart"+" 要启动的Activity"+target.getClass().getName());
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n exestart"+" "+mBase.getClass().getName());
// 开始调用原始的方法, 调不调用随你,但是不调用的话, 所有的startActivity都失效了.
// 由于这个方法是隐藏的,因此需要使用反射调用;首先找到这个方法
Method execStartActivity=null;
try {
execStartActivity = Instrumentation.class.getDeclaredMethod(
"execStartActivity",
Context.class, IBinder.class, IBinder.class, Activity.class,
Intent.class, int.class, Bundle.class);
if(!execStartActivity.isAccessible()){
execStartActivity.setAccessible(true);
}
return (ActivityResult) execStartActivity.invoke(mBase, who,
contextThread, token, target, intent, requestCode, options);
} catch (Exception e) {
// 某该死的rom修改了 需要手动适配
//throw new RuntimeException("do not support!!! pls adapt it");
try
{
Intent intexta=new Intent(target,com.hhs.myappho.activity.BaseActivity.class);
//intent.setClassName(.getPackage().getName(),com.hhs.myappho.activity.BaseActivity.class.getClass().getName());
intentm = intent;
return (ActivityResult) execStartActivity.invoke(mBase, who,
contextThread, token, target, intexta, requestCode, options);
}
catch (Exception ea)
{
throw new RuntimeException("do not support!!! pls adapt it 启动失败 "+e);
}
}
finally{
/*
if(execStartActivity!=null){
if(execStartActivity.isAccessible()){
execStartActivity.setAccessible(false);
}
}
*/
}
}
@Override
public void callActivityOnResume(Activity activity)
{
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n "+" callActivityOnResume "+mBase.getClass().getName());
super.callActivityOnResume(activity);
}
@Override
public void callActivityOnPostCreate(Activity activity, Bundle icicle)
{
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n "+" callActivityOnPostCreate "+mBase.getClass().getName());
if(activity!=null){
activity.setTitle("这是插件,被我修改了主题名");
}
super.callActivityOnPostCreate(activity, icicle);
}
@Override
public void callActivityOnPause(Activity activity)
{
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n "+" callActivityOnPause "+mBase.getClass().getName());
super.callActivityOnPause(activity);
}
@Override
public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException
{
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n newActivity"+" 目标 "+className+" 传递过来的信息"+intent);
//HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n "+" newActivity "+mBase.getClass().getName());
if(className.equals("com.hhs.myappho.MainActivity")){
return super.newActivity(cl, className, intent);
}
Intent target = intent;
try{
if(target!=null){
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n newActivity"+" 目标 "+className+" 启动细心"+intent);
//恢复原来启动的插件Activity
if(intentm!=null){
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n 没有注册但是要启动的组件信息组件:_"+target.getComponent());
return super.newActivity(cl, intentm.getComponent().getClassName(), target);
}
}
}catch(Exception erra){
}
finally{
intentm=null;
}
return super.newActivity(cl, "com.hhs.myappho.activity.JavaScriptActivity", intent);
}
@Override
public void callActivityOnNewIntent(Activity activity, Intent intent)
{
//
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n "+" newActivity "+intent.getComponent());
super.callActivityOnNewIntent(activity, intent);
}
}
}
###################################
*当调用startrActivity执行到我们Hook替换的execStartActivity方法时,对Intent进行记录然后换上在宿主中的占坑的Activity,系统然后初始化完后会回调public Activity newActivity(ClassLoader cl, String className, Intent intent) ,再把宿主带有宿主Activity的Intent扔掉把记录的Intent中的class取出让系统初始化然后大功告成了。_
public EvilInstrumentation(Instrumentation base) {
mBase = base;
}
*****一、在这里将插件Activity替换成我们的宿主的Activity实现让系统检查
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {
String testtxt ="\n执行了startActivity, 参数如下: \n" + "who = [" + who + "], " +
"\ncontextThread = [" + contextThread + "], \ntoken = [" + token + "], " +
"\ntarget = [" + target + "], \nintent = [" + intent +
"], \nrequestCode = [" + requestCode + "], \noptions = [" + options + "]";
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n "+testtxt);
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n exestart"+" 要启动的Activity"+target.getClass().getName());
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n exestart"+" "+mBase.getClass().getName());
// 开始调用原始的方法, 调不调用随你,但是不调用的话, 所有的startActivity都失效了.
// 由于这个方法是隐藏的,因此需要使用反射调用;首先找到这个方法
Method execStartActivity=null;
try {
execStartActivity = Instrumentation.class.getDeclaredMethod(
"execStartActivity",
Context.class, IBinder.class, IBinder.class, Activity.class,
Intent.class, int.class, Bundle.class);
if(!execStartActivity.isAccessible()){
execStartActivity.setAccessible(true);
}
return (ActivityResult) execStartActivity.invoke(mBase, who,
contextThread, token, target, intent, requestCode, options);
} catch (Exception e) {
// 某该死的rom修改了 需要手动适配
//throw new RuntimeException("do not support!!! pls adapt it");
try
{
Intent intexta=new Intent(target,com.hhs.myappho.activity.BaseActivity.class);****在这里new一个占坑Initent_Activity
//intent.setClassName(.getPackage().getName(),com.hhs.myappho.activity.BaseActivity.class.getClass().getName());
intentm = intent;******在这里记录了我们的插件Activity,这个Activity是在宿主中有定义的
return (ActivityResult) execStartActivity.invoke(mBase, who,
contextThread, token, target, intexta/*把我们的占坑Activity换上*/, requestCode, options);
}
catch (Exception ea)
{
throw new RuntimeException("do not support!!! pls adapt it 启动失败 "+e);
}
}
finally{
/*
if(execStartActivity!=null){
if(execStartActivity.isAccessible()){
execStartActivity.setAccessible(false);
}
}
*/
}
}
****二、在这里把插件Activity换回来
@Override
public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException
{
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n newActivity"+" 目标 "+className+" 传递过来的信息"+intent);
//HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n "+" newActivity "+mBase.getClass().getName());
if(className.equals("com.hhs.myappho.MainActivity")){
return super.newActivity(cl, className, intent);
}
Intent target = intent;
try{
if(target!=null){
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n newActivity"+" 目标 "+className+" 启动细心"+intent);
//恢复原来启动的插件Activity
if(intentm!=null){
HookHandler. method2("/storage/emulated/0/MT2/apks/Voms/Log.txt","\n 没有注册但是要启动的组件信息组件:_"+target.getComponent());
****在这里把记录的Activity恢复
return super.newActivity(cl, intentm.getComponent().getClassName(), target);
}
}
}catch(Exception erra){
}
finally{
intentm=null;
}
return super.newActivity(cl, "com.hhs.myappho.activity.JavaScriptActivity", intent);
}
在宿主初始化后
super.onCreate();
HookActivityThread.Hookatd();
HookHelper.hookPackageManager(this);***Hook包管理器PackageManager
最好带上异常捕获