做完硬件断点记录器后就开始研究如何隐藏Android的Bootloader锁了,当然最近没啥兴趣继续研究了,把目前为止的思路发出来
首先想到的一个方向是要先spoof安卓Setting里的oemlock status
在aoxpxref网站上搜索
bootloader unlocked
看到一个可疑的文件
/frameworks/base/core/java/android/service/oemlock/OemLockManager.java
xref 找到
/frameworks/base/services/core/java/com/android/server/oemlock/OemLockService.java
看到函数
可以看到Setting检测的是系统属性 ro.boot.flash.locked
来判断Bootloader是否解锁
AOSP搜索ro.boot.flash.locked
,发现/system/core/init/init.cpp
有初始化该属性值的代码
ro.boot.flash.locked
的值是受到 ro.boot.verifiedbootstate
的值影响
google搜了一下后面的这个属性,发现这个属性可能的值有red,orange,yellow,green
看到一个隐藏bl锁的github项目
https://github.com/topjohnwu/Magisk/blob/3c04dab47274e9bbbfb3ddd1fcf71c929c8ed0c0/native/jni/magiskhide/hide_policy.cpp#L12
看到替换表
可以确定green是bl未解锁,还有一个 ro.boot.vbmeta.device_state
要改成locked状态,实机看这个属性解锁bl状态下是unlocked,除了前三个之外其他属性解bl之后没变
还有 googleplay service 的验证
https://developer.android.com/training/safetynet/attestation
https://developer.android.com/google/play/integrity/overview
对应的解决方案是
https://github.com/kdrag0n/safetynet-fix
这个问题不大,国内又不用googleplay service
按照上述总结一下,隐藏bl锁需要修改以下属性
Java层最终会调用native_get
方法获取Property的值
顺着native_get
找到函数__system_property_find
这个是用户层标准的获取property值的函数,来自libc.so,往下翻就是android property系统的实现了,可以看这篇文章
https://bbs.kanxue.com/thread-274100.htm
进用户层初始化property service的地方
/system/core/init/property_service.cpp
找到函数 PropertyInit
从名字猜测这是init进程初始化系统基本property值的地方,ProcessBootconfig
和ProcessKernelCmdline
最后是通过读取/proc/bootconfig
和/proc/cmdline
调用_system_property_add
来设置ro.boot.verifiedbootstate
和ro.boot.vbmeta.device_state
的值
cat一下这两个设备文件,确实有相关信息
我想到了三个思路
kernel版本 5.10.168 路径/common/fs/proc/bootconfig.c
中的proc_boot_config_init
函数初始化了/proc/bootconfig
的输出,顺着全局变量 xbc_data
找到系统获取bootconfig的地方/common/init/main.c -> setup_bootconfig
, 可以看到bootconfig是从initrd里拿的
将返回的data copy进全局变量,然后由驱动打印出来看到数据
尝试文本替换
实验发现替换 uuid 和 vbmeta.device_state 系统正常启动,一旦修改 verifiedbootstate 系统就无法启动了,第一个思路就结束在这里了
先说结果: 成功了!!!!!!
安卓的linker使用的是mmap映射的elf文件,hook do_mmap的返回处,判断pgoff和filepath就能拦截到init进程加载libc.so,在这个时机里对_system_property_add函数下execute hook,
hook回调里对参数进行简单处理
修改成功
成功 Spoof Setting
第三个方法暂时没试过,感兴趣的可以试试看
有空就把第二个思路用kprobe来实现hook,包装成驱动连带硬件断点记录器分别开源到github上
刚入坑安卓,如有不对的地方或者有其他方法检测bl锁请大佬们在评论区指出!!!
private
static
final
String FLASH_LOCK_PROP =
"ro.boot.flash.locked"
;
private
static
final
String FLASH_LOCK_UNLOCKED =
"0"
public
boolean
isDeviceOemUnlocked() {
enforceOemUnlockReadPermission();
String locked = SystemProperties.get(FLASH_LOCK_PROP);
switch
(locked) {
case
FLASH_LOCK_UNLOCKED:
return
true
;
default
:
return
false
;
}
}
private
static
final
String FLASH_LOCK_PROP =
"ro.boot.flash.locked"
;
private
static
final
String FLASH_LOCK_UNLOCKED =
"0"
public
boolean
isDeviceOemUnlocked() {
enforceOemUnlockReadPermission();
String locked = SystemProperties.get(FLASH_LOCK_PROP);
switch
(locked) {
case
FLASH_LOCK_UNLOCKED:
return
true
;
default
:
return
false
;
}
}
static
void
export_oem_lock_status() {
if
(!android::base::GetBoolProperty(
"ro.oem_unlock_supported"
,
false
)) {
return
;
}
SetProperty(
"ro.boot.flash.locked"
,
android::base::GetProperty(
"ro.boot.verifiedbootstate"
,
""
) ==
"orange"
?
"0"
:
"1"
);
}
static
void
export_oem_lock_status() {
if
(!android::base::GetBoolProperty(
"ro.oem_unlock_supported"
,
false
)) {
return
;
}
SetProperty(
"ro.boot.flash.locked"
,
android::base::GetProperty(
"ro.boot.verifiedbootstate"
,
""
) ==
"orange"
?
"0"
:
"1"
);
}
static
const
char
*prop_key[] =
{
"ro.boot.vbmeta.device_state"
,
"ro.boot.verifiedbootstate"
,
"ro.boot.flash.locked"
,
"ro.boot.veritymode"
,
"ro.boot.warranty_bit"
,
"ro.warranty_bit"
,
"ro.debuggable"
,
"ro.secure"
,
"ro.build.type"
,
"ro.build.tags"
,
"ro.vendor.boot.warranty_bit"
,
"ro.vendor.warranty_bit"
,
"vendor.boot.vbmeta.device_state"
, nullptr };
static
const
char
*prop_val[] =
{
"locked"
,
"green"
,
"1"
,
"enforcing"
,
"0"
,
"0"
,
"0"
,
"1"
,
"user"
,
"release-keys"
,
"0"
,
"0"
,
"locked"
, nullptr };
static
const
char
*prop_key[] =
{
"ro.boot.vbmeta.device_state"
,
"ro.boot.verifiedbootstate"
,
"ro.boot.flash.locked"
,
"ro.boot.veritymode"
,
"ro.boot.warranty_bit"
,
"ro.warranty_bit"
,
"ro.debuggable"
,
"ro.secure"
,
"ro.build.type"
,
"ro.build.tags"
,
"ro.vendor.boot.warranty_bit"
,
"ro.vendor.warranty_bit"
,
"vendor.boot.vbmeta.device_state"
, nullptr };
static
const
char
*prop_val[] =
{
"locked"
,
"green"
,
"1"
,
"enforcing"
,
"0"
,
"0"
,
"0"
,
"1"
,
"user"
,
"release-keys"
,
"0"
,
"0"
,
"locked"
, nullptr };
Property |
Value |
ro.boot.flash.locked |
1 |
ro.boot.verifiedbootstate |
green |
ro.boot.vbmeta.device_state |
locked |
adb shell su
-
c cat
/
proc
/
bootconfig
androidboot.hardware
=
"qcom"
androidboot.memcg
=
"1"
androidboot.usbcontroller
=
"a600000.dwc3"
androidboot.bootdevice
=
"1d84000.ufshc"
androidboot.boot_devices
=
"soc/1d84000.ufshc"
androidboot.prjname
=
"22803"
androidboot.startupmode
=
"pwrkey"
androidboot.mode
=
"normal"
androidboot.product.hardware.sku
=
"0"
androidboot.hw_region_id
=
"1"
androidboot.serialno
=
"xxxxxxx"
androidboot.baseband
=
"msm"
androidboot.dtbo_idx
=
"12"
androidboot.dtb_idx
=
"1"
androidboot.force_normal_boot
=
"0"
androidboot.fstab_suffix
=
"default"
androidboot.verifiedbootstate
=
"orange"
androidboot.keymaster
=
"1"
androidboot.vbmeta.device
=
"PARTUUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
androidboot.vbmeta.avb_version
=
"1.0"
androidboot.vbmeta.device_state
=
"unlocked"
androidboot.vbmeta.hash_alg
=
"sha256"
androidboot.vbmeta.size
=
"23232"
androidboot.vbmeta.digest
=
"xxxxx"
androidboot.vbmeta.invalidate_on_error
=
"yes"
androidboot.veritymode
=
"enforcing"
androidboot.slot_suffix
=
"_a"
adb shell su
-
c cat
/
proc
/
bootconfig
androidboot.hardware
=
"qcom"
androidboot.memcg
=
"1"
androidboot.usbcontroller
=
"a600000.dwc3"
androidboot.bootdevice
=
"1d84000.ufshc"
androidboot.boot_devices
=
"soc/1d84000.ufshc"
androidboot.prjname
=
"22803"
androidboot.startupmode
=
"pwrkey"
androidboot.mode
=
"normal"
androidboot.product.hardware.sku
=
"0"
androidboot.hw_region_id
=
"1"
androidboot.serialno
=
"xxxxxxx"
androidboot.baseband
=
"msm"
androidboot.dtbo_idx
=
"12"
androidboot.dtb_idx
=
"1"
androidboot.force_normal_boot
=
"0"
androidboot.fstab_suffix
=
"default"
androidboot.verifiedbootstate
=
"orange"
androidboot.keymaster
=
"1"
androidboot.vbmeta.device
=
"PARTUUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
androidboot.vbmeta.avb_version
=
"1.0"
androidboot.vbmeta.device_state
=
"unlocked"
androidboot.vbmeta.hash_alg
=
"sha256"
androidboot.vbmeta.size
=
"23232"
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2023-8-17 23:40
被cslime编辑
,原因: 修复图片