Android 应用卸载监控的实现方法

不再主业折腾 Android 了,这段时间会陆续把之前折腾过的东西记录一下,免得日后忘记。

对于产品经理和运营来说,知道哪个用户,什么时候,为什么会卸载你的 app 可能是很重要的事。虽然我觉得挺扯蛋——看看国内那些应用在卸载时弹出的页面,可选原因 12345,列的比用户想的都全面周到——这分明就是在说,我也知道自己干了很多坏事让你们不爽,可我干的坏事是如此之多以至于我实在弄不清你们的底线在哪里。

好吧,在我朝可以有理想,但是不能太理想主义。所以本文只从技术角度讨论一些实现细节。

首先来看这篇文章,基本勾勒出了实现卸载监控所需的技术框架。这篇文章有以下几个关键字:

  • JNI
    Android 应用被卸载之前,其运行实例就会被停止掉。因此必须要有代码能够脱离应用的生命周期管理。这个入口就是 JNI。进入 c 的世界,想象空间完全不是 Android API 可以比拟。
  • fork
    对于卸载监控这个需求来说,JNI 是入口,为的就是进入 fork 这一环。fork 本身是比 Java 更为历史悠久的系统调用,在这里负责生成监控进程,是整个逻辑中非常关键的一环。至少要把 fork 示例的执行逻辑搞懂(系统补习的话当然是建议读 APUE 相关章节,后面 exec 也会用到)。
  • inotify
    Linux 特有的文件监控 api,IBM 这篇介绍的很好。
  • UserSerial
    这个是 Android 4.2+ 引入的安全机制,原文说的很清楚,这里不再赘述。
但是这篇文章的实现方案两个明显不足:
  • fork 出来的进程仍旧是一个带着 dalvik 的庞大进程(内存 20MiB+)
  • 通过进程父子关系较容易找到卸载监控进程
所以,针对上述不足,可以继续改良实现方案:
  • exec
    将 inotify 部分的逻辑抽离到独立的可执行文件中,fork 出来的监控进程,可以通过 exec 这个独立的可执行文件来将自己变成一个非常轻量级的监控进程(内存占用只有 KiB 级别),同时也可以通过参数将伪装自己的进程名字。其实 fork + exec 的组合在传统的 unix 多进程编程中非常常见。
  • 两次 fork
    为了断绝父子进程关系,可以通过两次 fork 的技巧。主进程 A 通过 JNI 调用,进行第一次 fork,其父进程 A 继续运行,子进程 B 调用 exec 成为监控进程。监控进程 B 再进行一次 fork,父进程 B 直接退出,子进程 C 执行 inotify 逻辑监控 app 目录。由于进程 C 的父进程 B 直接退出,进程 C 将直接成为 init 的子进程,进程 C 和原始进程 A 之间看不到明显的关联关系。
上述技术环节打通之后,剩下的就是细节的打磨了。下面这些问题都比较简单,或是影响较小。考虑到我厂在黑科技上的投入,恕不巨细无遗了。

  • inotify 是面向 inode 的。当可执行文件在运行中被删除,inode 还在不在?会触发哪些 inotify 事件?文件夹呢?所以监控哪个目录,选择哪个 inotify 事件其实还是挺有讲究的事情。这些问题追到底其实很考较对 Linux 文件子系统的理解。
  • 如何将运行时参数(比如用户 id)传递给监控进程?监控进程既然已经跟主进程没有任何关系,那么在监控进程孤悬海外期间,主进程的用户 id 变化了怎么办?
  • 覆盖安装、升级时候的误判怎么办?360 某应用的方案竟然是在反馈页面中直接加了个『我在升级/重装』的选项,挺有意思。
  • 应该在主进程的哪个时间点启动监控进程?在 thread 中执行了 fork 会怎么样?fork 过的进程中线程还都在吗?fork 执行时父进程是个 Android 进程,而 Android 进程都是从 zygote 进程 fork 出来的。这样的进程直接 fork 会有问题吗?zygote 都做了些什么事让 fork 可能存在风险?
  • 如何避免多个监控进程同时存在?
  • 默认 ndk-build 编译出来的可执行文件 stdin/stdout/stderr 都被重定向到了 /dev/null,非常不利于调试,怎么办?

评论

7m7qwnf0oz说…
We have been round for greater than twenty Reusable EVA Shower Caps years offering customized solutions for canopies, sunshades, walkways, and a number of|various|a variety of} other|and a number of} other} other architectural parts that improve the look of your constructing. We associate with common contractors, architects, and engineers offering not only manufacturing and design services, but set up as well. Our 650,000 sq. toes of production house can handle any project. The strategy of stamping forms the spine of the engraving market, which consists of a vast vary of metallic merchandise that bear engravings of initials, names, pictures and design motifs.