Qual+Android方案Unlock学习 以Oneplus7Pro为例

本文作者通过逆向工程探讨了如何解锁OnePlus7Pro的Bootloader,涉及Unpack OPS固件、Firehose提取、解锁流程分析、分区读写以及MSM Download逆向等步骤,分享了在解锁过程中遇到的问题和解决方案。
摘要由CSDN通过智能技术生成

目录

背景

Unpack guacamole_21_H.04_190416.ops

Unlock探究

开发者选项–允许解锁

fastboot oem unlock

extract LinuxLoader from abl

过程分析

FH读写分区

逆向MSM Download

USB抓包

token & pk 逆向结果

尝试修改分区实现unlock

VerifiedBoot Protocol 分析

结束

参考

                                hack渗透视频教程,扫码免费领


背景

严格意义上来说本文应该叫做: <<我本来只是想救个砖,但是却逆向了刷机工具尝试搞清楚android unlock的原理>> :D

前段时间因为一些工作需求想给手里的测试机(一加7Pro)刷个ColorOS,因为之前想体验Android12,机器是刷了个userdebug的lineageos,遂尝试了卡刷、sideload等之后机器被我搞坏了,开机直接recovery,报错信息是什么 mount fs的时候失败了 :( 没办法只能救转了,逛了一圈论坛发现有人提供9008刷机工具(https://www.oneplusbbs.com/forum.php?mod=viewthread&tid=4730052),通过万能的9008救回来之后,我就想做点别的: 把他的firehose“偷”出来玩玩。

Unpack guacamole_21_H.04_190416.ops

刷机工具解压之后就几个文件,一个刷机工具 msmdownloadtoolv4.0.88,还有个guacamole_21_H.04_190416.ops,一看就是固件包,然后就是一些完整性校验用的文件。

根据经验,这类刷机包里应该是内置了firehouse的,可以考虑两条路:

  1. 解包,直接把firehose提出来

  2. 内存dump,在刷机工具尝试给手机传输firehose的时候的时候内存dump,从内存里根据ELF文件头给截出来

方法2是我最开始尝试的办法,但是dump了几次,发现了好几个ELF,但是都不对,所以尝试方法1 :D 很显然这个包是厂商自己搞得加密,不过网上已经有大佬分析了(早用方法1就少走弯路了),所以根据 How to Extract/Decrypt OnePlus OPS Firmware(https://www.droidwin.com/how-to-extract-oneplus-ops-firmware/) 提供的工具,可以成功吧固件包解开,获取到firehose

# muhe @ muheMacBookAir in ~/Work/play_with_oneplus7pro on git:main x [22:01:37]
$ ls -al prog_firehose_*
-rw-r--r--@ 1 muhe staff 726400 Oct 28 22:46 prog_firehose_ddr.elf
-rw-r--r--@ 1 muhe staff 726272 Oct 28 22:46 prog_firehose_lite.elf

随便试了一把读分区,是可以的,说明firehose是没问题的 :)

图片

然后就想着顺手看点别的,研究研究Qual+Android平台的解锁BL是怎么实现的,遂有了后续的过程。

Unlock探究

开发者选项–允许解锁

参考android-9-r1, 因为现在用的一加的系统的是Android9的

没在开发这里允许解锁BL的话,直接fastboot oem unlock是不行的

  1. onOemUnlockConfirmed

https://cs.android.com/android/platform/superproject/+/android-9.0.0_r1:packages/apps/Settings/src/com/android/settings/development/OemUnlockPreferenceController.java;l=132

public void onOemUnlockConfirmed() {
  mOemLockManager.setOemUnlockAllowedByUser(true);
}
  1. setOemUnlockAllowedByUser

https://cs.android.com/android/platform/superproject/+/android-9.0.0_r1:frameworks/base/core/java/android/service/oemlock/OemLockManager.java;drc=b45a2ea782074944f79fc388df20b06e01f265f7;l=114

@RequiresPermission(android.Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE)
  public void setOemUnlockAllowedByUser(boolean allowed) {
      try {
          mService.setOemUnlockAllowedByUser(allowed);
      } catch (RemoteException e) {
          throw e.rethrowFromSystemServer();
      }
  }
  1. setOemUnlockAllowedByUser

https://cs.android.com/android/platform/superproject/+/android-9.0.0_r1:frameworks/base/services/core/java/com/android/server/oemlock/OemLockService.java;l=156;drc=b45a2ea782074944f79fc388df20b06e01f265f7;bpv=0;bpt=1

// The user has the final say so if they allow unlock, then the device allows the bootloader
// to OEM unlock it.
@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);
  }
}
  1. setPersistentDataBlockOemUnlockAllowedBit

https://cs.android.com/android/platform/superproject/+/android-9.0.0_r1:frameworks/base/services/core/java/com/android/server/oemlock/OemLockService.java;drc=b45a2ea782074944f79fc388df20b06e01f265f7;bpv=0;bpt=1;l=232

/**
* 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);
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值