(一)xposed 检测
1. 每一个被hook的进程,都会将xposed 的相关库文件和jar 文件加载到相应的进程空间中,如图:
这里看到进程空间中加载了
1)app_process32_xposed
2)libxposed_art.so
3)XResourcesSuperClass.dex
既然能看到,一般的应用都会使用读取maps 文件的方法检测到,如何规避呢:
1)刷机关键字替换。
2)hook 相关的函数做到读取文件伪装。(maps 函数,open 函数)
2. 通过PackageManager查看安装列表
最简单的检测,PackageManager
的API来遍历系统中应用程序安装的情况来辨别是否有安装Xposed Installer
相关的软件包。
PackageManager packageManager = context.getPackageManager();
List applicationInfoList = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo applicationInfo: applicationInfoList) {
if (applicationInfo.packageName.equals("de.robv.android.xposed.installer")) {
// is Xposed TODO... }
}
既然能看到,一般的应用都会使用系统的方法检测到,如何规避呢:
1)代理或者替换使不可见。
3. classloader 检测
android 未安装Xposed框架时的Android应用中的ClassLoader
Xposed挟持后的classloader
所以可以检测, 反检测方法有。
4 异常读取栈
try { throw new Exception("blah"); } catch(Exception e) { for (StackTraceElement stackTraceElement: e.getStackTrace()) { // stackTraceElement.getClassName() stackTraceElement.getMethodName() 是否存 在Xposed } }
所以可以检测, 反检测方法也有。
5. 反射调用读取Xposed相关类和方法。
1) 反射调用xposed 的某一个关键类和关键方法是否在classloader 中存在。
6. 检查关键Java方法被变为Native JNI方法
当一个Android App中的Java
方法被莫名其妙地变成了Native JNI
方法,则非常有可能被Xposed Hook
了。由此可得,检查关键方法是不是变成Native JNI
方法,也可以检测是否被Hook。
通过反射调用Modifier.isNative(method.getModifiers())
方法可以校验方法是不是Native JNI
方法,Xposed同样可以篡改isNative
这个方法的返回值。
7. 判断某些xposed 的库的导出函数的特征信息,基于载入库文件的文件名或文件路径。
void* lookup_symbol(char* libraryname,char* symbolname)
{ void *imagehandle = dlopen(libraryname, RTLD_GLOBAL | RTLD_NOW);
if (imagehandle != NULL){ void * sym = dlsym(imagehandle, symbolname);
if (sym != NULL){ return sym; //发现Cydia Substrate相关模块 } ...
}
8.反hook 的检测, 每一个函数在编译连接后加载到内存后每一条指令是一定的,位置一定的。
这个是maps 文件 so 基于segment 加载的分布, 第一行包含代码段是可以执行的。其他两个相关的bss 和数据,栈段。
可以读取maps 文件 的某一个so 的某一个函数进行特征分析。
1)取样分析函数的机器码的变化。
9. mprotect 函数可以动态改变内存地址的rwx 属性。(可以采取自身kook)