先锋军Android注射技术《三》
继续
Component Injection
原理
android:process
process
attribute.<manifest>
element.with the same certificate.
shared with other applications, reducing resource usage.
演示样例二
com.demo.host
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo.host"
android:sharedUserId="com.demo"
android:versionCode="1"
android:versionName="1.0" > <application
android:name=".DemoApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:process="com.demo"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> <uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="9" /> </manifest>
关键代码
package com.demo.host; import android.app.Activity;
import android.content.ContentResolver;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log; /**
*
* @author boyliang
*
*/
public final class MainActivity extends Activity {
private static int sA = 1; public static void setA(int a) {
sA = a;
} public static int getA() {
return sA;
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://demo_contentprovider");
resolver.query(uri, null, null, null, null); new Thread() { public void run() {
while (true) {
Log.i("TTT", "" + getA());
setA(getA() + 1); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; }.start();
}
}
host一启动,就立即调用ContentResolver的query,这个正是Inject里的ContentProvider组件。
com.demo.inject
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo.inject"
android:sharedUserId="com.demo"
android:versionCode="1"
android:versionName="1.0" > <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:process="com.demo"
android:theme="@style/AppTheme" > <provider
android:name=".DemoContentProvider"
android:authorities="demo_contentprovider"
android:exported="false" /> </application> <uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="9" /> </manifest>
关键代码
<span style="white-space:pre"> </span>@Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) { final Timer timer = new Timer("demo");
timer.schedule(new TimerTask() { @Override
public void run() {
try {
Log.i("TTT", ">>>>>>>>>>>>>I am in, I am a bad boy!!!!<<<<<<<<<<<<<<\n");
//Class<?> MainActivity_class = Class.forName("com.demo.host.MainActivity");
Context context = ContexHunter.getContext();
ClassLoader classloader = context.getClass().getClassLoader();
Class<?> MainActivity_class = classloader.loadClass("com.demo.host.MainActivity");
Method setA_method = MainActivity_class.getDeclaredMethod("setA", int.class);
setA_method.invoke(null, 998);
} catch (Exception e) {
e.printStackTrace();
} timer.cancel();
} }, 5000); return null;
}
inject中,当query被调用后。会等待5s,然后通过反射调用host的MainActivity.setA方法,改动打印的数值。
绕过ClassLoader双亲托付
当我们尝试在DemoContentProvider通过Class.forNmae寻找MainActivity时,必定会抛ClassNotFoundException。唯一可行的方案是找到host的PathClassLoader,然后通过这个ClassLoader寻找MainActivity。我们须要寻找的变量须要满足例如以下条件:
- 这个变量必须由host产生的;
- 这个变量必须是全局的,并且其引用会保存在BootClassLoader(也就是Android SDK中的某个引用)。
- 能够通过反射机制读取到;
通过阅读源代码。发现能够通过以下的方式读取到Application对象:
- 假设是System_Process。能够通过例如以下方式获取
Context context = ActivityThread.mSystemContext
- 假设是非System_Process(即普通的Android进程)。能够通过例如以下方式获取
Context context = ((ApplicationThread)RuntimeInit.getApplicationObject()).app_obj.this$0
输出
I/TTT ( 633): com.demo.inject starts.
I/TTT ( 633): com.demo.host starts
I/TTT ( 633): 1
I/TTT ( 633): 2
I/TTT ( 633): 3
I/TTT ( 633): 4
I/TTT ( 633): 5
I/TTT ( 633): >>>>>>>>>>>>>I am in, I am a bad boy!!!!<<<<<<<<<<<<<<
I/TTT ( 633): 998
I/TTT ( 633): 999
I/TTT ( 633): 1000
I/TTT ( 633): 1001
I/TTT ( 633): 1002
I/TTT ( 633): 1003
从前二行就能够看出,这两个组件都是执行在同一个进程的。从第5秒開始。打印的数据開始发生变化,证明我们的注入逻辑生效了。
最后
版权声明:本文博主原创文章,博客,未经同意不得转载。
先锋军Android注射技术《三》的更多相关文章
- Android动画 三种动画
Android可以使用三种动画 Frame Animation-帧动画 ,就像GIF图片,通过一系列Drawable依次显示来模拟动画的效果 Tween Animation-补间动画,给出两个关键帧, ...
- 【转】Android LCD(三):Samsung LCD接口篇
关键词:android LCD控制器 Framebuffer PWM 平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:samsung exynos ...
- 【转】android camera(三):camera V4L2 FIMC
关键词:android camera CMM 模组 camera参数 CAMIF V4L2 平台信息:内核:linux系统:android 平台:S5PV310(samsung exynos ...
- Android LCD(三):Samsung LCD接口篇
关键词:android LCD控制器 Framebuffer PWM 平台信息: 内核:linux2.6/linux3.0 系统:android/android4.0 平台:samsung exy ...
- Android中三种超实用的滑屏方式汇总(转载)
Android中三种超实用的滑屏方式汇总 现如今主流的Android应用中,都少不了左右滑动滚屏这项功能,(貌似现在好多人使用智能机都习惯性的有事没事的左右滑屏,也不知道在干什么...嘿嘿),由于 ...
- Android Studio(三):设置Android Studio编码
Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...
- 我的Android第三章
先看效果图. 点击之后出变成 按钮内容改变了,并且弹出一个小提示 下面我们就来看看如何实现这个小案例 1)先打开string.xml文件,把要定义的字符串资源放置在里面 2)然后我们要画页面,基本An ...
- Android入门(三)Activity-生命周期与启动模式
原文链接:http://www.orlion.ga/432/ 一.活动的生命周期 1.返回栈 Android中的活动是可以重叠的,我们每启动一个新的活动,就会覆盖在原活动之上,然后点击Back键会销毁 ...
- 修正 XE5 Android 键盘三个问题
说明:XE5 在 Android 平台上存在这一些键盘操作的问题,目前发现有下列几种: 按键盘上的隐藏键后,无法按上一页(需要修改 XE5 源码「FMX.VirtualKeyboard.Android ...
随机推荐
- 修改linux系统时间、rtc时间以及时间同步
修改linux的系统时间用date -s [MMDDhhmm[[CC]YY][.ss]] 但是系统重启就会从新和硬件时钟同步. 要想永久修改系统时间,就需要如下命令:hwclock hwclock - ...
- 雷人的一幕:国外的codeproject论坛竟有人发“中文贴”.....
潜水近一年,头一次见国人在此发“中文贴”,截图留个“纪念”....
- RPC模式的Hub操作
signalR 专题—— 第四篇 模拟RPC模式的Hub操作 在之前的文章中,我们使用的都是持久连接,但是使用持久连接的话,这种模拟socket的形式使用起来还是很不方便的,比如只有一个唯一的 O ...
- 代写java程序qq:928900200
学校为全面提升学校教学质量,提高管理水平,决定开发一套小型成绩管理系统,实现以下功能.1) 系统用户分为管理员.教师和学生三种角色,每种角色都可以包含若干个用户.其中管理员登录后可以进行教师.学生 ...
- Oracle SQL Lesson (10) - 使用DDL语句创建和管理表
数据库对象TableViewSequenceIndexSynonym 对象名称最长30个字符,不能与当前用户下其他对象重名.create table "select" as sel ...
- vs修错小知识,相当于我自己的笔记,需要的人可以看下
在出现这种外部错误时,首先得检查你自己的的类的方法是否都以及实现了,我就是出现没有实现某些方法所以报出这个错误!!! 结果是onExit()方法我定义了没有去实现它. (待续)
- J2SE习题(2)
第四.五周练习题 1.a. Define a class called BlogEntry that could be used to store an entry for a Weblog. Th ...
- 检验身份证的正确性(Golang版本)
// CheckID_card project main.go package main /* * ai -> a1 , a2, a3, a4, a5, a6... a17 (a18 是校验码) ...
- Android 设计模式模式适配器
自定义适配器模式:一类的接口,转换成客户的期望,也是一个接口.适配器使原本接口不是与类兼容可以无缝.下面两个图看起来更加清晰 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...
- 基于lua的网页脚本开发语言cgilua(转)
这里为大家介绍基于lua脚本实现的网页开发语言,cgilua 介绍 cgilua使用Lua是一个用于创建动态网页的服务器端脚本语言.纯LUA脚本和LUA页(LP)的支持,cgilua.Lua脚本是一个 ...