0%

Hook surfaceflinger进程给surface开后门

对于可执行文件创建的 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)
{
// LOGD("new_createSurface");
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) //这里根据surface的名字来判断是否是要Hook的surface.strcmp()会闪退,只能用字符串的16进制来比较.
{
LOGD("getCallingPid:%d", getCallingPid());
LOGD("getCallingUid:%d", getCallingUid());
Hook_Pid = getCallingPid(); //这里拿到Pid
Hook_Uid = getCallingUid(); //Uid
}
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)
{
// LOGD("new_getCallingPid");
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(); //更新Uid
return 0; //如果是我们创建的surface,就返回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)
{
// LOGD("new_getCallingUid");
if (NULL == ori_getCallingUid)
{
LOGE("failed to get original new_getCallingUid");
return false;
}
int Uid = ori_getCallingUid(thiz);
if (Uid == Hook_Uid)
{
// LOGE("Hook Uid");
return 0; // 如果是我们创建的surface,就返回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();
}