系统属性读写与 Binder 包装:两个进阶接口
这组接口面向「往系统层再探一步」的场景:读写系统属性、以特权身份拿系统服务的 Binder。
系统属性:StellarSystemProperties
// 读取
val brand = StellarSystemProperties.get("ro.product.brand")
val sdk = StellarSystemProperties.getInt("ro.build.version.sdk", 0)
val dumpable = StellarSystemProperties.getBoolean("persist.debug.something", false)
// 写入(需要相应权限)
StellarSystemProperties.set("persist.debug.something", "true")
读写边界随启动通道变化
| 通道 | 可写属性 |
|---|---|
| ADB 模式(uid=2000) | debug.*、persist.debug.*、log.*、vendor.debug.* |
| Root 模式(uid=0) | 大部分属性(ro.* 只读属性除外) |
写不进去时先看服务的运行模式——很多「set 无效」的问题根源在这里,见服务状态解读。
Binder 包装:StellarBinderWrapper
需要直接调用系统服务接口时,把拿到的 Binder 包一层,即可获得特权访问:
val binder = StellarBinderWrapper.getSystemService("package")
val pm = IPackageManager.Stub.asInterface(binder)
// 之后即可使用特权 PackageManager API
配合 transactRemote(data, reply, flags) 可以转发原始 Binder 事务——兼容层对 Shizuku API 的转发走的也是同一条通路,原理见兼容层。
使用提醒
- 系统属性名是系统资产,跨版本可能改名或失效,写入前确认目标属性在当前系统上的语义;
set操作不可逆的属性(如部分persist.*)要谨慎,改前记录原值;- 这两类接口同样受命令安全里说的边界约束:能力越大,确认越多。