BootloaderSpoofer 源码导读:一个 Xposed 模块如何让“已解锁 Bootloader“在密钥认证中伪装成“已锁定“ BootloaderSpoofer 源码导读一个 Xposed 模块如何让已解锁 Bootloader在密钥认证中伪装成已锁定【免费下载链接】BootloaderSpooferSpoof locked bootloader on local attestations项目地址: https://gitcode.com/gh_mirrors/bo/BootloaderSpoofer项目速览它解决什么问题BootloaderSpoofer 是一个 Android Xposed 模块Xposed 是一种通过 hook 系统方法修改其他 App 行为的框架模块通常没有自己的界面纯靠代码生效。它解决的问题是Android 的密钥认证Key Attestation机制会把Bootloader 是否锁定写进证书扩展设备一解锁就能被服务器或本地校验识破这个模块通过在本地拦截证书链生成过程把bootloaderState伪装成已锁定从而骗过依赖本地认证的 App。一句话定位一个把解锁状态伪装成锁定状态的 Android 本地密钥认证欺骗工具。适合人群研究 Android Key Attestation 机制的安全爱好者以及想让自己的设备通过某些本地完整性校验的开发者。核心能力与使用场景伪造 RootOfTrust 扩展重写证书中的信任根字段把未引导/未锁定改成已锁定bootedTRUE还能补上noAuthRequired、系统版本、补丁级别等字段能帮你让本地校验方看到一份设备状态健康的证书。隐藏系统认证能力hookhasSystemFeature让应用以为设备不支持 StrongBox 和安全芯片认证从而走本地软件/TEE认证路径能帮你把校验流程引导到模块能篡改的环节。替换密钥对生成把 AndroidKeyStore 的密钥生成替换为内置的一对 EC RSA 密钥能帮你保证后续签名环节可控。指定作用范围通过 Xposed scope 只作用于目标 App如io.github.vvb2060.keyattestation认证测试工具能帮你避免全局 hook 带来的副作用。典型场景你有一台解锁了 Bootloader 的手机某个 App比如密钥认证测试工具会在本地生成密钥并检查证书链中的信任根判定设备不可信。安装本模块并选中目标 App 后同样的操作会返回Bootloader 已锁定的证书链本地校验通过。关键文件与入口解析这个项目的全部业务逻辑集中在一个 Java 文件里其余都是 Xposed 模块的外壳。Xposed.java —— 所有逻辑都在这一个文件位置app/src/main/java/es/chiteroman/bootloaderspoofer/Xposed.java它是模块的唯一入口类约 660 行实现IXposedHookLoadPackage接口。逻辑分四步走静态块解析内置的 PEM 格式密钥EC RSA 各一对和一批预置的中间证书。hook 系统特性查询if (PackageManager.FEATURE_STRONGBOX_KEYSTORE.equals(featureName)) param.setResult(Boolean.FALSE); else if (PackageManager.FEATURE_KEYSTORE_APP_ATTEST_KEY.equals(featureName)) param.setResult(Boolean.FALSE); else if (android.software.device_id_attestation.equals(featureName)) param.setResult(Boolean.FALSE);白话说目标 App 问你这手机有没有安全芯片/安全元件认证能力时模块回答没有迫使认证走本地路径——只有本地生成的证书链才能被模块改写。hook 密钥生成把KeyPairGenerator.generateKeyPair直接替换成内置密钥对并 hooksetAttestationChallenge偷偷记下认证挑战值challenge后面重签证书时会原样填回去。hook 证书链返回核心中的核心拦截engineGetCertificateChain拿到真实证书链后解析 ASN.1 结构里的 Attestation 扩展OID1.3.6.1.4.1.11129.2.1.17替换其中第 704 号字段RootOfTrustASN1Encodable[] rootOfTrustEncodables {new DEROctetString(bytes1), ASN1Boolean.TRUE, new ASN1Enumerated(0), new DEROctetString(bytes2)};这里第 2 个元素就是bootloaderState模块直接硬编码成TRUE已锁定。改这一行比如改成FALSE就回到真实状态了。改完后用内置私钥重新签名返回一份看起来完全合法的证书链。整个项目最精彩、也最需要重点阅读的就是addHackedExtension和createHackedExtensions这两个方法。xposed_init —— Xposed 模块的启动开关位置app/src/main/assets/xposed_init只有一行内容模块入口类的全限定名es.chiteroman.bootloaderspoofer.Xposed。Xposed 框架装模块时靠它找到入口类改错类名模块就不会加载。理解 Xposed 模块机制的话这个文件是必读的第一课。AndroidManifest.xml —— 声明我是 Xposed 模块位置app/src/main/AndroidManifest.xml注意它没有任何 Activity——模块没有界面。关键内容是几段meta-dataxposedmoduletrue向框架表明这是模块xposedminversion82要求 Xposed API 82 以上低于此版本的框架会拒绝加载xposedscope指向数组资源指定默认作用范围。arrays.xml —— 模块默认作用于哪些 App位置app/src/main/res/values/arrays.xmlstring-array namescope itemio.github.vvb2060.keyattestation/item itemio.github.vvb2060.mahoshojo/item /string-array前一项是密钥认证测试工具后一项是一款需要设备完整性校验的移动端游戏。想让自己的 App 被 hook把包名加进这里即可实际运行时也可以在 Xposed 框架里手动勾选范围。app/build.gradle —— 依赖只有两个位置app/build.gradlecompileOnly de.robv.android.xposed:api:82 implementation org.bouncycastle:bcpkix-jdk18on:1.78.1Xposed API 是compileOnly——只在编译期存在运行时由框架提供所以打包进去的 APK 不含有 Xposed 代码BouncyCastle 负责 PEM 解析和 X.509 证书构建是真正打进 APK 的依赖。minSdk 26Android 8.0以上才能用。项目目录导航BootloaderSpoofer/ ├── app/ │ ├── build.gradle # 模块构建脚本与依赖 │ └── src/main/ │ ├── AndroidManifest.xml # Xposed 模块元信息 │ ├── assets/xposed_init # 入口类声明一行 │ ├── java/es/chiteroman/bootloaderspoofer/Xposed.java # 全部核心逻辑 │ └── res/values/ # 应用名与作用范围 ├── build.gradle # 根构建脚本AGP 8.5.2 ├── settings.gradle # 声明 Xposed 仓库等依赖源 ├── gradle.properties # Gradle 全局属性 └── gradle/wrapper/ # Gradle 8.9 包装器路径用途app/src/main/java/es/chiteroman/bootloaderspoofer/Xposed.java核心hook 证书链并伪造锁定状态app/src/main/assets/xposed_init模块入口声明app/src/main/AndroidManifest.xml模块元信息描述、最低 API 版本、范围app/src/main/res/values/arrays.xml默认作用范围包名列表app/build.gradle依赖与 SDK 版本配置settings.gradle添加了https://api.xposed.info/作为 Xposed API 仓库构建与配置说明 构建前提JDK 17、Android SDKcompileSdk 35。克隆后执行git clone https://gitcode.com/gh_mirrors/bo/BootloaderSpoofer cd BootloaderSpoofer ./gradlew assembleRelease产物在app/build/outputs/apk/release/安装后需要在 Xposed/LSPosed 框架中勾选模块并选中目标 App 才能生效。几个值得注意的配置项app/build.gradle 中的versionCode 40 / versionName 4.0版本号偏保守是刻意的伪装证书里的系统版本字段osVersion130000即 Android 13在源码中写死如果你的系统更新到更高版本改这里才能保持版本自洽。settings.gradle 中的 Xposed 仓库删掉maven { url https://api.xposed.info/ }后依赖解析会失败这个仓库是 Xposed API 的唯一来源。gradle.properties 中的org.gradle.jvmargs-Xmx2048m给 Gradle 守护进程 2G 内存内存小的构建机可以调小但低于 1G 大概率 OOM。延伸阅读与下一步项目自述见 README.md一句话说明了项目目标Spoof locked bootloader on local attestations在本地认证中伪装锁定的 Bootloader。想深入 Android 侧细节可以对照 AOSP 的KeyMint/attestation文档理解证书扩展 OID1.3.6.1.4.1.11129.2.1.17每个字段的含义再回头看createHackedExtensions会清晰很多。两个建议的下一步动手实验在模拟器或备用机上装好 LSPosed配合keyattestation测试 App分别对比模块开启前后证书链中bootloaderState字段的差异——这是理解本项目的最快方式。跟踪一个字段从setAttestationChallenge的 hook 开始跟一次 challenge 值如何被记下、又如何被填回新证书串起整个数据流。最后提醒一句模块内置的密钥对是写死在源码里的公开密钥仅适合学习与本地研究场景不要用于任何规避真实风控的生产用途。【免费下载链接】BootloaderSpooferSpoof locked bootloader on local attestations项目地址: https://gitcode.com/gh_mirrors/bo/BootloaderSpoofer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考