Xposed检测与自定义Xposed
- 前言:
-
- Xposed检测
-
-
- 1、遍历App安装列表检测
- 2、自造异常检测堆栈信息。
- 3、检查关键Java方法是否变为native方法
- 4、反射XposedHelper类和XposedBridge类
- 5、检测Xposed相关文件
- 6、Root检测
- 7、安全建议
-
- 自定义Xposed
-
- 一、修改XposedBridge.jar包名
- 二、修改Xposed相关文件名
- 三、修改installer包名
前言:
Xposed已经诞生很多年了,用的人多自然检测Xposed的app也多,同样的从Xposed衍生出去的一些自定义的框架也多。
Xposed检测
先对一些常见的检测手段做个概述,这方面的帖子很多,请自行查找资料。
1、遍历App安装列表检测
调用PackageManager的系统API来遍历App安装列表,辨别是否有安装Xposed Installer相关的软件包,比如de.robv.android.xposed.installer
这是最简单的检测,要过这个检测修改installer包名即可,后续内容中给出自定义方案。
2、自造异常检测堆栈信息。
- Android系统启动过程中,init进程会去解析init.rc文件启动一系列的服务,其中就有app_process进程,在app_process执行过程中,会设置自身进程名为Zygote,启动com.android.internal.os.ZygoteInit.Main方法
- Xposed修改了app_process,会先启动de.robv.android.xposed.XposedBridge.Main方法,再由它去启动com.android.internal.os.ZygoteInit.Main方法,因此堆栈信息中会多出一些内容。
这里分两种堆栈,第一种函数没有被Hook(进程依然是被注入的)情况下

可以看到多了一个de.robv.android.xposed.XposedBridge.Main,要过这个检测就像上图一样,修改XposedBridge.jar包名和类名即可,后续内容中给出自定义方案。
第二种是函数被Hook情况下
出现在堆栈中的handleHookMethod、afterHookedMethod、beforeHookedMethod等常用函数都可以检测,相关帖子已经很多了,这里不再展开。要过这个检测的话,修改函数名即可。其中修改handleHookMethod,需要同步修改so层JNI代码。
3、检查关键Java方法是否变为native方法
- Xposed把Method的nativefunc修改为它自己的处理函数,再这个函数中会回调Java层的handleHookMethod,处理函数钩子。
- 但是只有native函数,虚拟机才会走nativefunc,所以Xposed会把Java函数的修饰符修改为native。
- 通过反射调用Modifier.isNative(method.getModifiers())方法可以校验方法是不是native方法。
- 要过这个检测的话,Hook getModifiers修改返回值即可。
4、反射XposedHelper类和XposedBridge类
- Xposed中有几个比较常用的方法,findAndHookMethod等。通过反射找到要Hook的函数后会保存到XposedHelper类中的fieldCache、methodCache、constructorCache字段中。
- 因此,可以通过反射遍历XposedHelper类中的fieldCache、methodCache、constructorCache变量,读取HashMap缓存字段
- 也可以通过反射de.robv.android.xposed.XposedBridge的disableHooks字段来禁用Xposed
- 要过这个检测,其实跟第二种检测一样,只要修改XposedBridge.jar包名和类名即可。
5、检测Xposed相关文件
- /system/frameworks目录下的xposed.prop和XposedBridge.jar
- /system/lib目录下的libxposed_art.so
- 主要也就是检测以上三个文件了。而检测可以通过读取proc/self/maps文件,遍历自身加载的库。也可以通过遍历PathClassLoader的pathList字段来检测。
6、Root检测
- 获取default.prop 中文件ro.secure的值不为1
- 在各种目录下检测到有su程序
- 其实吧,Xposed在Hook的时候是不需要root权限的,它只是在替换文件的时候需要Root权限。也就是一开始就把Xposed集成到系统中去的话,是可以不用Root也能Hook的。
7、安全建议
在art环境下,Xposed需要修改libart.so来为XposedBrige.jar提供服务
很少有修改libart.so里面的函数的,因此可以遍历libart.so的导出表,检测是否包含xposed字眼
自定义Xposed
首先你要会Android系统编译,原版Xposed框架编译,这个资料有很多,这里不再展开。
Xposed框架编译前先编译一次Android系统,可以编译user版本,不需要Root权限
一、修改XposedBridge.jar包名
用AndroidStudio修改包名很方便,因为你改完包名后他会自动修改所有的引用。
改完这个包名还不够,还需要修改清单文件里面的包名。
把编译后的app-release-unsigned.apk改为XposedBridge.jar
AOSP源码中frameworks/base/cmds/xposed
终端在这个目录下执行 grep ‘robv’ -r ./ 搜索关键字
把搜索到的以下内容替换包名即可
xposed_shared.h文件暂时先不动,其他3个文件6个地方改掉。
编译Xposed框架, 至于如何编译,资料很多,自行找查找资料
这里以nexus 5手机5.1的系统为例,编译完事后。
1、把aosp/out/sdk22/arm/files下的system整个文件夹替换到aosp/out/target/product/hammerhead下的system目录
2、把system/bin目录下的app_process32删掉,把app_process32_xposed改成app_process32
3、把之前编译的XposedBridge.jar放到system/framework下
4、终端回到源码根目录make snod 打包成镜像文件system.img 进行刷机
5、编译api.jar,写代码要用
6、由于XposedBridge.jar的包名修改了,所有Xposed模块里的引用也要相应修改。
到此就把Xposed集成到系统了,并且免RootHook
二、修改Xposed相关文件名
这个比较简单,修改画框的这几个文件名即可
编译Xposed框架后,先修改相关文件名,然后按第一部分的方法集成到系统即可。
修改了xposed.prop文件名后,会导致installer读不到这个文件而判定Xposed未安装,所以还要修改installer相关代码,请看后续内容。
三、修改installer包名
1、在GitHub下载installer工程,这里除了在AndroidStudio中修改包名,以及清单文件中的包名以外,还需要把gradle里面的applicationId修改掉。
2、还需要修改XposedBridge.jar工程里面的路径,因为他需要根据这个路径去读取要加载的模块列表
3、还记得自定义修改第二部分说的,修改了xposed.prop文件名后,会导致installer读不到这个文件而判定Xposed未安装吗?看下图就明白了
4、还记得自定义第一部分的时候说的暂时不改的那个文件么?
在aosp源码中把xposed_shared.h文件两个地方的路径改掉
5、按之前的方法编译,然后怼到手机里
在GitHub上找了个检测Xposed的app
从这里便能看出来这个app只是一个简单的检测,我们如果需要检测Xposed还需要其他的方法。比如Xposed检测中的第7条。很少有去修改libart.so的
修改后的Xposed我这里就不放出来了,大家自己动手丰衣足食吧。
技术交流QQ群 894821295