android OEM unlocking分析

在测试CTS Verifier测试的时候,有一项为开发者选项"OEM unlocking"功能,测试的时候需要人为进行判断是否成功。
测试此项前,需要执行如下动作:

adb shell settings put global hidden_api_policy 1

adb install -r -g  CtsVerifier.apk

adb install -r -t CtsEmptyDeviceOwner.apk

adb shell dpm set-device-owner com.android.cts.emptydeviceowner/.EmptyDeviceAdmin

在这里插入图片描述

然后进入开发者选项,查看OEM unlocking选项后面,是否会弹出一个“!”的图标,点击会弹出一个动画框,能否弹出对话框是根据设备是否已lock来判断的。在bootloader中执行fastboot flashing lock后,此项就可以通过了。

查看lock和unlocked时的系统属性,
$ getprop |grep lock
[cache_key.is_user_unlocked]: [8110559973390150548]
[ro.boot.flash.locked]: [1]
[ro.boot.vbmeta.device_state]: [locked]
[ro.frp.pst]: [/dev/block/bootdevice/by-name/frp]
[ro.oem_unlock_supported]: [1]
[sys.oem_unlock_allowed]: [1]

$ getprop |grep lock
[cache_key.is_user_unlocked]: [8110559973390150548]
[ro.boot.flash.locked]: [1]
[ro.boot.vbmeta.device_state]: [locked]
[ro.frp.pst]: [/dev/block/bootdevice/by-name/frp]
[ro.oem_unlock_supported]: [1]
[sys.oem_unlock_allowed]: [0]


带着这个问题,我们看一下OEM unlocking的内容,主要是根据opengrok跟一下代码的调用过程,内容如下:


settings层===
EnableOemUnlockSettingWarningDialog.java onClick
host.onOemUnlockDialogConfirmed();
|

DevelopmentDashboardFragment.java   onOemUnlockDialogConfirmed()
@Override
public void onOemUnlockDialogConfirmed() {
	final OemUnlockPreferenceController controller = getDevelopmentOptionsController(
			OemUnlockPreferenceController.class);
	controller.onOemUnlockConfirmed();
}
|

OemUnlockPreferenceController.java onOemUnlockConfirmed()
public void onOemUnlockConfirmed() {
	mOemLockManager.setOemUnlockAllowedByUser(true);
}
|

framework层===
OemLockManager.java setOemUnlockAllowedByUser
mService.setOemUnlockAllowedByUser
|
IOemLockService.aidl setOemUnlockAllowedByUser(boolean allowed)
|
OemLockService.java setOemUnlockAllowedByUser(boolean allowedByUser)
          @Override
	public void setOemUnlockAllowedByUser(boolean allowedByUser) {
	  if (ActivityManager.isUserAMonkey()) {
		  // Prevent a monkey from changing this
		  return;
	  }

	  enforceManageUserOemUnlockPermission();
	  enforceUserIsAdmin();

	  final long token = Binder.clearCallingIdentity();
	  try {
		  if (!isOemUnlockAllowedByAdmin()) {
			  throw new SecurityException("Admin does not allow OEM unlock");
		  }

		  if (!mOemLock.isOemUnlockAllowedByCarrier()) {
			  throw new SecurityException("Carrier does not allow OEM unlock");
		  }

		  mOemLock.setOemUnlockAllowedByDevice(allowedByUser);
		  setPersistentDataBlockOemUnlockAllowedBit(allowedByUser);
	  } finally {
		  Binder.restoreCallingIdentity(token);
	  }
	}

    /**
     * Always synchronize the OemUnlockAllowed bit to the FRP partition, which
     * is used to erase FRP information on a unlockable device.
     */
    private void setPersistentDataBlockOemUnlockAllowedBit(boolean allowed) {
        final PersistentDataBlockManagerInternal pdbmi
                = LocalServices.getService(PersistentDataBlockManagerInternal.class);
        // if mOemLock is PersistentDataBlockLock, then the bit should have already been set
        if (pdbmi != null && !(mOemLock instanceof PersistentDataBlockLock)) {
            Slog.i(TAG, "Update OEM Unlock bit in pst partition to " + allowed);
            pdbmi.forceOemUnlockEnabled(allowed);
        }
    }

|

HW层===
android\hardware\interfaces\oemlock\1.0\IOemLock.hal setOemUnlockAllowedByDevice(bool allowed) generates (OemLockStatus status)
|
android/external/libese/esed/OemLock.cpp OemLock::setOemUnlockAllowedByDevice(bool allowed)

看代码实现,此项应该是留给oem厂商进行定制使用的,开关打开和关闭主要是操作FRP分区,这个分区一般是GMS包版本会用到,比如GMS开机向导中输入的用户账号等信息,都是存在FRP分区中。
当用户在设置中手动执行恢复出厂设置时,在Recovery中一般会清除掉FRP分区信息。用户执行这个恢复出厂设置动作是“可信的”,可以清除FRP分区。
但是当其他形为,比如直接通过命令如adb reboot recovery等或其他途径进入到recovery,是不会清除掉FRP分区的,开机进入到GMS开机向导界面,还是需要用户输入账号等信息的。而且我们这里的oem lock上锁仍然是有效的,数据没有被清除掉。

那么oem unlocking数据是存在哪了呢?
看代码是存在了FRP分区的最后一个block的最后一个BIT比特位上,那是否真是如此呢?
我们可以将FRP分区通过dd命令导出来看一下,命令如下:

dd if=/dev/block/bootdevice/by-name/frp of=/data/data/1.data

在lock和unlock的状态下,分别去dd一下,看下两者有什么不同,下面是我的dd后的效果图:
在这里插入图片描述
而且下面两句都是往FRP分区的最后一个bit位操作,只是一个是hal对象的方式,一个是通过PersistentDataBlockManagerInternal API接口去操作的;hal的方式留出来是为了将来厂商进行定制使用。

OemLockService.java setOemUnlockAllowedByUser(boolean allowedByUser)
          @Override
	public void setOemUnlockAllowedByUser(boolean allowedByUser) {
...

		  mOemLock.setOemUnlockAllowedByDevice(allowedByUser);
		  setPersistentDataBlockOemUnlockAllowedBit(allowedByUser);

	}

我的理解大概就是这样,仅供参考。

<think>嗯,用户想了解Android设备的OEM解锁是什么,用途和操作方法。首先,我需要先明确OEM解锁的定义。根据引用[1],OEM解锁是解除制造商限制的过程,允许用户刷机、安装ROM等。这可能涉及系统分区的访问,比如PERSIST分区,引用[2]提到解锁可能需要修改系统以绕过账号信息的检查。 接下来,用途方面,用户可能想获取完全控制权,进行自定义系统或root。操作方法通常是在开发者选项中开启,但不同Android版本可能有差异,比如Android 13默认打开这个开关,而Android 6.0涉及OEM分区和PERSIST分区的处理。 要注意不同厂商可能隐藏该选项,需要多次点击版本号激活开发者模式。另外,解锁可能导致保修失效或安全风险,需要提醒用户备份数据。操作步骤需要分版本说明,比如Android 8+的步骤,以及特殊情况如Bootloader已锁的情况。 最后,生成相关问题时要涵盖风险、Bootloader关系、厂商限制等,帮助用户全面理解。</think>### Android OEM解锁解析 #### 一、概念与用途 Android OEM解锁(Original Equipment Manufacturer Unlock)是允许用户解除设备制造商对系统分区的锁定功能。通过此操作,用户可刷入第三方ROM、获取root权限或修改系统核心组件[^1]。其核心作用包括: 1. **解除系统限制**:突破厂商对`/system`、`/boot`等分区的写保护 2. **开发调试**:支持通过fastboot刷入自定义镜像(如TWRP Recovery) 3. **硬件利用**:访问`PERSIST`分区中的底层数据(需配合修改版系统绕过安全检测)[^2] #### 二、操作步骤(以Android 8+为例) 1. **启用开发者选项**:设置 > 关于手机 > 连续点击版本号7次 2. **打开OEM解锁**:开发者选项 > "OEM unlocking"开关 3. **Bootloader解锁**(需PC连接): ```bash adb reboot bootloader fastboot oem unlock ``` **注意**:部分厂商设备需官网申请解锁码(如小米、华为) #### 三、风险提示 1. 触发防回滚机制(Anti-Rollback) 2. 丢失DRM数字版权密钥(如Widevine L1) 3. 可能无法通过SafetyNet认证(影响支付类APP) #### 四、厂商限制实例 | 品牌 | 解锁难度 | 数据清除 | 保修影响 | |---------|----------|----------|----------| | Google | ★☆☆☆☆ | 强制 | 失效 | | 三星 | ★★★☆☆ | 可选 | 部分保留 | | 华为 | ★★★★★ | 强制 | 完全失效 | : Android 13.0系统通过`OemUnlockPreferenceController.java`控制相关功能实现 [^2]: Android 6.0需修改系统绕过PERSIST分区验证
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值