Build.* 与 SystemProperties 两条通道的覆盖范围
Java Build.* 层
这是最常用的一层 API,几乎所有应用都会读:
| 字段 | Hook 方式 | 备注 |
|---|---|---|
| Build.BRAND | 替换字段值 | 品牌 |
| Build.MANUFACTURER | 替换字段值 | 制造商,留空则不 Hook |
| Build.MODEL | 替换字段值 | 型号 |
| Build.DEVICE | 替换字段值 | 设备代号 |
| Build.PRODUCT | 替换字段值 | 产品代号 |
| Build.BOARD | 替换字段值 | 主板代号 |
| Build.HARDWARE | 替换字段值 | 硬件/CPU 代号 |
| Build.FINGERPRINT | 自动拼接生成 | 不手动填 |
| Build.ID | 替换字段值 | 构建 ID |
| Build.HOST | 替换字段值 | 构建主机 |
| Build.USER | 替换字段值 | 构建用户 |
| Build.TIME | 替换字段值 | 构建时间戳 |
| Build.DISPLAY | 替换字段值 | 显示名称 |
Build.VERSION.* 版本号
| 字段 | 备注 |
|---|---|
| Build.VERSION.RELEASE | Android 版本号,如 14 |
| Build.VERSION.INCREMENTAL | 增量版本,如 UP1A.231005.07 |
| Build.VERSION.SECURITY_PATCH | 安全补丁日期 |
| Build.VERSION.SDK_INT | ⚠️ 通常取自真机,改了应用会崩 |
API 级别不能改。应用会根据 SDK_INT 做运行时分支,改成不存在的值会直接崩溃。
SystemProperties 层 — 最容易漏的一层
很多应用和完整性检查根本不读 Java Build 类,而是直接读系统属性。Guise 覆盖 23 个 ro.* 键,包括:
ro.product.brandro.product.modelro.product.devicero.product.namero.product.manufacturerro.build.display.idro.build.fingerprintro.build.idro.build.typero.build.tagsro.build.version.releasero.build.version.incrementalro.build.version.security_patch- ……等 23 个构建相关属性
为什么属性层必须同时 Hook
假设你只 Hook 了 Build.MODEL = "Pixel 7",但没 Hook ro.product.model:
- 应用 A 用
Build.MODEL读 → 看到 Pixel 7 ✅ - 应用 B 用
SystemProperties.get("ro.product.model")读 → 看到真机 Redmi ❌ - 完整性检查 SDK 两边都读 → 检测到矛盾 → 标记可疑 ❌
只 Hook Java 层、属性层漏了——这是改机模块「半残」最常见的样子。 Guise 两条通道同步覆盖,你改一个字段,两层一起变。
Build.getSerial()
自 Android 8 起 Build.SERIAL 常量恒为 UNKNOWN。真正被调用的是 Build.getSerial() 方法——Guise 专门 Hook 这个入口,返回配置好的序列号。