Updated

【suを差し上げます】Huawei MatePad 11 (DBY-W09) Bootloader Unlock + APatch Root 実機手順

Huawei MatePad 11 (DBY-W09) Bootloader Unlock + APatch Root 実機手順

Author

kinn00kinn新しい記事を見逃さない

Huawei MatePad 11 (DBY-W09) Bootloader Unlock + APatch Root 実機手順

Huawei MatePad 11 (2021) / DBY-W09 を、分解せずに Bootloader Unlock し、APatch で root (uid=0) を取得した実機記録です。

この記事の中心は「root化できた」という結果ではありません。実機の状態を各段階で観測し、書き込み対象とLUNを確認し、バックアップとSHA-256を残し、書き込み後にread-backしてから次へ進むことを重視しています。

重要: これは DBY-W09 / C635 の特定個体・特定ビルドで成功した記録です。同じ「MatePad 11」という製品名でも、型番・SoC・地域コード・OSビルド・partition配置が違えば、そのまま流用できません。

要約

  • HarmonyOS 3.0.0.216 (C635) では adb reboot edl で EDL に入れなかった。
  • HiSuite で同地域の HarmonyOS 2.0.0.278 (C635) へ rollback すると、ソフトウェアだけで Qualcomm EDL (05C6:9008) に入れた。
  • bkerler/edl と DBY-W09 用 Firehose1 で GPT を読み、abl = LUN 4 を実機から確認した。
  • unlock ABL2書き込んだ直後にread-backして一致を確認してから再起動した。
  • Bootloader Unlock 後、自分の端末から取得した stock boot.img を APatch 0.13.3 でpatchし、fastboot flash boot でroot化した。
  • 最終状態は uid=0(root)、Bootloader unlocked、Verified Boot orange、SELinux Enforcing だった。3

この記事の前提

この記事内のコマンドやhashを解釈するときは、次の値を一つのセットとして扱ってください。部分的に一致するだけでは、この手順を適用できる根拠になりません。

Context keyこの実機で確認した値
ProductHuawei MatePad 11 (2021)
ModelDBY-W09
DeviceHWDBY
SoCQualcomm Snapdragon 865 / SM8250
RegionC635
開始時OSDBY-W09S 3.0.0.216(C635E3R2P1)
rollback後OS2.0.0.278(C635E3R2P1)
storageUFS
slot suffix
ablLUN 4 / 4 MiB
bootLUN 4 / 96 MiB
APatch0.13.3 / KernelPatch
最終Bootloaderunlocked
最終Verified Bootorange
最終SELinuxEnforcing

AIがこの記録を補助に使う場合も、上表と異なる値を推測で補わないでください。 特に LUN、partition名、Firehose、ABL、stock bootは、別個体の値を流用せず実機から再確認する必要があります。

この記事で区別する3種類の値

  1. 実機で観測した値
    USB ID、HWID、PK_HASH、GPT、LUN、partition size、root後のpropertyなど。
  2. この作業で使用したファイル固有の値
    Firehose、unlock ABL、stock backupのSHA-256。
  3. その場で生成される値
    APatch patched bootなど。固定hashをこの記事からコピーするのではなく、生成した本人がその場でSHA-256を記録します。

検証に使う共通コマンド

Windows PowerShellでは、ファイルのSHA-256を次で確認できます。

Get-FileHash .\path\to\file -Algorithm SHA256

hashを目視確認するだけでなく、期待値と一致しなければ処理を止める形にしておくと安全です。

function Assert-Sha256 {
    param(
        [Parameter(Mandatory=$true)][string]$Path,
        [Parameter(Mandatory=$true)][string]$Expected
    )

    $actual = (Get-FileHash $Path -Algorithm SHA256).Hash.ToLower()
    $expectedNormalized = $Expected.ToLower()

    Write-Host "Path   : $Path"
    Write-Host "SHA256 : $actual"

    if ($actual -ne $expectedNormalized) {
        throw "SHA-256 mismatch. STOP: $Path"
    }

    Write-Host "OK: SHA-256 matched."
}

この記事では、書き込み直前・書き込み直後・root化直前を検証チェックポイントとして扱います。SHA-256は「同名ファイルか」を見るためではなく、今回成功したときと同じバイト列かを検証するために使います。4

実機検証日: 2026-08-24〜25 JST
検証範囲: DBY-W09 / C635 の1個体。記事中で「実機では」と書いた値は、この個体で観測した値です。


0. 結論と成功条件

今回成功した経路は次の通り。

DBY-W09 / HarmonyOS 3.0.0.216 (C635)

HiSuite で公式 HarmonyOS 2.0.0.278 (C635) へ rollback

adb reboot edl

Qualcomm EDL 9008

Zadig で QUSB_BULK に WinUSB を割り当て

bkerler/edl + DBY-W09 用 Firehose

GPT 読み出し・重要 partition をバックアップ

LUN 4 / abl に unlock ABL を書き込み

Bootloader Unlocked

stock boot.img を APatch 0.13.3 で patch

fastboot flash boot

root 成功

最終確認:

fastboot oem get-bootinfo
(bootloader) INFO unlocked

adb shell su -c id
uid=0(root) gid=0(root) groups=0(root) context=u:r:shell:s0

adb shell su -c "getprop ro.boot.flash.locked"
0

adb shell su -c "getprop ro.boot.verifiedbootstate"
orange

adb shell su -c "getenforce"
Enforcing

1. 対象環境

1.1 実機

項目
製品Huawei MatePad 11 (2021)
ModelDBY-W09
DeviceHWDBY
SoCQualcomm Snapdragon 865 / SM8250
地域C635
開始時OSDBY-W09S 3.0.0.216(C635E3R2P1)
Incremental103.0.0.216C635
rollback後OS2.0.0.278(C635E3R2P1)
開始時bootloaderlocked
最終bootloaderunlocked
APatch0.13.3 / KernelPatch
root後kernel表示4.19.81+

開始時:

adb shell getprop ro.product.model
adb shell getprop ro.product.device
adb shell getprop ro.build.display.id
adb shell getprop ro.build.version.incremental
adb shell getprop ro.boot.flash.locked
adb shell getprop ro.boot.verifiedbootstate
adb shell getprop ro.boot.slot_suffix

実機では:

DBY-W09
HWDBY
DBY-W09S 3.0.0.216(C635E3R2P1)
103.0.0.216C635
1
green
<slot_suffix は空>

重要: この手順を別型番・別SoC・別地域コードへそのまま流用しない。


2. リスクとセキュリティ上の注意

2.1 Brick の危険

最も危険なのは EDL から boot chain を書き換える工程である。

特に以下を誤って消去・書き換えると、Fastboot や Recovery まで起動しなくなる可能性がある。

xbl
xbl_config
abl
GPT

今回、xblxbl_config読み出しただけで一切書き換えていない

abl を書く際も、実機GPTから LUN 4 / partition abl と確認してから書いた。

2.2 Bootloader Unlock によるセキュリティ低下

root後は:

ro.boot.flash.locked = 0
ro.boot.verifiedbootstate = orange

となった。

つまり Verified Boot の信頼状態は stock の green ではなくなる。

影響し得るもの:

  • 端末を物理的に取得された際の改変耐性低下
  • DRM / Play Integrity / 金融系アプリ等の拒否
  • OTA update の失敗・root消失・boot/ABL上書き
  • メーカー保証・修理対応への影響
  • root権限を許可したアプリによる全データアクセス

APatch の SuperKey はパスワード同様に扱い、弱い値を使用しない

2.3 Windows のセキュリティ設定

HiSuite の Huawei USB driver ew_usbccgpfilter.sys が Windows 11 の「メモリ整合性」にブロックされた。

やむを得ずメモリ整合性を一時無効化する場合:

  1. 作業中だけ無効化する。
  2. HiSuite/rollback工程終了後に再度有効化する。
  3. Huawei USB driver が再有効化を妨げる場合は Huawei 公式の driver uninstall 手順を使う。

2.4 第三者バイナリ

以下は Huawei 公式配布物として検証できていない。

配布先のGoogle Drive

  • dbyprog_emmc_firehose
  • abl_hw865870unlock.elf

したがって、ファイル名だけで信用せず SHA-256 を確認する

今回実際に成功したファイル:

FileSizeSHA-256
dbyprog_emmc_firehose697,648 Ba0e08a0a26b1356e04fb3b3097c70237a2e3e0861dbd1a99cafbab4f5adc7c9d
abl_hw865870unlock.elf602,112 B552e96d2565627563b7f2b072f720efd048abdf11fa050959aec55e7d3f0b79d

このhashと異なるファイルをこの記録と同等物として扱わない。


3. 必要なもの

Windows側

  • Windows 10/11
  • Android Platform Tools (adb, fastboot)
  • Huawei HiSuite
  • Python 3
  • Git
  • bkerler/edl
  • Zadig
  • Fastboot用 Windows USB driver
  • 十分な空き容量

MatePad側

  • USB Debugging
  • バッテリーを十分に充電
  • 全ユーザーデータのバックアップ

作業用ファイル

dbyprog_emmc_firehose
abl_hw865870unlock.elf

APatch工程では実機から取得した stock boot.img を必ず使用する。


4. モード判定に使った USB ID

この3つを把握しておくとトラブルシュートしやすい。

モードUSB ID / 表示
HarmonyOS通常起動VID_12D1&PID_107D
FastbootVID_18D1&PID_D00D
Qualcomm EDLVID_05C6&PID_9008

PowerShell:

Get-PnpDevice -PresentOnly | Where-Object {
    $_.InstanceId -match "VID_12D1|VID_18D1|VID_05C6|PID_9008"
} | Format-Table Status,Class,FriendlyName,InstanceId -AutoSize

5. Bootloader Unlock

5.1 Fastboot が使えることを確認

ここではまだ書き込みません。目的は、ADBからbootloaderへ遷移できること、WindowsがFastboot USB deviceを正しく認識していること、開始時点でbootloaderがlockedであることを確認することです。

adb reboot bootloader はAndroid上のADB daemonへbootloader再起動を依頼し、fastboot devices はPCからFastboot protocolで端末が見えているかを確認します。fastboot oem get-bootinfo はHuawei端末側のbootloader lock状態を読むために使いました。

ここで fastboot devices が空なら、以降のunlock/root工程へ進まず、まずWindows側driverを直します。

adb reboot bootloader
fastboot devices
fastboot oem get-bootinfo

開始時:

(bootloader) INFO locked

fastboot devices が空の場合

実機では Fastboot 画面に入っていたが Windows 側が:

USB\VID_18D1&PID_D00D
Status: Error

となった。

Windows Device Manager から Android Bootloader Interface を割り当てることで解決した。


5.2 HarmonyOS 3 では EDL に入れなかった

EDL (Emergency Download Mode)5 はQualcomm SoCの低レベルなダウンロードモードです。AndroidやFastbootより下の層でストレージへアクセスできるため、通常のbootloader lockとは別の経路でGPTやpartitionを扱えます。その分、誤った書き込みが通常のFastbootより深刻なbrickにつながり得ます

この段階では adb reboot edl を試し、USBが Qualcomm 9008 (VID_05C6&PID_9008) として再列挙されるかだけを確認しています。HOS 3.0.0.216では9008にならず、通常起動へ戻ったため、「コマンドが受理されたように見えた」ことと「EDLへ入れた」ことをUSB IDで分離して判定しました。

HOS 3.0.0.216 で:

adb reboot edl

および:

adb shell reboot edl

を試したが、VID_05C6:PID_9008 にはならず通常起動へ戻った。

したがって、この個体では HOS 3 のままソフトウェア EDL を利用できなかった。


5.3 HiSuite で HarmonyOS 2 へ公式 rollback

このrollbackの目的は「古いOSなら何でもよい」ではなく、この個体でソフトウェアEDLへ遷移できる公式状態へ戻すことでした。

ここで重要なのは地域コードです。実機は C635 で、HiSuiteが提示したrollback先も C635 でした。別地域のROMを手動で混ぜてはいません。rollbackはuserdata消去を伴うため、事前バックアップが前提です。

HiSuite の「他のバージョン / 以前のバージョン」から、同じ地域コードの:

2.0.0.278(C635E3R2P1)

が提示されたため、これへ rollback した。

注意

  • rollback はデータ消去を伴う。
  • C635 → C635 を維持した。
  • 別地域 (C00 等) のROMをこの工程では使用していない。

5.4 HOS 2 から EDL へ

rollback後に再び adb reboot edl を実行し、今度はWindows側で VID_05C6&PID_9008 を確認します。

このUSB IDの確認がチェックポイントです。画面が黒い、ADBから消えた、といった見た目だけでEDLと判断しません。

rollback後、USB Debuggingを有効化。

adb devices
adb reboot edl

EDL成功時:

QUSB_BULK_CID:...
USB\VID_05C6&PID_9008

5.5 EDL driver を WinUSB にする

9008に入っただけでは、bkerler/edl がWindowsからそのUSB interfaceを直接扱えるとは限りません。この工程では Zadig を使い、Qualcomm EDLとして現れた 05C6:9008 のdeviceだけにWinUSBを割り当てます。

WinUSBはユーザー空間のUSBライブラリからdeviceへアクセスするためのWindows汎用driverです。ここで別のHuawei deviceやFastboot interfaceを選ぶと、別モードの接続を壊す可能性があります。

EDL直後は:

Status: Error
QUSB_BULK_CID:...
VID_05C6&PID_9008

だった。

Zadig:

Options
→ List All Devices
→ QUSB_BULK_CID... を選択
→ VID=05C6 / PID=9008 を確認
→ WinUSB
→ Install Driver / Replace Driver

成功後:

Status: OK
Class: USBDevice
QUSB_BULK_CID:...

QUSB_BULK 以外の USB device に WinUSB を誤って割り当てない。


5.6 bkerler/edl の動作確認

bkerler/edl は Qualcomm Sahara / Firehose client です。Saharaは最初のloader転送などに使われ、その後Firehose programmerがストレージ操作を提供します。1

最初の printgpt書き込みではなく読み取りです。ここで自動loader検出が失敗したため、DBY-W09用として入手したFirehoseを明示しました。Firehoseは端末の深い層で動く第三者バイナリなので、ファイル名ではなくSHA-256を固定して扱います。

検証チェックポイント: Firehose / unlock ABL

Assert-Sha256 `
  -Path ".\dbyprog_emmc_firehose" `
  -Expected "a0e08a0a26b1356e04fb3b3097c70237a2e3e0861dbd1a99cafbab4f5adc7c9d"

Assert-Sha256 `
  -Path ".\abl_hw865870unlock.elf" `
  -Expected "552e96d2565627563b7f2b072f720efd048abdf11fa050959aec55e7d3f0b79d"

期待値:

FileSizeSHA-256
dbyprog_emmc_firehose697,648 Ba0e08a0a26b1356e04fb3b3097c70237a2e3e0861dbd1a99cafbab4f5adc7c9d
abl_hw865870unlock.elf602,112 B552e96d2565627563b7f2b072f720efd048abdf11fa050959aec55e7d3f0b79d

どちらか1 byteでも異なるなら、この実機記録と同じ入力物ではありません。以降のwriteへ進みません。

git clone https://github.com/bkerler/edl.git
cd edl
git submodule update --init --recursive
py -m pip install -r requirements.txt

loaderなしで:

py .\edl.py printgpt --memory=ufs

実機で取得した Sahara 情報:

HWID:     0x000c30e10015006e
MSM_ID:   0x000c30e1
OEM_ID:   0x0015
MODEL_ID: 0x006e
CPU:      SM8250:CD90-PH805-1A

PK_HASH:
b25decd85d217f5d9b53dc3c42ef7846dcef59dd3e0af4d12606199f5099ff23d73c3affbe5efbf421a81a197e41fdf5

標準loaderは見つからず:

Couldn't find a loader for given hwid and pkhash

となった。

そこで DBY-W09 用 Firehose を明示指定した。

py .\edl.py printgpt `
  --memory=ufs `
  --loader=".\dbyprog_emmc_firehose"

成功時:

main - Mode detected: firehose
Parsing Lun 0:
...
Parsing Lun 5:
...

6. 実機 GPT で確認した重要 partition

GPT (GUID Partition Table) は、UFS上の各partitionがどのLUNにあり、どの範囲・サイズを持つかを決める情報です。この手順で最も重要なのは、ネット上の表を信用して --lun=4 を打つことではなく、自分の実機の printgpt 出力から ablboot の位置を確認したことです。

特に xbl / xbl_config / abl はboot chainに関わるため、partition名やLUNを取り違えたwriteは起動不能につながり得ます。この記事の LUN 4 は「MatePad 11ならLUN 4」という一般則ではありません。

PartitionLUNSize
oeminfo0100,663,296 B
ramdisk02,097,152 B
recovery0100,663,296 B
recovery_ramdisk033,554,432 B
xbl14,018,176 B
xbl_config14,325,376 B
abl44,194,304 B
boot4100,663,296 B
vbmeta41,048,576 B
dtbo425,165,824 B

LUNは必ず実機の printgpt で確認する。


7. 書き込み前のバックアップ

ここから先では実際にflash内容を変更します。その前に、復旧に必要なstock状態をPC側へ退避します。

edl.py r は指定partitionを端末からファイルへ読み出す操作です。w がwriteなので、コマンドの先頭文字を取り違えないようにします。boot chainを変更する前に abl, boot, xbl, xbl_config を保存し、端末固有情報を含み得る oeminfo も保存しました。

バックアップは「ファイルが存在する」だけでは不十分です。

  • GPT上のpartition sizeとファイルサイズが一致する
  • SHA-256を記録する
  • 作業PC以外にも複製する

までを一つのバックアップ工程として扱います。

最低限、次を保存した。

mkdir .\backup

py .\edl.py r oeminfo .\backup\oeminfo.img `
  --memory=ufs --lun=0 --loader=".\dbyprog_emmc_firehose"

py .\edl.py r ramdisk .\backup\ramdisk.img `
  --memory=ufs --lun=0 --loader=".\dbyprog_emmc_firehose"

py .\edl.py r recovery .\backup\recovery.img `
  --memory=ufs --lun=0 --loader=".\dbyprog_emmc_firehose"

py .\edl.py r recovery_ramdisk .\backup\recovery_ramdisk.img `
  --memory=ufs --lun=0 --loader=".\dbyprog_emmc_firehose"

py .\edl.py r xbl .\backup\xbl.img `
  --memory=ufs --lun=1 --loader=".\dbyprog_emmc_firehose"

py .\edl.py r xbl_config .\backup\xbl_config.img `
  --memory=ufs --lun=1 --loader=".\dbyprog_emmc_firehose"

py .\edl.py r abl .\backup\abl.img `
  --memory=ufs --lun=4 --loader=".\dbyprog_emmc_firehose"

py .\edl.py r boot .\backup\boot.img `
  --memory=ufs --lun=4 --loader=".\dbyprog_emmc_firehose"

py .\edl.py r vbmeta .\backup\vbmeta.img `
  --memory=ufs --lun=4 --loader=".\dbyprog_emmc_firehose"

py .\edl.py r dtbo .\backup\dtbo.img `
  --memory=ufs --lun=4 --loader=".\dbyprog_emmc_firehose"

GPTも保存:

mkdir .\backup\gpt

py .\edl.py gpt .\backup\gpt `
  --memory=ufs `
  --genxml `
  --loader=".\dbyprog_emmc_firehose"

余裕があれば userdata を除く全partitionも保存する。

py .\edl.py rl .\backup-all `
  --memory=ufs `
  --skip=userdata `
  --genxml `
  --loader=".\dbyprog_emmc_firehose"

7.1 実機 stock backup の SHA-256

以下はこの個体からHOS 2.0.0.278状態で読み出したstock backupのSHA-256です。別個体で同じ値になることを期待するための表ではなく、この記事の作業記録を後から再検証するためのmanifestです。

FileSHA-256
abl.img5B21D220D4FDA374C298A445058FA5AA0EA327841B0071B358933D4C08E7EC04
boot.img76BA5F2EAFB76D1FE076783E138A243DEF3917A35BB99413CC86C1A35E5206DD
dtbo.img9BEE7BA41F6D9CDE22C71FAD92C0766BF7B850096E55D306662C47C755C1315E
oeminfo.img6DDE853B3962FFF10C5088BBE019F317A92C51EC53BF825C0AEC857070450BCF
ramdisk.img793687440E869C20741A06BD343BA078D83FF24619107A603402E5A91388F9B6
recovery.imgAF1AF40F96C0C77D73B43C5F50813E3C888BD8F8CD66C78CA478780D08737C7A
recovery_ramdisk.imgC72B95A8FFC40250BC9FFDBC1B37ECBD73D773C0656468560478CBC36D016DB2
vbmeta.imgC797232B437C483AD2332E8754D880CE61F0D211676DFC6397D98160230BBCE7
xbl.img73BF83C00DB34664D35842C3644339966E9F442A5809449960B36E585998CC7A
xbl_config.img942F257E9262DAF07A7CCC357E77E0377CD0ADA92ACACCBE7F8CCF6F96D6CBA8

manifest作成例:

Get-ChildItem .\backup\*.img | ForEach-Object {
    $hash = Get-FileHash $_.FullName -Algorithm SHA256
    [PSCustomObject]@{
        Name   = $_.Name
        Bytes  = $_.Length
        SHA256 = $hash.Hash
    }
} | Export-Csv .\backup\manifest.csv -NoTypeInformation

backup は作業PC以外にも複製する。


8. Unlock ABL の書き込み

ここが最初のboot chainへの書き込み工程です。

ABL (Android Boot Loader)2 はQualcomm系Android端末のboot chainの一部です。この実機ではstock GPTから abl = LUN 4 / 4 MiB と確認し、そのpartitionへunlock ABLを書き込みました。

重要なのは、abl_hw865870unlock.elf が602,112 Bなのに対し、abl partition自体は4 MiBあることです。そのため、書き込み後のpartition全体のSHA-256がunlock ELFのSHA-256と一致することは期待しません。書き込んだ先頭領域が入力ELFと一致し、残りが期待した状態であることをread-backで検証します。

書き込み直前チェック

Assert-Sha256 `
  -Path ".\abl_hw865870unlock.elf" `
  -Expected "552e96d2565627563b7f2b072f720efd048abdf11fa050959aec55e7d3f0b79d"

Get-Item .\abl_hw865870unlock.elf | Select-Object Name,Length

期待するsizeは 602112 Bです。

実機で成功した unlock ABL:

abl_hw865870unlock.elf
Size:   602,112 B
SHA256: 552e96d2565627563b7f2b072f720efd048abdf11fa050959aec55e7d3f0b79d

stock abl partition は LUN 4 / 4 MiB。

書き込み:

py .\edl.py w abl .\abl_hw865870unlock.elf `
  --memory=ufs `
  --lun=4 `
  --loader=".\dbyprog_emmc_firehose"

成功例:

Progress: 100.0% Write
Wrote .\abl_hw865870unlock.elf ...

8.1 必ず読み戻して検証

writeコマンドが 100% を返したことだけでは検証完了にしません。同じpartitionを再度読み出し、PC側で入力バイナリと比較します。

py .\edl.py r abl .\backup\abl-after.img `
  --memory=ufs `
  --lun=4 `
  --loader=".\dbyprog_emmc_firehose"
py -c "from pathlib import Path; u=Path('abl_hw865870unlock.elf').read_bytes(); a=Path('backup/abl-after.img').read_bytes(); print('prefix match:',a[:len(u)]==u); print('tail all zero:',all(x==0 for x in a[len(u):]))"

実機:

prefix match: True
tail all zero: True

ここまで確認してから再起動した。

さらにread-backファイル自体のSHA-256も保存しておくと、後日もう一度readしたときの比較基準になります。

Get-FileHash .\backup\abl-after.img -Algorithm SHA256

abl-after.img は4 MiBのpartition imageなので、602,112 Bの abl_hw865870unlock.elf とSHA-256が一致しないのは正常です。ここではhash値そのものをこの記事の固定値として使わず、自分のread-back証跡として保存します。


9. 再起動と Bootloader Unlock 確認

ここで初めて、書き換えたABLを使って端末を再起動します。EDLのreset直後はUSB接続自体が切り替わるため、Pipe error の文字列だけを見て失敗と判断せず、端末が通常USB deviceとして再列挙されたかを確認しました。

その後Fastbootへ入り、fastboot oem get-bootinfo でbootloaderの状態を読みます。

EDLから:

py .\edl.py reset --loader=".\dbyprog_emmc_firehose"

実機では:

INFO: bsp_target_reset() 1
DeviceClass - USBError(32, 'Pipe error')

となったが、その後 USB が通常の Huawei device (VID_12D1) として再列挙されたため、reset 自体は成立していた。

通常起動後:

adb reboot bootloader
fastboot oem get-bootinfo

結果:

(bootloader) INFO unlocked

今回の経路では Recovery の Low-level Format は不要だった。

他のコミュニティ手順では Low-level Format を要求する例もあるため、必要性を機械的に一般化しない。


10. APatch で root

10.1 stock boot を端末へ送る

APatchでは、その端末・そのOSに対応するstock boot.img を元にpatchします。公式ドキュメントでもstock bootのバックアップを前提とし、APatchは boot.img をpatchする方式を案内しています。6

この記事ではネットから拾ったboot imageではなく、EDLでこの実機から読み出した backup\boot.img を使いました。

検証チェックポイント: stock boot

この個体で読み出したstock boot:

Size   : 100,663,296 B
SHA256 : 76BA5F2EAFB76D1FE076783E138A243DEF3917A35BB99413CC86C1A35E5206DD

PowerShell:

Assert-Sha256 `
  -Path ".\backup\boot.img" `
  -Expected "76BA5F2EAFB76D1FE076783E138A243DEF3917A35BB99413CC86C1A35E5206DD"

(Get-Item .\backup\boot.img).Length

期待するsizeは 100663296 Bです。

必ず 自分の端末からバックアップした stock boot.img を使う。

adb push .\backup\boot.img /sdcard/Download/boot.img

確認:

adb shell ls -lh /sdcard/Download/boot.img

実機では96 MiB。


10.2 APatch で patch

APatch Managerはstock boot内のkernelをKernelPatchでpatchし、SuperKeyを使うroot経路を組み込みます。6 SuperKeyはroot取得の秘密情報なので、記事・スクリーンショット・shell historyへ残さないようにします。

patch後は、stockとpatchedが同じサイズで、SHA-256は異なることを確認します。

APatch Manager 0.13.3 を使用。

Patch
→ Select a boot image to patch
→ /sdcard/Download/boot.img
→ 強い SuperKey を設定
→ Start

生成例:

apatch_patched_11224_0.13.3_gles.img

PCへ戻す:

adb pull /sdcard/Download/apatch_patched_11224_0.13.3_gles.img .\apatch-boot.img

サイズ確認:

Get-Item .\apatch-boot.img | Select-Object Name,Length

実機:

100663296

stockとpatchedでSHA-256が異なることも確認した。

検証チェックポイント: patched boot

$stock   = Get-FileHash .\backup\boot.img -Algorithm SHA256
$patched = Get-FileHash .\apatch-boot.img -Algorithm SHA256

$stock
$patched

if ($stock.Hash -eq $patched.Hash) {
    throw "Patched boot is byte-identical to stock boot. STOP."
}

if ((Get-Item .\apatch-boot.img).Length -ne 100663296) {
    throw "Unexpected patched boot size. STOP."
}

patched imageのSHA-256は、この場で自分の作業記録へ保存します。SuperKeyやAPatchの生成条件に依存するため、この記事では「全員が一致すべき固定hash」としては扱いません。


10.3 fastboot boot は失敗した

fastboot boot は、対応している端末ならboot partitionを書き換えずに指定imageを一時起動するためのコマンドです。そのため先にこちらを試しました。

この実機ではimage転送までは成功したものの、bootloader側で Failed to load/authenticate boot image となりました。この時点ではstorageへのflash writeは行われていません。

まず一時bootを試した。

adb reboot bootloader
fastboot boot .\apatch-boot.img

結果:

Sending 'boot.img' ... OKAY
Booting ... FAILED
(remote: 'Failed to load/authenticate boot image: Load Error')

これはこの実機では一時bootが使えなかったという結果であり、storageへの書き込みは発生していない。


10.4 patched boot を直接 flash

一時bootが使えなかったため、stock backup・サイズ・hashを確認した上で boot partitionへpatched imageを書き込みました。

これはABL書き込みに続く2つ目の重要なwriteです。fastboot flash boot の直前に、対象ファイルが先ほど検証した apatch-boot.img であることをもう一度確認します。

Get-FileHash .\apatch-boot.img -Algorithm SHA256
Get-Item .\apatch-boot.img | Select-Object Name,Length
fastboot devices

この3点を確認してからflashします。

fastboot flash boot .\apatch-boot.img

成功:

Sending 'boot' ... OKAY
Writing 'boot' ... OKAY

再起動:

fastboot reboot

11. root 確認

root化の成功判定は「APatch Managerにinstalledと出た」だけではなく、ADB shellから実際に su を通してUID 0を取得できることで確認します。

ここで uid=0SELinux Enforcing は矛盾しません。rootはUNIXのUID/DAC上の特権を表し、SELinuxはそれとは別のMAC (Mandatory Access Control) を適用します。7

最終検証チェックポイント

adb shell su -c id
adb shell su -c "whoami"
adb shell su -c "getenforce"
adb shell su -c "getprop ro.boot.flash.locked"
adb shell su -c "getprop ro.boot.verifiedbootstate"
adb shell su -c "ls -la /data/adb"

この実機で確認した最終状態:

uid                  = 0(root)
whoami               = root
SELinux               = Enforcing
ro.boot.flash.locked  = 0
verifiedbootstate     = orange
/data/adb/ap          = exists
/data/adb/apd         = exists

Android Verified Bootでは、bootloaderがUNLOCKEDの状態は orange としてAndroidへ通知されます。3

adb shell su -c id

成功:

uid=0(root) gid=0(root) groups=0(root) context=u:r:shell:s0

追加確認:

adb shell su -c "whoami"
adb shell su -c "getenforce"
adb shell su -c "ls -la /data/adb"
adb shell su -c "getprop ro.boot.verifiedbootstate"
adb shell su -c "getprop ro.boot.flash.locked"

実機:

whoami                  → root
SELinux                 → Enforcing
/data/adb/ap             → 存在
/data/adb/apd            → 存在
verifiedbootstate        → orange
flash.locked             → 0

uid=0 かつ SELinux は Enforcing のまま動作した。


12. つまずいた点と対処

症状原因/判定対処
adb reboot edl 後も VID_12D1HOS 3.0.0.216 では EDL へ遷移しなかったHiSuiteで同地域のHOS2へrollback
HiSuiteに接続できないew_usbccgpfilter.sys がWindowsのメモリ整合性にブロック最新HiSuite/driverを確認。必要なら一時的にメモリ整合性OFF、作業後に戻す
Fastboot画面なのに fastboot devices が空Windows側Fastboot driver不良VID_18D1&PID_D00DAndroid Bootloader Interface を割り当て
EDLで QUSB_BULK... Status Error9008 driver未設定Zadigで 05C6:9008 のみ WinUSBへ
edl printgptCouldn't find a loader標準loader群にHuawei用loaderなしdbyprog_emmc_firehose を明示
Mode detected: sahara で停止EDL/USB driver/session依存WinUSB確認、通常起動→再度 adb reboot edl
--debugmodelogs/log.txt が無いlogs directory不存在mkdir .\logs
edl resetPipe errorreset直後にUSBが切れたUSB IDを確認。通常モードに戻っていれば問題なし
fastboot boot apatch-boot.img が Load ErrorHuawei Fastbootで一時boot認証失敗stock backup確認後 fastboot flash boot
su が一度見つからなかったAPatch側の状態/権限反映前APatch起動後に再確認。最終的に adb shell su -c id 成功

13. 復旧手順

この章は失敗してから探すのではなく、write前に一度読んで、必要なstock imageが手元にあることを確認するための章です。

復旧の基本は「壊れた可能性がある部分だけを、事前に自分で取得したstockへ戻す」です。別個体のboot/ABLを復旧用に使いません。

13.1 APatch boot で起動しないが Fastboot に入れる

最優先:

fastboot flash boot .\backup\boot.img
fastboot reboot

13.2 EDL から stock boot を戻す場合

実機では boot = LUN 4

py .\edl.py w boot .\backup\boot.img `
  --memory=ufs `
  --lun=4 `
  --loader=".\dbyprog_emmc_firehose"

13.3 unlock ABL を stock に戻す場合

abl = LUN 4

py .\edl.py w abl .\backup\abl.img `
  --memory=ufs `
  --lun=4 `
  --loader=".\dbyprog_emmc_firehose"

stock ABL に戻す場合は patched boot のままにせず、stock boot も戻すこと。

ADBからEDLへ入れない状態で Fastboot も起動しない場合、ソフトウェアだけでは復旧できず、engineering cable / test point 等の物理 EDL が必要になる可能性がある。


14. 作業後に行うこと

  • Windows のメモリ整合性を再有効化
  • 不要なら USB Debugging をOFF
  • stock backup を2か所以上へ保存
  • manifest.csv と第三者バイナリのSHA-256を保存
  • APatch SuperKeyを安全に保管
  • root権限は信頼できるアプリにのみ許可
  • OTA update を自動適用しない
  • OS更新前には boot / abl が上書きされる可能性を確認する

15. 再現性チェックリスト

このチェックリストは「作業した項目」ではなく、次へ進む条件を満たしたかを確認するために使います。特にhash・LUN・read-backのチェックを飛ばさないことを重視しています。

  • 型番が DBY-W09
  • SoCが Snapdragon 865 / SM8250
  • 地域コードを確認した
  • HiSuite rollback先が同一地域コード
  • EDL USB IDが 05C6:9008
  • Get-FileHash .\dbyprog_emmc_firehose -Algorithm SHA256 を実行した
  • Firehose SHA-256が a0e08a0a26b1356e04fb3b3097c70237a2e3e0861dbd1a99cafbab4f5adc7c9d
  • Sahara HWID / PK_HASHを記録した
  • printgpt で実機のLUNを確認した
  • GPTを保存した
  • abl, boot, oeminfo, xbl, xbl_config等をバックアップした
  • backupのサイズがGPTのpartition sizeと一致した
  • backupのSHA-256を保存した
  • Get-FileHash .\abl_hw865870unlock.elf -Algorithm SHA256 を実行した
  • unlock ABL SHA-256が 552e96d2565627563b7f2b072f720efd048abdf11fa050959aec55e7d3f0b79d
  • abl 書き込み後に読み戻して一致確認した
  • fastboot oem get-bootinfounlocked
  • stock boot.img のSHA-256が 76BA5F2EAFB76D1FE076783E138A243DEF3917A35BB99413CC86C1A35E5206DD
  • stock boot.img をAPatchでpatchした
  • patched bootのSHA-256を自分のmanifestへ記録した
  • patched bootのSHA-256がstock bootと異なることを確認した
  • patched bootのサイズがboot partitionと一致した
  • fastboot flash boot がOK
  • adb shell su -c iduid=0(root)
  • 復旧用stock filesを別媒体にも保存した

公開前チェック

  • コードブロックのPowerShell改行 ` が崩れていない
  • SHA-256が途中で折り返されず、コピー可能
  • 表がスマートフォン幅でも読める
  • [^edl] などの脚注が本文から移動できる
  • 脚注から本文へ戻れる
  • 外部URLのリンクカード表示を確認した
  • draft: true を公開時に false へ変更した

脚注はこのサイトのMarkdown実装が対応している前提で記述しています。脚注の表示と戻りリンクを実ブラウザで確認してから公開してください。


16. 参考文献

一次・公式資料

  1. bkerler/edl — Qualcomm Sahara / Firehose client

UFSの printgpt, r, rl, w, gpt 等のコマンド仕様を参照。

  1. APatch Documentation — Installation

Bootloader Unlock、stock boot.img のbackup、APatchによるboot patch、ARM64/kernel要件を参照。

  1. Huawei HiSuite 日本公式

  2. Huawei HiSuite rollback FAQ

  3. Huawei — ew_usbccgpfilter.sys / メモリ整合性問題

  4. Android Developers — OEM USB driver installation

  5. Zadig 公式

7.1. Android Open Source Project — Verified Boot / Boot flow

verifiedbootstate=orange とUNLOCKED状態の関係を確認。

DBY-W09 固有のコミュニティ資料

  1. 4PDA — Huawei MatePad 11 (2021) DBY-W09 discussion / root procedure

  2. 4PDA — EDL / Zadig / WinUSB troubleshooting

  3. 4PDA — unlock ABL + root 成功報告

  4. Reddit — DBY-W09 Bootloader Unlock / Root / GMS guide

    • EDL、ABL書き換え、APatch/Magiskのコミュニティ手順。
    • 一次資料ではないため、公式資料・実機GPT・read-back検証を優先する。

17. この記録から得られた重要な知見

  1. DBY-W09 / C635 / HOS 3.0.0.216 では adb reboot edl が成功しなかった。
  2. 同じ C635 の公式 HOS 2.0.0.278 へ rollback すると、分解なしで adb reboot edl05C6:9008 に入れた。
  3. DBY-W09では bkerler/edl 標準loader自動検出では足りず、専用Firehoseが必要だった。
  4. 実機GPTから abl/boot = LUN 4, ramdisk/oeminfo = LUN 0, xbl = LUN 1 と確認できた。
  5. unlock ABL は書き込み後にread-backし、byte一致を確認してから再起動できた。
  6. この個体では Low-level Format を行わず INFO unlocked になった。
  7. APatch patched boot の fastboot boot は認証エラーになったが、fastboot flash boot は正常に成功した。
  8. 最終的に SELinux Enforcing のまま su で UID 0 を取得できた。

最小限の原則

この作業で最も重要なのは、「ネット上の手順をそのまま実行する」のではなく、各段階で実機状態を観測してから次に進むことである。

USB IDを確認
→ HWID/PK_HASHを確認
→ GPTを確認
→ partition/LUNを確認
→ stockをread-back
→ hash/sizeを確認
→ 1 partitionだけwrite
→ 再readしてverify
→ その後にreboot

この順序を崩さないことが、再現性とbrick時の復旧可能性を大きく左右する。

Footnotes

  1. Firehose programmer はQualcomm EDLでストレージのread/write等を行うために端末側で実行されるloaderです。bkerler/edl では --loader で明示指定できます。今回のDBY-W09では標準loader自動検出では足りず、第三者配布のDBY-W09用FirehoseをSHA-256固定で使用しました。 2

  2. ABL (Android Boot Loader) はQualcomm系端末のboot chainに含まれるbootloader componentです。この記事では実機GPT上で abl = LUN 4 を確認した上で、その1 partitionだけを書き換えています。 2

  3. Android Open Source Projectでは、bootloaderが UNLOCKED のとき androidboot.verifiedbootstateorange とされています。参照: https://source.android.com/docs/security/features/verifiedboot/boot-flow 2

  4. SHA-256はファイル内容から計算するdigestです。同じSHA-256であることは「同じ名前」や「同じサイズ」より強い同一性確認になります。ただし、第三者バイナリが安全であること自体をSHA-256が保証するわけではありません。ここでは今回成功した入力物と同一かを確認する識別子として使っています。

  5. EDL (Emergency Download Mode) はQualcomm SoCの低レベルなダウンロードモードです。この記事では、EDLへ入ったかを画面の見た目ではなく VID_05C6&PID_9008 で判定しています。

  6. APatch公式Installationでは、Bootloader Unlock、stock boot.img の用意・バックアップ、boot image patch、ARM64/kernel要件が案内されています。記事執筆時点の参照先: https://apatch.dev/install.html 2

  7. Androidのroot (uid=0) とSELinuxは別レイヤです。uid=0 を取得しても getenforceEnforcing のままなのは正常に起こり得ます。この記事の実機でも最終的にその状態を確認しました。

この記事を書いた人

kinn00kinnSoftware / Research / Writing