安卓进程保活方案记录(双重fork+文件锁+手搓parcel)

最近看到一个安卓保活的文章,挺震惊的,都2026年还能搞保活,记录一下。

从文章来看应该是字节和腾讯都用了这种方案,核心上是一样的。

1.双重fork

进程保活首先要解决一个问题,进程被杀了谁来重新唤起。此方案采用子进程唤醒的方式重新拉起主进程,但是安卓8.0之后,应用进入后台后,系统可能杀死主进程及其所有子进程,所以需要想办法解决这个问题。

在Linux/Android中,父进程死亡后,子进程会由init进程接管,即其父进程变成init,通过这种方法使子进程逃逸出进程组,即其与原先的父进程没有关系了,这样子就不会被一锅端掉。

实现方法是native层fork一个子进程,子进程在fork一个孙进程,然后将子进程exit,这样子孙进程就成功逃逸了。

2.监听父进程死亡

逃逸出来的进程需要知道父进程是否死亡,然后在其死亡时唤醒父进程。查询父进程是否还在,可以访问 /proc/ 目录,看当前系统的进程有哪些,但是轮询显然太耗电且容易被查杀。这个方案巧妙使用了锁的机制。

首先父进程一开始对一个文件进行加锁,逃逸出来的子进程尝试对同一个文件进行flock,由于互斥锁的存在,此进程会被内核挂起阻塞(或者 usleep 轮询),不占用 CPU 资源;如果父进程死亡,操作系统回收其文件句柄,那么子进程被唤醒拿到锁,这时代表父进程被杀,需要唤起父进程。

3.手搓ipc数据包(Parcel)拉起app

当子进程发现主进程死亡后,如果通过常规的 am start 命令行去拉起,不仅速度慢,而且极易被高版本 Android 的后台拦截机制阻断。

此方案在native层引入了NDK 的 AIBinder API,徒手拼接底层 IPC 数据包(Parcel),提前在内存中组装好了一个向 ActivityManagerService 发送 startInstrumentation 事务的 Parcel 包。触发时,直接调用 AIBinder_transact 将伪造的请求发给 AMS。系统接收到请求后,会主动分配进程资源,拉起该 APP 注册的自定义 Instrumentation。应用随之在 callApplicationOnCreate中启动,完成唤起。

在主进程死亡后伪造合法请求,触发 AMS 重新分配进程并拉起自定义 Instrumentation,从而实现隐蔽唤醒。

相关推荐
s_nshine5 分钟前
释放C盘,迁移studio相关数据到其他盘
android·windows·android studio·内存·c盘
韩曙亮32 分钟前
【Flutter】Flutter 中的 Android / iOS 特殊配置 ① ( 网络权限配置 | HTTP 明文传输配置 | 应用名称配置 )
android·网络·flutter·http·ios·网络权限
_李小白33 分钟前
【android opencv学习笔记】Day 31:提取轮廓之Canny算法
android·opencv·学习
hashiqimiya1 小时前
每日android布局xml文件
android·xml·gitee
m0_738120722 小时前
渗透测试基础——PHP 序列化数据结构与反序列化机制详解
android·服务器·网络·数据结构·安全·php
故渊at2 小时前
第二板块:Android 四大组件标准化学理 | 第十一篇:组件间通信(IPC)与 Binder 深度解析
android·binder·组件化·组件间通信
ZC跨境爬虫2 小时前
跟着 MDN 学JavaScript day_10:数组——数据的有序集合
android·java·开发语言·前端·javascript
消失的旧时光-19433 小时前
Kotlin 协程设计思想(九):Flow 到底是什么?为什么 suspend 函数还需要 Flow?
android·kotlin·协程·协程异常
消失的旧时光-19433 小时前
Kotlin 协程设计思想(八):suspend 到底是什么?为什么 suspend 不是开启协程?
android·kotlin·suspend·continuation