记录对 riru (riru-hide) 注入 so 后的检测与对抗.
原理
被 riru-hide 隐藏的 so 是一段匿名内存,但与大部分匿名内存不同,他的权限位会出现 "x"(可执行).
通过检测 maps 文件中的匿名内存权限位是否有 "x" 来判断这段内存是不是 riru-hide 隐藏的 so.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| char line[512]; FILE* fp; fp = fopen("/proc/self/maps", "r"); if (fp) { while (fgets(line, 512, fp)) { char* part[6]; part[0] = strtok(line, " "); int i=1; while(i<6) { part[i] = strtok(NULL, " "); i++; } if (strcmp(part[5],"\n")==0){ if (strstr(part[1],"x")){ LOGD("发现权限有x的匿名内存,地址:%s",part[0]); } }
} LOGD("没有发现权限有x的匿名内存"); fclose(fp); }
|
对抗
至于对抗,只需要把 Hook 逻辑直接写进 Riru 里就行,不要让 Riru 加载 so 模块.
1. 下载 Riru 源码
1
| git clone https://github.com/RikkaApps/Riru.git
|
2. 修改 nativeForkAndSpecialize_pre 和 nativeForkAndSpecialize_post 函数代码
nativeForkAndSpecialize_post
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
| static void nativeForkAndSpecialize_post(JNIEnv *env, jclass clazz, jint uid, jboolean is_child_zygote, jint res) {
LOGI("nativeForkAndSpecialize_post"); }
|
nativeSpecializeAppProcess_pre
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 30 31
| static void nativeSpecializeAppProcess_pre( JNIEnv *env, jclass clazz, jint &uid, jint &gid, jintArray &gids, jint &runtimeFlags, jobjectArray &rlimits, jint &mountExternal, jstring &seInfo, jstring &niceName, jboolean &startChildZygote, jstring &instructionSet, jstring &appDataDir, jboolean &isTopApp, jobjectArray &pkgDataInfoList, jobjectArray &whitelistedDataInfoList, jboolean &bindMountAppDataDirs, jboolean &bindMountAppStorageDirs) {
LOGI("nativeSpecializeAppProcess_pre"); }
|
3. 编译
1
| gradlew :riru:assembleRelease
|
如果报错,看看是不是少了 local.properties 文件
4. 安装
略…
效果
最后效果如图