首页
社区
课程
招聘
[原创]ANDROID 黑科技 : 保活机制深度逆向
发表于: 3天前 1224

[原创]ANDROID 黑科技 : 保活机制深度逆向

3天前
1224

在 Android 逆向与安全防护的博弈中,进程保活(Keep-Alive)始终是一个充满争议且技术密集的话题。随着 Android 系统的迭代,从早期的 1 像素 ActivityJobScheduler,到后来的各种同步账号机制,系统对后台进程的容忍度越来越低。

本文将以某头部大厂 APP 中的保活模块(libundead_native_ability_q.so)为例,深度剖析其在 Android 10+ (API 29及以上) 环境下,如何利用 C/C++ 层的双重 Fork 逃逸、Flock 文件锁监控以及纯 Native 层的 Binder 穿透技术,实现高隐蔽性、高存活率的“不死”机制。

通过对 APK 的初步分析,我们定位到核心的保活入口位于包 com.bytedance.platform.ka 下。针对高版本 Android 系统,应用采用了分层策略,其中针对 Android 10+ 的核心类为 KaAbilityQ

查看其反编译代码:

从这里可以看出,Java 层主要负责环境准备和参数收集(如当前进程名、各种开关 Flag),真正的硬核逻辑全部通过 doKaOnNative 交给了 libundead_native_ability_q.so 处理。

在 ServiceImpl 的 LIZIZ 函数中进行了参数初始化并调用了 LIZ 函数。

将 SO 拖入 IDA Pro 进行分析,定位到导出函数 Java_com_bytedance_platform_ka_ability_q_KaAbilityQ_doKaOnNative,内部调用了真实的实现逻辑 do_ka

该 SO 的核心保活流转经历了三个精妙的阶段:

为了防止系统在杀死主应用时,顺藤摸瓜将子进程“一锅端”,该组件在 Native 层实现了经典的 Double Fork 逃逸:

(注:与部分保活方案使用 Pipe 管道阻塞监控不同,这里脱离进程树是为了避免被 ActivityManagerService (AMS) 的 ProcessRecord.kill() 连坐查杀。)

脱离进程组后,守护进程需要一种极低功耗的方式来感知主进程的生死。轮询 /proc/ 目录显然太耗电且容易被查杀。

该组件巧妙地利用了 Linux 的 flock (File Lock) 机制:

这是该方案最为硬核的部分。当守护进程发现主进程死亡后,如果通过常规的 am start 命令行去拉起,不仅速度慢,而且极易被高版本 Android 的后台拦截机制阻断。

逆向伪代码显示,该 SO 直接引入了 NDK 的 AIBinder API,徒手拼接底层 IPC 数据包(Parcel):

守护进程提前在内存中组装好了一通向 ActivityManagerService 发送 startInstrumentation 事务的 Parcel 包。触发时,直接调用 AIBinder_transact 将伪造的请求发给 AMS。系统接收到请求后,会主动分配进程资源,拉起该 APP 注册的自定义 Instrumentation。应用随之在 callApplicationOnCreate 中完成复苏。

守护进程通过 AIBinder_transact 向 AMS 发起 startInstrumentation 请求,其底层完整的调用链涉及客户端 Binder 代理与服务端实现两个关键环节。

客户端代理实现android.app.IActivityManager 的 Stub 代理):

服务端真实处理ActivityManagerService.java):

以上两段代码完整展示了从客户端通过 Binder 事务码 51 发起 startInstrumentation 请求,到服务端 ActivityManagerService 进行权限校验、签名匹配、进程强制停止(或复用)以及 ActiveInstrumentation 注册的完整流程。守护进程正是利用这一底层通道,在主进程死亡后伪造合法请求,触发 AMS 重新分配进程并拉起自定义 Instrumentation,从而实现隐蔽唤醒。

该厂的保活方案代表了目前 Android 端企服/核心业务模块在进程驻留方面的一流水平。“Double Fork 逃避进程树监控 + Flock 零功耗挂起 + Native Binder 直接穿透 AMS” 的组合拳,巧妙绕过了 Java 层层层加码的系统限制。


传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 3天前 被易之生生编辑 ,原因:
收藏
免费 12
支持
分享
最新回复 (5)
雪    币: 4079
活跃值: (6309)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
2
好文章没人回复吗
3天前
0
雪    币: 176
活跃值: (1335)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
方案差不多已经失效了,国产厂商差不多都禁用了孤儿进程直接拉起binder,不过还是有一些骚套路可以绕过的
3天前
0
雪    币: 1550
活跃值: (4493)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
4
666
2天前
0
雪    币: 94
活跃值: (4722)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
666
2天前
0
雪    币: 100
活跃值: (526)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6

孤儿进程即使脱离了进程组,也无法脱离cgroup,注意不要把cgroup和进程组混为一谈。a15+杀进程,都是直接杀进程组了,所以这个方法理论无效

最后于 2天前 被mb_bvvcoitr编辑 ,原因:
2天前
0
游客
登录 | 注册 方可回帖
返回