在 Magisk 注入 app 并嵌入 imgui (二) 里成功创建了 surface, 但是 imgui 的画面并没有显示出来,
看看 SurfaceFlinger 的信息.
1 | adb shell dumpsys SurfaceFlinger |
1 | Offscreen Layers: |
唉,我的 Layer 怎么在 Offscreen 里?
1 | Layer Shocker#0 (BufferStateLayer) callingPid:8669 callingUid:10219 ownerUid:10219 |
打开 imgui 可执行文件的版本.
看看有什么区别.
1 | + BufferStateLayer (ImGuiLink#0 screenFlags = 0 miuiVkWidgetTransparent = 0) uid=0 |
唉,发现可执行文件的 uid=0 而,app 创建的 surface 的 uid 不为 0.
去源码看看.
1 | 4353 bool addToRoot = callingThreadHasUnscopedSurfaceFlingerAccess(); |
http://aospxref.com/android-12.0.0_r3/s?refs=createLayer&project=frameworks
1 | 3888 bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache) { |
这里的 pid,uid 就是通过下面的函数获取的.
1 | 3890 const int pid = ipc->getCallingPid(); |
对于可执行文件来说,pid 和 uid 都是 0.
那么有没有办法让我们创建的 surface pid 和 uid 同时为 0 呢?
当然有…
Hook surfaceflinger 进程给 surface 开后门
最后做一个总结:
相比于外部 imgui,hook eglswapbuffers 来说,creteSurface 基本上是最优解,它既不会涉及到跨进程读写内存,也不会卡游戏画面.
唯一美中不足的地方就是编译复杂,没法跨安卓版本使用.