前言
Android 使用 dex2oat 进行 dex 编译,类 Xposed 框架为了防止方法内联钩子失效,需要设置系统属性 dalvik.vm.dex2oat-flags=--inline-max-code-units=0
,这可以很容易被检测到。
解决
方案
套一个假的 wrapper,在其中执行真正的 dex2oat,并添加参数 --inline-max-code-units=0
。
问题
- dex2oat 由 installd 启动,installd 以 root 权限运行,但在 exec dex2oat 前会执行降权,降权后的 dex2oat 权限与普通应用一致,无法直接访问
magisk --path
- linker 会识别
/apex/<name>/bin
下的二进制并自动链接一些动态库,original bin 若不在/apex
下,启动时会找不到库 - 需要防止 wrapper 本身被检测到
实现
使用类似 riru 的方案,在 /dev
中建立一个随机目录,并在开机时将路径动态 hexpatch 进 wrapper 的 bin;在 /dev
目录建立建立 socket,由 unshared daemon 打开 origin bin 得到 fd,发送到 wrapper 并 fexecve
。
不过 /apex/com.android.art/bin/dex2oat*
的 context 是 u:object_r:dex2oat_exec:s0
,wrapper 加载会触发 avc: denied { execute_no_trans }
,即使让 wrapper 的 context 为 u:r:installd:s0
仍然会触发,原因未知,因此采取折中方案复制一份 origin bin 放在 tmpdir,chcon u:object_r:magisk_file:s0
并在 daemon mount 到 /apex
再发送 fd。
1 条评论
您好,我想学习xposed相关的模块的开发,例如基于lsposed的。请问可以有一些建议给我不,在需要了解的技术上和学习途径上的。我自己有一定的编程能力,主要语言为Java和Js。