Android Property 实现解析与黑魔法
2022年4月9日 17:30
Android Property (属性系统)可谓是 Android 中使用最广泛的进程间信息共享机制了,如 app 获取系统版本号,就是通过属性系统传递的信息;对于如此常用的底层机制,你可能知道 getprop SystemProperties __system_property_get 这些 API,但是,你真的了解它吗?这次,我们不但要会遵守规则用这些 API,我们还要成为规则的缔造者,让系统为我们服务!Let’s go!
系统实现分析
首先,我们有这几个问题需要解答:
ro.开头的属性是只读的,只能被设置一次,系统是怎么实现的?- 系统里的属性那么多,难免会有一些 app 读取不了的敏感属性,系统是怎么限制我们读取的?
Linus 大神有句话很出名:“Read the F*cking Source Code。”想要解答这些问题,阅读源码是必须的。
Property Context
我们通常使用 __system_properties_get 这个 API 去获取系统属性,点开这个函数看看:
1 | static SystemProperties system_properties; |
先去调用 Find() 函数找到一个叫做 prop_info* 的东西,然后从里面读出值来。
1 | const prop_info* SystemProperties::Find(const char* name) { |
看到这里你是不是一头雾水,这函数有个 initialized_ 一看就是要初始化的,谁去初始化的?contexts_ prop_area 又是什么?这里就不卖关子了,在 libc.so 被加载的时候,它的 .init.array 段里面的函数会被自动执行,而有 __attribute__((constructor(1)) 的函数就会被放到 .init.array 段从而被自动执行。里面兜兜转转,会调用一个 __system_properties_init() 函数,而这个函数正是初始化上面这些东西的关键所在。