KeepAlive 攻防指南:MIUI 为何封杀它?系统级防御与反制策略全解读
2026/9/14 18:12:33 网站建设 项目流程

KeepAlive 攻防指南:MIUI 为何封杀它?系统级防御与反制策略全解读

【免费下载链接】KeepAliveFighting against force-stop kill process on Android with binder ioctl / Android高级保活项目地址: https://gitcode.com/gh_mirrors/ke/KeepAlive

KeepAlive 是一个 Android 高级保活(进程复活)开源库,它通过 binder ioctl 直接与系统 binder 驱动通信,让被杀死的进程能被"守护进程"复活。本文带你彻底看懂它的攻防原理:为什么 MIUI 等定制系统会封杀它、系统层该如何防御、又该如何反制。

什么是 KeepAlive:Android 保活的"不死方案"

KeepAlive 在 Leoric(通过 JNI 复活进程)的基础上,实现了通过ioctl 复活进程,能最大程度提高复活率:

  • 🪶资源占用少,用户无感知
  • 🔁成功率高:在未被封杀的环境下(Android 4.4 ~ 9.0 模拟器)几乎"杀不死"
  • 📚 同时是学习binder 框架的优秀案例

⚠️ 作者明确提示:真机上不能保证保活成功(MIUI 等定制系统已封杀了这个方案),不建议在 C 端产品上使用。

保活原理:三个进程如何互相"守护"

一、进程结构:主进程 + 双守护

KeepAlive 把 App 拆成三个互相监听的进程(配置见library/src/main/java/com/boolbird/keepalive/KeepAliveConfigs.java):

进程默认名称角色
主进程App 包名业务逻辑,负责初始化保活
常驻进程:resident守护者 A,监控守护者 B
Daemon 助手android.process.daemon守护者 B,伪装成系统进程名

任一进程被杀,另外两个都会通过 binder 把它"拉起来",形成连环守护。

二、复活机制:绕过 Java API 直接喊话 AMS

核心实现在library/src/main/java/com/boolbird/keepalive/KeepAliveProcessImpl.java

  1. 反射拿到ActivityManagerNative的远程代理mRemote(即 ActivityManagerService 的 binder 对象);
  2. 按 AIDL 协议手工构造startService的 Parcel 数据——注意不同系统版本的 transaction code 不同(Android 9 为 24、8.0 为 30、7.x 为 26、4.4 为 34),这就是它只能覆盖 4.4~9.0 的原因;
  3. 一旦检测到目标进程死亡,直接调用mRemote.transact(code, parcel, null, 1),让系统"以为"是正常启动服务,进程原地复活。

三、监听机制:C++ 层的隐藏观察者

library/src/main/cpp/keep_alive.cpp(JNI 声明见library/src/main/java/com/boolbird/keepalive/NativeKeepAlive.java)实现了"进程死亡检测":

  • 双重fork派生隐藏子进程,并用setArgV0把进程名伪装成app_d,躲避ps排查;
  • 用 indicator 标记文件 +flock文件锁判断对方是否还活着:进程死亡时锁自动释放,观察者立刻发起 binder 复活;
  • 配合AlarmManager每 60 秒定时唤醒(见KeepAlive.launchAlarm)和bindService+linkToDeath死亡回调,多管齐下。

为防止"无限重启风暴",还内置了rebootThreshold(10s, 3):10 秒内连续重启超过 3 次就自动停用守护(实现见KeepAlive.checkProcessContinuousBootOverTimes)。

为什么 MIUI 会封杀 KeepAlive?

这套方案的隐藏前提是:"杀了我之后,系统还允许我启动新进程"

用户点击"强制停止"(am force-stop)时,标准流程是直接杀掉该应用的进程。但如果观察者进程在被打死前抢先发出一次transact,进程就复活了,保活成功。

MIUI 等定制 ROM 正是针对这个窗口期做了两处系统级改造(README「应对方法」一节给出的官方思路):

  1. force-stop 期间禁止启动新进程:系统为该应用打上"正在强杀"标记,标记存续期间,所有指向该应用的 startService/startActivity 请求被直接拒绝——观察者喊话也喊不出活来;
  2. 批量收集后统一击杀:不再"发现一个杀一个",而是先收集好应用的全部进程,必要时先发送 SIGSTOP 冻结,再统一 kill,杜绝任何进程在间隙中"偷跑"复活请求。

反制策略:一条命令冻结并终结观察者

项目根目录的 kill_alive.sh 就是压力测试脚本:循环 100 次执行am force-stop观察复活率。在未被改造的系统上,单条 force-stop 往往杀不干净,正确的终结姿势是(README 给出):

ps -A | grep `ps -A | grep keepalive | awk '{print $1}' | head -1` | awk '{print $2}' | xargs kill -19 && am force-stop com.boolbird.keepalive

拆解一下:

  • kill -19发送SIGSTOP,先把观察者进程冻结,让它彻底失去复活窗口;
  • 随后am force-stop再整体击杀。

这正是防御策略"先 SIGSTOP、后统一 kill"在攻击侧的直接应用——攻防双方博弈的核心,都在这几百毫秒的时间窗口里。

如何快速上手:4 步集成 KeepAlive

以 demo 模块app/为例:

  1. 注册保活配置:在 Application 的attachBaseContext中调用KeepAlive.init(base, configs),指定常驻 Service(demo:app/src/main/java/com/boolbird/keepalive/demo/MainApplication.java);
  2. 声明 Service:在app/src/main/AndroidManifest.xml中给 Service 设置独立进程:resident,Service 需继承KeepAliveService,否则在 Android 4.4 上无保活效果;
  3. 启动服务startService(...)即可自动唤醒保活进程;
  4. 可选增强configs.ignoreBatteryOptimization()忽略电池优化、configs.rebootThreshold(10*1000, 3)重启限频、configs.setOnBootReceivedListener(...)设置开机自启。

适用场景与注意事项

维度说明
✅ 推荐自研轻量定制 Android 系统对系统应用的保活
✅ 推荐作为binder 框架的学习案例
⚠️ 谨慎C 端(消费者)产品不建议使用
⚠️ 注意避免在 Application 中初始化第三方库,否则所有进程都会重复初始化

一句话总结:KeepAlive 用"三进程互守 + binder 直连 AMS"把复活率拉满,而 MIUI 的应对就是"强杀期间禁启 + 先冻结后集火"。理解了这场攻防,你也就读懂了 Android 进程保活与系统管控博弈的本质。

【免费下载链接】KeepAliveFighting against force-stop kill process on Android with binder ioctl / Android高级保活项目地址: https://gitcode.com/gh_mirrors/ke/KeepAlive

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询