Android Xposed 学习笔记

| 分类 Android  | 标签 Android  Xposed 

0x00 前言

现在写偏技术点的文章都喜欢写个前言,介绍一下背景,吹吹牛逼,其乐无穷。话说这个Xposed刚开始接触的时候,还真觉得是个挺高端的技术,看原理看了一上午也没有看出个什么名堂出来,但即使不懂它的原理,知道怎么用对于我们这些代码“打包者”来说也就足够了,自我写程序以来一直都有一个观念——很多东西没必要去了解原理,用的时候网上一搜然后复制粘贴下来就可以用了。所以到如今还是很多普通的代码也不会写,例如java里面的InputStreamReader,StreamReader,Reader,BufferedReader这些类到底有什么区别,什么时候该用哪个,每次要用的时候都是网上一搜然后一切都解决了,当然对于项目开发来说这也并没有什么不妥,但是对于个人的长期发展来说始终是有很大的弊端。不过算了,慢慢改吧,再来说说这个Xposed,最开始是github上rovo89大牛设计的针对Android平台的动态劫持项目,所谓劫持,其实就是类似与windows系统下的钩子,当遇到特定的事件触发时,先跳转到我们预定的函数去执行,然后再执行正常的功能。

0x01 搭建开发环境

  • 新建Android项目,并导入XposedBridgeApi.jar,然后修改项目中的AndroidMainfest.xml,添加如下几行。
1
2
3
4
5
6
7
8
9
<meta-data
            android:name="xposedmodule"
            android:value="true" />
        <meta-data
            android:name="xposeddescription"
            android:value="" />
        <meta-data
            android:name="xposedminversion"
            android:value="30" />
  • 手机必须获取Root权限,然后安装XposedInstaller,安装完之后如下图,在模块中勾选要开发的项目名。
  • 推荐安装RE管理器,因为每次修改完重新安装项目后都要保证,/data/data/de.robv.android.xposed.installer/conf/modules.list中应用的位置与实际位置相匹配,否则就会导致xposed无法运行。
  • 一般的开发步骤也就是这样,但是在开始编写hook函数时,还需要提前反编译目标应用从而获得相应的类名和函数名。

0x02 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;

public class Test2 implements IXposedHookLoadPackage{

	@Override
	public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
		// TODO 自动生成的方法存根

		if (lpparam.packageName.contains("com.tencent.mm")){  // 要挂钩的应用启动时

			
			// 挂钩相应的函数, String.class, ClassLoader.class是函数a的参数

			findAndHookMethod("com.tencent.mm.compatible.util.m", lpparam.classLoader,"a",String.class, ClassLoader.class,new XC_MethodHook() {
				@Override
			     protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
//			    	

			     }
			     @Override
			     protected void afterHookedMethod(MethodHookParam param) throws Throwable {
			    	 
			     }
			});
		}
	}
	
}

0x04 遇到的几个问题

虽然说是在Xposed项目中遇到几个小问题,但是在其他java或者Android项目中也还是可能会遇到的,所以记录一下相应的解决方法。

在调用Runtime执行adb shell指令时中文乱码

说到这个问题,又想起我当时被坑的情形了。。。大家都知道Xposed调试起来不是那么方便,而且又是运行外部进程,更加的不知所以。解决的方法就是在传入参数之前先进行编码,如我使用的就是Base64编码,然后进程中再进行解码,这个方法也可以解决很多类似的问题。

使用adb shell在手机中创建相册后,图库却无法显示

首先通过RE管理器我们就可以发现手机的相册都存放在/storage/emulated/0/DCIM/目录下,但是我通过程序在这个目录下创建文件夹并且加入图片后发现图库中怎么也刷新不了新创建的文件夹和图片。最后解决方法是创建完文件夹之后要调用系统函数扫描一遍所有添加的文件,代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 获取目录下所有文件名

	public List<String> getAllFile(File dir){
		List<String> res = new ArrayList<String>();
		File[] files = dir.listFiles();
		for(int i=0;i<files.length;i++){
			if( files[i].isFile() ) res.add(files[i].getPath());
		}
		return res;
	}
	
	// 扫描一遍所有文件

	public void scanSdCard(String dir) {
		File file = new File(dir);
		List<String> files = getAllFile(file);
		XposedBridge.log("dir:" + dir + " " + files.size());
		String[] path = new String[files.size()] ;
		for(int i=0;i<files.size();i++){
			path[i] =  files.get(i);
		}
		
		MediaScannerConnection.scanFile(launchActivity,
				path, null,
                new MediaScannerConnection.OnScanCompletedListener() {
            public void onScanCompleted(String path, Uri uri) {
     //       	XposedBridge.log("ExternalStorage"+"Scanned " + path + ":");

            }
        });
		 
	 }

最后,关于Xposed详细的原理介绍请参考博客http://blog.csdn.net/wxyyxc1992/article/details/17320911,看完这篇文章虽然没有看懂多少,但是深切体会到人外有人啊,自己还是太弱了!


上一篇     下一篇