Prop 解析 – 检测对抗原理

Prop 有什么用

一般是风控检测,因为包含很多有效信息
而其中有很多字段是不可读的
这也就对我们修改提出了挑战

Prop 的产生

https://blog.csdn.net/zhangjg_blog/article/details/122057945

现有的修改方案

resetprop

resetprop 是一个由 magisk 开发团队提供的工具,用于修改 Android Property

https://blog.canyie.top/2022/04/09/property-implementation-and-isolation/

这篇博客里面讲了一些关于系统是如何解析 Prop 的,以及 resetprop 是如何工作的一些内容。
简单来说,就是去 /dev/properties/property_info 这里读取二进制的 prop 然后加载到内存中
而 resetprop 则是直接和 prop service(这个服务的 socket 文件也在 /dev/properties/)通信,进行修改

手动修改

在 /system/build.prop 中存在着一些 prop,但是这个文件,由于 system 本身不可写,因此也是不可写的
但是解决方法很简单,直接把 system mount 成 rw 即可

mount -o rw,remount /system

修改完成之后

chmod 644 /system/build.prop
mount -o ro,remount /system

之后软重启即可

什么,你不知道怎么软重启? killall zygote (确信)

注意必须软重启,不然会被覆盖

方案的缺陷

使用 nullptr 的 native test,我们很快就能发现其会报 Property Modified,尤其是我们开启了 zygisk 的情况下

我们知道作为一个实用工具提供的 resetprop 被 ksu 和 magisk 用于修改系统的 prop。那么是不是 resetprop 的问题呢?

关闭 zygisk,在系统启动之后使用 resetprop

Prop 解析 - 检测对抗原理

还是正常,并且在两个手机上都通过了测试

另一种方案同样通过了测试,而且也不会显示 Inconsistent Mount

但是缺陷确实存在,而且看起来只是当这个工具在 init 之前被使用才会出现

Update:我是傻呗,和 resetprop 无关,只要不挂载 system 就可以了。。。

OpenGL

通过 libhwui 获取 prop 会有问题,具体请看下一节

检测

  1. 检测 selinux
  2. 手动尝试解析 /dev/__properties/
  3. 利用 EGL 和 CacheProperty

EGL 和 CachedProperty

由于 Android 手机不同时,EGL 库储存的位置也不一样,因此安卓提供了一个方案,就是通过 prop 值来确定 EGL 库的位置
因此,在初始化 EGL 的时候要求 prop 不能被修改,可以创建线程
(p.s. 我个人阅读源码
https://android.googlesource.com/platform/frameworks/native/+/refs/heads/main/opengl/libs/EGL/Loader.cpp

的时候没有发现这个问题,不是很懂,但是有很多检测器是这么做的。可以试试 )

CachedProperty

详见 properties.h
可以调用缓存的 prop,存在检测的可能

UPDATE: resetprop

通过 setprop/getprop 等手段操作 property 实际上是操作了位于 /dev/property 下的文件。按 property 各自的 SELinux Context 存储,相同的 context 分为一组,存储在一个文件内。每个文件大小为固定的 128KB。需要使用的 prop_bt prop_info 等对象由一个线性内存分配器实现,每次分配内存时只是简单地 bump 地址,不支持释放内存。
更多细节可以查看 https://blog.canyie.top/2022/04/09/property-implementation-and-isolation/

Magisk 的 resetprop 在删除 property 时,会将 prop_bt 中指向 prop_info 的引用置空,然后清空整个 prop_info 的内存。问题就发生在这里,prop_info 的内存被清空但并没有被释放,这就导致对应内存位置出现一片很大的空区域。通过检测这里,应用可以检测到对应属性区域有属性被删除了,进而推断出设备已经 root(因为正常情况 property 是不支持删除的)。

什么时候会发生删除操作?通过 resetprop 重置 ro 也就是只读属性时。而保存着 bootloader 锁定状态的多个 property 和保存着 native bridge 的 ro.dalvik.vm.native.bridge 还有经常被修改的设备指纹都是只读属性。也就是说,除非避免修改这些属性,否则就会被检测到,而不修改 bootloader 状态的属性又会导致里面直接存着“已解锁”,应用一样可以读到。

https://github.com/topjohnwu/Magisk/commit/f41994cb52ca08856216a8da0a28ed148c833f4e 过后,作为副作用,上面的问题刚好被缓解,但还有另一个问题:

prop_info 上有一个字段叫 serial,当这个 prop_info 被更新时,serial 会自增 2。也就是说,prop 被更新的次数 = serial / 2。而对于 ro 属性,它们是只读的,正常情况根本无法被更新,因此 serial 应该始终保持为 0。也就是说,如果发现 serial 不为 0 的只读属性,就代表它被 resetprop 过。

正文完
 0
评论(没有评论)