首页
社区
课程
招聘
[原创] Magisk学习之刷入vbmeta.img及关闭avb2.0校验
发表于: 2021-2-1 18:05 84739

[原创] Magisk学习之刷入vbmeta.img及关闭avb2.0校验

2021-2-1 18:05
84739

最近刷了很多机型的Magisk,经历了N次变砖和修复,也有了一些经验,Magisk提供了三种方式刷入Magisk,分别是:

这三种安装方式教程很多,主要介绍一下直接安装或者patch boot.img刷完magisk变砖之后遇到的分区验证导致变砖问题以及如何解决。

从刷入Magisk的方式都需要操作boot.img也可以看出来,magisk的核心原理就是修改和替换了负责安卓系统启动的boot.img中的Ramdisk部分,该映像包括了一系列初始化init进程和启动时使用的rc文件。

如果直接能拿到Root权限,可以考虑直接安装或者选择并修补boot.img的方式刷入,两种方式的本质相同,均是获取到boot.img后进行patch,只不过实现方式不同,一种依赖Fastboot进行刷入,一种则是Magisk Manager中进行刷入。

获取boot.img的方式有两种:

如果在刷入Magisk时变砖无法开机或着无限重启,通常只需在fastboot中将正常的boot.img重新刷回即可,也是为什么要提前备份boot.img等的原因。

在部分机型中,可能由于vbmeta.img的验证导致设备无法启动,验证启动(Verified Boot)是Android一个重要的安全功能,主要是为了访问启动镜像被篡改,提高系统的抗攻击能力,简单描述做法就是在启动过程中增加一条校验链,即 ROM code 校验 BootLoader,确保 BootLoader 的合法性和完整性,BootLoader 则需要校验 boot image,确保 Kernel 启动所需 image 的合法性和完整性,而 Kernel 则负责校验 System 分区和 vendor 分区。

由于 ROM code 和 BootLoader 通常都是由设备厂商 OEM 提供,而各家实际做法和研发能力不尽相同,为了让设备厂商更方便的引入 Verified boot 功能,Google 在 Android O上推出了一个统一的验证启动框架 Android verified boot 2.0,好处是既保证了基于该框架开发的verified boot 功能能够满足 CDD 要求,也保留了各家 OEM 定制启动校验流程的弹性。

简单的说,就是部分厂商机型可能由于avb2.0验证boot.img是否被修改,导致刷入magisk或者三方Recovery后陷入假变砖无限重启的情况,此时将备份的vbmeta.img重新刷入并关闭验证即可:

fastboot --disable-verity --disable-verification flash vbmeta vbmeta.img

这种方式简单易用,适合个人玩家,但如果是用在生产中,成千台设备需要批量刷入magisk时,这种方式太过人工,因此还可以通过定制Magisk代码的方式来一键刷入Magisk。

来看一下Fastboot的原理,查阅上一步中FastBoot的源码可以看到:

实际上只是对vbmeta.img中120偏移处进行了两个bit位的处理,即vbmeta.img中是否关闭验证有两个flag可以控制,我们只需依葫芦画瓢:

这三步中比较困难的就是第三步,将patch完的vbmeta.img重新刷回系统中,因此这里参考了Magisk在有root权限时patch完boot.img之后直接刷入new_boot.img的操作。

看起来很复杂,核心写入的步骤其实就是eval $CMD1 | eval $CMD2 | cat - /dev/zero > "$2" 2>/dev/null,通过这行命令就可以实现不在Fastboot中通过shell命令完成boot.img和vbmeta.img的写入(也许也可以类推到其他img映像分区)

而且vbmeta.img相比于boot.img比较简单,不需要签名、验证等步骤,因此可以简单提炼为:

再加上patch操作,完整代码为:

 
 
 
ls -l /dev/block/by-name/ | grep boot
dd if=/dev/block/sdc6 of=/sdcard/boot.img
ls -l /dev/block/by-name/ | grep boot
dd if=/dev/block/sdc6 of=/sdcard/boot.img
 
 
 
// There's a 32-bit big endian |flags| field at offset 120 where
    // bit 0 corresponds to disable-verity and bit 1 corresponds to
    // disable-verification.
    //
    // See external/avb/libavb/avb_vbmeta_image.h for the layout of
    // the VBMeta struct.
    uint64_t flags_offset = 123 + vbmeta_offset;
    if (g_disable_verity) {
        data[flags_offset] |= 0x01;
    }
    if (g_disable_verification) {
        data[flags_offset] |= 0x02;
    }
// There's a 32-bit big endian |flags| field at offset 120 where
    // bit 0 corresponds to disable-verity and bit 1 corresponds to
    // disable-verification.
    //
    // See external/avb/libavb/avb_vbmeta_image.h for the layout of
    // the VBMeta struct.
    uint64_t flags_offset = 123 + vbmeta_offset;
    if (g_disable_verity) {
        data[flags_offset] |= 0x01;
    }
    if (g_disable_verification) {
        data[flags_offset] |= 0x02;
    }
// MagiskInstaller.kt 直接安装的入口
protected fun direct() = findImage() && extractZip() && patchBoot() && flashBoot()
 
private fun flashBoot(): Boolean {
        if (!"direct_install $installDir $srcBoot".sh().isSuccess)
            return false
        "run_migrations".sh()
        return true
    }
 
// shell脚本
direct_install() {
  rm -rf $MAGISKBIN/* 2>/dev/null
  mkdir -p $MAGISKBIN 2>/dev/null
  chmod 700 $NVBASE
  cp -af $1/. $MAGISKBIN
  rm -f $MAGISKBIN/new-boot.img
  echo "- Flashing new boot image"
  flash_image $1/new-boot.img $2
  if [ $? -ne 0 ]; then
    echo "! Insufficient partition size"
    return 1
  fi
  rm -rf $1
  return 0
}
 
# $1参数是patch后的new-boot.img路径,$2参数是设备系统中boot.img路径
flash_image() {
  # Make sure all blocks are writable
  $MAGISKBIN/magisk --unlock-blocks 2>/dev/null
  case "$1" in
    *.gz) CMD1="$MAGISKBIN/magiskboot decompress '$1' - 2>/dev/null";;
    *)    CMD1="cat '$1'";;
  esac
  if $BOOTSIGNED; then
    CMD2="$BOOTSIGNER -sign"
    ui_print "- Sign image with verity keys"
  else
    CMD2="cat -"
  fi
  if [ -b "$2" ]; then
    local img_sz=`stat -c '%s' "$1"`
    local blk_sz=`blockdev --getsize64 "$2"`
    [ $img_sz -gt $blk_sz ] && return 1
    eval $CMD1 | eval $CMD2 | cat - /dev/zero > "$2" 2>/dev/null
  elif [ -c "$2" ]; then
    flash_eraseall "$2" >&2
    eval $CMD1 | eval $CMD2 | nandwrite -p "$2" - >&2
  else
    ui_print "- Not block or char device, storing image"
    eval $CMD1 | eval $CMD2 > "$2" 2>/dev/null
  fi
  return 0
}
// MagiskInstaller.kt 直接安装的入口
protected fun direct() = findImage() && extractZip() && patchBoot() && flashBoot()
 
private fun flashBoot(): Boolean {
        if (!"direct_install $installDir $srcBoot".sh().isSuccess)
            return false
        "run_migrations".sh()
        return true
    }
 
// shell脚本
direct_install() {
  rm -rf $MAGISKBIN/* 2>/dev/null
  mkdir -p $MAGISKBIN 2>/dev/null
  chmod 700 $NVBASE
  cp -af $1/. $MAGISKBIN
  rm -f $MAGISKBIN/new-boot.img
  echo "- Flashing new boot image"
  flash_image $1/new-boot.img $2
  if [ $? -ne 0 ]; then
    echo "! Insufficient partition size"
    return 1
  fi
  rm -rf $1
  return 0
}
 
# $1参数是patch后的new-boot.img路径,$2参数是设备系统中boot.img路径
flash_image() {
  # Make sure all blocks are writable
  $MAGISKBIN/magisk --unlock-blocks 2>/dev/null
  case "$1" in

[峰会]看雪.第八届安全开发者峰会10月23日上海龙之梦大酒店举办!

最后于 2021-2-1 18:07 被alienhe编辑 ,原因:
收藏
免费 14
支持
分享
最新回复 (22)
雪    币: 3290
活跃值: (13864)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
2
火钳刘明
2021-2-1 18:08
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
TQL
2021-2-1 18:45
0
雪    币: 3013
活跃值: (981)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
围观~
2021-2-2 08:43
0
雪    币: 2
活跃值: (425)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
大佬学习了
2021-2-4 14:10
0
雪    币: 116
活跃值: (980)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不懂
2021-2-12 02:34
0
雪    币: 110
活跃值: (151)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
大神,学习了,全网找到的比较全面的文章
2021-7-9 12:10
0
雪    币: 205
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
hi,你好,请问三星设备的vbmeta.img位置在哪呢,我在21年8月发布的固件包里没有找到,设备是S9/SM-G9600
2021-11-5 21:24
0
雪    币: 224
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
小小伟yo hi,你好,请问三星设备的vbmeta.img位置在哪呢,我在21年8月发布的固件包里没有找到,设备是S9/SM-G9600
兄弟,S9 不是vbmata的机制....S10开始才有的...
2021-11-19 18:05
0
雪    币: 171
活跃值: (221)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
能干掉vbmata的Magisk仓库有吗?帖子里的代码和现在的共有仓库不一样。
2021-12-7 11:50
0
雪    币: 529
活跃值: (2651)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
晏子的土地 能干掉vbmata的Magisk仓库有吗?帖子里的代码和现在的共有仓库不一样。

内部仓库,你可以自己在Magisk的代码里按需加入

最后于 2021-12-7 16:52 被alienhe编辑 ,原因:
2021-12-7 16:50
0
雪    币: 207
活跃值: (39)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
受教了
2021-12-7 21:38
0
雪    币: 5330
活跃值: (5449)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
13
6666,刚好用到
2021-12-8 16:54
0
雪    币: 171
活跃值: (221)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
请问一下,这段代码可否共享?
主要是我前些天OTA后卡logo,要进fastboot里处理vbmeta才能开机。估计其他机型未来也会有类似问题。若可以,我可能会提交到其他第三方Magisk。
2021-12-8 17:20
0
雪    币: 244
活跃值: (266)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
解包 vbmeta.img flag改3数值完事
2021-12-13 17:39
0
雪    币: 4178
活跃值: (2542)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
120位改成了0x03还是开不了机。。。是不是magisk patch的boot.img有问题
2021-12-14 09:47
0
雪    币: 9745
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
数字云信息 解包 vbmeta.img flag改3数值完事
120位改2是disable,改3是什么功能,能说明下吗?
2022-3-21 10:12
0
雪    币: 15
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
白九 120位改2是disable,改3是什么功能,能说明下吗?
有两个验证, g_disable_verification 和 g_disable_verity,因为是通过二进制位控制的,3的二进制是'0b11', 就是两个都关闭
2022-3-24 17:22
0
雪    币: 15
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
图灵真主护佑 120位改成了0x03还是开不了机。。。是不是magisk patch的boot.img有问题
位置错了,注意看代码注释,是字节偏移120位置开始的32位(即4个字节),因为是大端地址,0x00000003存储时,0x03的位置实际上在123,120-122的值为0。如果编辑vbmeta.img镜像文件,只需要改123地址的值为0x03。而如果用代码操作,则把uint32或int型的0x03(总之是4字节变量,大端格式)写到120地址,或者把uint8的0x03写到123地址
2022-3-24 17:22
0
雪    币: 9745
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
JARK006 有两个验证, g_disable_verification 和 g_disable_verity,因为是通过二进制位控制的,3的二进制是'0b11', 就是两个都关闭
看你的其他回复,就是需要把文件的123的地址修改成0x03,而不是修改120的地址
2022-3-27 08:18
0
雪    币: 15
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
白九 看你的其他回复,就是需要把文件的123的地址修改成0x03,而不是修改120的地址[em_41]

fastboot.cpp 源码971行 

uint64_t flags_offset 123 + vbmeta_offset; //无特殊情况的vbmeta_offset值为零

故单字节实际操作地址是123


最后于 2022-4-1 22:07 被JARK006编辑 ,原因:
2022-4-1 22:07
0
雪    币: 244
活跃值: (266)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
学习了
2022-4-3 19:57
0
雪    币: 3888
活跃值: (4637)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
正好需要,感谢分享
2023-10-2 16:40
0
游客
登录 | 注册 方可回帖
返回
//