先锋军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 ...
随机推荐
- [置顶] 轻量级语言Lua入门
作为一个脚本爱好者,而且是脚本(Perl)起家的我,一有空就喜欢学习下这些脚本语言.据说魔兽世界.愤怒小鸟都用到了它,所以今天研究下Lua这个叫法有点奇特的脚本 [转载请注明出处:http://blo ...
- Applet 数字签名技术完全攻略
这里说声对不起大家.毕竟2几年前,我想写这篇文章,但因为他才懒得一直没有写.同时也给自己的东西好.前些日子我老大让我又搞这个东西发现我曾经的资料没留,又凭着自己印象从新来过.但发现网上写的东西真的 ...
- C# 32位程序访问64位系统注册表
原文:C# 32位程序访问64位系统注册表 我的上一篇文章已经阐述了“32位程序和64位程序在64位平台上读\写注册表的区别”,那么接下来将要回答上篇所留下来的一个问题:32位程序如何访问64位系统注 ...
- URAL 1934 Black Spot --- 最短的简单修改
右侧是1.维护的同时保持最短路p值至少,我有直接存款(1-p).该概率不满足,为了使这个值极大. #include <iostream> #include <cstdlib> ...
- Linux学习记录--命名管道通信
命名管道通信 什么是命名管道 一个主要的限制是,它是匿名管道的应用还没有名字,因此,只有它可以用于进程间通信的方式与亲缘关系.在命名管道(named pipe或FIFO)提出后,该限制得到了克服.FI ...
- sql server事物控制
一.多个数据库 1.存储过程 2.Commit写在 Try...Catch后面 protected void Button1_Click(object sender, EventArgs e) ...
- JQuery Easy Ui (Tree树)详解(转)
第一讲:JQuery Easy Ui到底是什么呢? 首先咱们知道JQuery是对Java Script的封装,是一个js库,主要提供的功能是选择器,属性修改和事件绑定等等.. JQuery ui是在j ...
- 【HDU】5256 系列转换(上涨时间最长的序列修饰)
假设a[i]和a[j]我想的一样,满足条件的需要是 a[j] - a[i] > j - i 也就是说,a[i] - i < a[j] - j 例1 4 2 不满意,所以1和2必须有必要之间 ...
- xp硬盘安装Fedora14 过程记录及心得体会(fedora14 live版本680M 和fedora14 DVD版本3.2G的选择)
这次电脑奔溃了,奇怪的是直接ghost覆盖c盘竟然不中.之前电脑上硬盘安装的fedora14操作系统,也是双系统.不知道是不是这个问题,记得同学说过,在硬盘装fedora之后,要手动修改c盘隐藏的那个 ...
- Android 设计模式模式适配器
自定义适配器模式:一类的接口,转换成客户的期望,也是一个接口.适配器使原本接口不是与类兼容可以无缝.下面两个图看起来更加清晰 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...