使用动态代理拦截Android Activity的启动
来源:互联网 发布:张逗张花小卖部 淘宝 编辑:程序博客网 时间:2024/05/22 01:28
使用动态代理拦截Android Activity的启动
1.动态代理拦截的要求
- 要代理的类要实现接口
- 要能获取目标类的对象
2.对startActivity进行拦截
activity的启动过程通过分析源码知道了实际内部调用了ActivityManagerNative.getDefault()
这个方法,而getDefault这个方法内部是
.startActivity
static public IActivityManager getDefault() { return gDefault.get(); }
这个gDefault是一个静态常量Singleton。
所以关键就是通过反射获取到gDefault然后拦截它的startactivity方法。
ActivityManagerNative是一个继承了Binder的类,还实现了IActivityManager这个接口.相当于AIDL中系统生成的Stub类。然后ActivityManagerNative是一个抽象类,它的实现类是ActivityManagerService。
ActivityManagerNative内部还有一个类,ActivityManagerProxy,这个类就是这个Binder的远端代理类。我们要拦截的就是这个ActivityManagerProxy对象的startActivity方法。
public static void hookAms() { try { Class<?> activityManagerNativeClass = Class.forName("android.app.ActivityManagerNative"); Field gDefaultField = activityManagerNativeClass.getDeclaredField("gDefault"); gDefaultField.setAccessible(true); Object gDefault = gDefaultField.get(null); Class<?> singleton = Class.forName("android.util.Singleton"); Field mInstanceField = singleton.getDeclaredField("mInstance"); mInstanceField.setAccessible(true); Object rawIActivityManager = mInstanceField.get(gDefault); Class<?> iActivityManager = Class.forName("android.app.IActivityManager"); Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class[]{iActivityManager} ,new AmsHookBinderInvocationHanlder(rawIActivityManager)); mInstanceField.set(gDefault,proxy); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }
然后在我们的InvocationHandler中
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("startActivity".equals(method.getName())){ Intent raw; int index = 0; for(int i=0;i< args.length;i++){ if(args[i] instanceof Intent){ index = i; break; } } raw = (Intent) args[index]; Intent newIntent = new Intent(); String targetPackage = "com.github"; ComponentName componentName = new ComponentName(targetPackage, FileInterSendActivity.class.getName()); newIntent.setComponent(componentName); newIntent.putExtra("_tartget_intent",raw); Log.d("hook",Thread.currentThread().getName()); Log.d("hook","拦截activity的启动成功"+"\n" + "component:"+((Intent)args[2]).getComponent().getPackageName()+","+((Intent)args[2]).getComponent().getClassName()); args[index] = newIntent; Log.d("hook","change activity component successful"+"\n" + "component:"+((Intent)args[2]).getComponent().getPackageName()+","+((Intent)args[2]).getComponent().getClassName()); return method.invoke(obj,args); } return method.invoke(obj, args); }
运行项目,会发现我们成功的将想要启动的activity替换掉了。
阅读全文
0 0
- 使用动态代理拦截Android Activity的启动
- Android-->动态加载Activity (不使用Intent,启动Activity)
- 使用Java动态代理实现的拦截器
- Android 中拦截 Activity 的启动(拦截系统的 Intent)
- 动态代理--struts的拦截器基础
- 如何拦截Activity的启动(一)
- 如何拦截Activity的启动(二)
- Android动态加载进阶 代理Activity模式
- Android动态加载进阶 代理Activity模式
- Android动态加载进阶 代理Activity模式
- Android动态加载进阶 代理Activity模式
- Android动态加载之代理Activity模式
- 动态代理的使用
- Android中实现Activity的启动拦截之----实现360卫士的安装应用界面
- Android中实现Activity的启动拦截之----实现360卫士的安装应用界面
- Android设计模式之动态代理,实现方法拦截功能
- Java中使用动态代理实现拦截器
- 【动态加载】Android动态加载进阶:代理Activity模式
- Mac Safari 打不开网页,因为无法连接到服务器
- 解决ScrollView自动滑动到底部的问题
- PyQt5中文基础教程3 菜单栏和工具栏
- layer.layerInfos为空的问题
- mac上所需软件的安装
- 使用动态代理拦截Android Activity的启动
- 一篇就够了系列之BroadcastReceiver全解析
- CSS深入之padding应用相关实现(二)
- 闪迪U3利用工具U3-Pwn
- sql锁表
- Edittext获取焦点问题
- COOKIE和SESSION有什么区别
- 神经网络隐藏层节点个数
- 暗黑兄弟不是中文界面问题处理