对于可执行文件创建的 surface 来说。它的 uid 和 pid 都为 0.
对于 app 内部创建的 surface 来说。它的 uid 和 pid 都不为 0.
见 Magisk 注入 app 并嵌入 imgui (三)
我们只需要找到 app 创建的 surface, 并把它的 pid 和 uid 改成 0, 就可以实现可执行文件的效果.
1. 注入 surfaceflinger 进程
参考:AndroidPtraceInject
参考:AndroidPtraceInject
2.Dobby hook createSurface
1 2 3 4 5 6 7 8 9 10 11 12
| int hook_createSurface() { LOGD("hook_createSurface start\n"); void *sym = DobbySymbolResolver(NULL, "_ZN7android6Client13createSurfaceERKNS_7String8EjjijRKNS_2spINS_7IBinderEEENS_13LayerMetadataEPS6_PNS4_INS_22IGraphicBufferProducerEEEPiPj"); if (NULL != sym) { LOGD("_ZN7android6Client13createSurfaceERKNS_7String8EjjijRKNS_2spINS_7IBinderEEENS_13LayerMetadataEPS6_PNS4_INS_22IGraphicBufferProducerEEEPiPj:%llx", (unsigned long long)sym); DobbyHook(sym, (void *)new_createSurface, (void **)&ori_createSurface); } LOGD("hook_createSurface finish\n"); return 0; }
|
3. 从 surface 的 name 拿到想要 hook 的 surface 的 pid 和 uid
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| static int64_t new_createSurface(void *thiz, void *a2, void *a3, void *a4, void *a5, void *a6, void *a7, void *a8, void *a9, void *a10, void *a11, void *a12) { if (NULL == ori_createSurface) { LOGE("failed to get original new_createSurface"); return false; } LOGD("str:%llx", *(unsigned long long *)*(unsigned long long *)a2);
if (*(unsigned long long *)*(unsigned long long *)a2 == 0x72656b636f6853) { LOGD("getCallingPid:%d", getCallingPid()); LOGD("getCallingUid:%d", getCallingUid()); Hook_Pid = getCallingPid(); Hook_Uid = getCallingUid(); } return ori_createSurface(thiz, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
|
4.Dobby hook getCallingPid 和 getCallingUid
Hook 代码省略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| static int64_t new_getCallingPid(void *thiz) { if (NULL == ori_getCallingPid) { LOGE("failed to get original new_getCallingPid"); return false; } int Pid = ori_getCallingPid(thiz); if (Pid == Hook_Pid) { Hook_Uid = getCallingUid(); return 0; } else { return Pid; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| static int64_t new_getCallingUid(void *thiz) { if (NULL == ori_getCallingUid) { LOGE("failed to get original new_getCallingUid"); return false; } int Uid = ori_getCallingUid(thiz); if (Uid == Hook_Uid) { return 0; } else { return Uid; } }
|
getCallingPid () 和 getCallingUid () 可以在 aosp 环境里封装一个.a 的静态库
编译的时候链接就行.
1 2 3 4 5 6 7 8 9 10 11
| int getCallingPid() { IPCThreadState *ipc = IPCThreadState::self(); return ipc->getCallingPid(); }
int getCallingUid() { IPCThreadState *ipc = IPCThreadState::self(); return ipc->getCallingUid(); }
|