前面分析的adbi框架和libinject都是使用so注入的方式,实现将指定代码装入目标进程,这种方式有几个特点:
1. 是动态的,需要目标进程已经启动
2. 无法影响全局,比如注入A进程挂钩里边libc.so的open函数,此时,B进程使用的libc.so的open函数还是老函数,linux系统通过COW机制,在你注入A进程并执行对open的挂钩的时候,拷贝了新的页面,放入新的函数。如果要影响全局,应该注入到类似 Zygote 这样的进程,且应该在zygote进程启动之后马上注入,这样后续zygote进程生成子进程时就能使用挂钩后的函数
3. 需要依赖ptrace机制,某些情况下,目标进程无法被执行ptrace,则这种方式会失效
这一篇我们分析另外一种方式,是著名的xposed框架使用的方式,不需要动态注入,而是直接替换android系统的一个可执行程序。
一,android应用层进程启动最初始的几步
linux系统装载并初始化各个子系统完毕后,执行第一个应用层程序init, android 的 init 程序是自己定制的,与其它linux发行版不一样,它同样会解析并执行 init.rc 配置文件。其中,有一步如下,调用 app_process 程序启动 zygote 进程,xposed 替换的就是这个 /system/bin/app_process 程序
system/core/rootdir/init.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-servercla