安卓,Hook住HookActivityThread-的Instrumentation

因为我的是安卓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
最好带上异常捕获

#########这篇文章并非原创,出处忘记在哪了,侵权删#####

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是代码形式的电话线路图状态: ``` @startuml title Telephone State Diagram [*] --> Idle : Initial State Idle --> Dialing : Off Hook Event Dialing --> Connecting : Valid Number Event Dialing --> Disconnected : Invalid/Wrong Number Event Connecting --> TimeOut : Timeout Event Connecting --> Connected : Called Phone Answers Event Ringing --> Connected : Called Phone Answers Event Connected --> Idle : On Hook Event Connected --> Busy Tone : Line Busy Event Connected --> TimeOut : Timeout Event Connected --> Disconnected : Timeout Event Connected --> Ringing : Play Message Event @enduml ``` 解释一下: - 初始状态为空闲状态(`[*] --> Idle : Initial State`)。 - 当电话机摘机时,电话状态从空闲状态转入拨号状态(`Idle --> Dialing : Off Hook Event`)。 - 当拨号有效号码时,电话状态从拨号状态转入连接状态(`Dialing --> Connecting : Valid Number Event`)。 - 当拨号号码无效或错误时,电话状态从拨号状态转入未连接状态(`Dialing --> Disconnected : Invalid/Wrong Number Event`)。 - 当连接超时时,电话连接状态从连接状态转入超时状态(`Connecting --> TimeOut : Timeout Event`)。 - 当被拨打的电话接听时,电话连接状态从连接状态或响铃状态转入已连接状态(`Connecting --> Connected : Called Phone Answers Event` 或 `Ringing --> Connected : Called Phone Answers Event`)。 - 当已连接状态的电话机挂机时,电话状态从已连接状态转入空闲状态(`Connected --> Idle : On Hook Event`)。 - 当已连接状态的电话线路忙碌时,电话状态从已连接状态转入忙音状态(`Connected --> Busy Tone : Line Busy Event`)。 - 当已连接状态的电话连接超时时,电话状态从已连接状态转入未连接状态(`Connected --> TimeOut : Timeout Event`)。 - 当已连接状态的电话播放信息时,电话状态从已连接状态转入响铃状态(`Connected --> Ringing : Play Message Event`)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值