0%

Magisk注入app并嵌入imgui(二)

之前我写过一篇文章介绍了 Magisk 注入 app 并嵌入 imgui.
其原理就是 Hook app 进程的 eglSwapBuffers 函数。在其中完成 imgui 的初始化的显示.

但我测试 UE4 游戏的时候发现,要么画面出不来,要么就闪退.
大概率是和引擎冲突了…
淦.

没办法,那么就创建一个 surface.
注意,createSurface 等函数需要 aosp 环境。所以需要在 aosp 环境里编译 zygisk 模块.

环境和工具

1.Android 12 环境 (版本可根据自己真机版本选择,硬盘空间最好大于 250G, 不然拉取失败会出现很多问题)
2.wsl 或虚拟机 (wsl Ubuntu18.04)
3. 安卓真机 (小米 12)

过程

下载 Android12, 编译 Android12.

这些网上有很多教学,值得一提的是,相比 Android5, 新版本编译的时候没有什么错误,基本上一次过。很爽.

Android 系统开发系列(1):Android 12 源代码下载、编译和刷机

死磕 Android_AOSP 编译过程

注意:硬盘剩余空间一定要大于 250g, 硬盘剩余空间一定要大于 250g, 硬盘剩余空间一定要大于 250g
否则失败了会很麻烦.

复制源文件到 Android 源码里

参考 Android 可执行文件 imgui 绘制,区别就是编译成动态库 (cc_library_shared), 还要把 zygisk 头文件丢进去.

文件结构如上图.

过滤到包名,多线程创建 imgui

1
2
3
4
5
6
7
8
9
10
11
void postAppSpecialize(const AppSpecializeArgs *args) override
{
// Use JNI to fetch our process name
const char *process = env->GetStringUTFChars(args->nice_name, nullptr);
if (init(process) == false)
{
//没有找到游戏
api->setOption(zygisk::Option::DLCLOSE_MODULE_LIBRARY);
}
env->ReleaseStringUTFChars(args->nice_name, process);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool init(const char *process)
{
// LOGD("example: process=[%s]", process);
if (strcmp(hook_pkg_name, process) == 0)
{
pthread_t ntid;
if (pthread_create(&ntid, nullptr, startImGui, nullptr))
{
LOGD("can't create thread");
}
return true;
}
return false;
}

这里 startImGui 的代码和 Android 可执行文件 imgui 绘制代码一致.

观察结果

然后你会发现完全没有效果,但这并不意味着创建 surface 失败了,因为如果你打印 surface 的地址,会发现是有值的,如果你在 tick 打印日志,会发现日志会一直有输出.

为啥会这样呢?

Magisk 注入 app 并嵌入 imgui (三).