Root Android Phone: Zenfone Max M2

7 minute read

最近的研究正好有 root Android 手機的需求,心想既然難得有研究 Android root 的機會,乾脆寫一篇文章做個筆記,加上坊間大部分 root 的文章或教學,都沒有解釋每個步驟大致上在做什麼,這使得某個步驟出錯時,debug 會變得非常困難,因此我就順便研究了 root 幾個步驟的細節,希望之後回來看應該蠻受用的。

之後 blog 會考慮加上 comment 系統,因為這篇文章可能蠻多細節不是這麼正確,但我目前還沒物色到一個符合我需求的 commenting server。

Bootloader

在作業系統開起來之前,需要跑的東西就是 bootloader,裡面基本上有好幾個分區 (partition),例如 boot、recovery 以及 ramdisk。ramdisk 這裡先不提,少數的手機需要用到這個 partition;而 recovery 顧名思義就是當無法正常開機時,例如 boot 無法開機,我們至少還能從 recovery partition 開機,進行一些簡單的操作或修復,預設的恢復原廠設定 (factory reset) 也可以從這裡進行,下圖是我手機進入 recovery 的畫面。

而今天的主角是 boot,boot 是主要用來開機的分區,手機預設會從 boot partition 開機,例如我今天拿來實驗的手機 Asus Zenfone Max M2 (ZB633KL, 2020 一月生產),他出廠時 boot partition 是 Android 8.1 + Asus 自己塞的一些東西。我們可以透過設定中的關於手機下的版本號碼 (Build number) 看到這個 boot image 是 OPM1.WW_Phone-15.2016.1902.159-20190227,Asus 官方也有提供這個 boot image 下載,版本號是 Version WW-15.2016.1902.159,不過這一包其實除了 boot image (boot.img) 還有其他韌體以及安裝腳本,我們這裡只需要在意這個原廠 boot image,這個 image 我們稱作 stock image / factory image

至於官方有沒有提供 recovery 分區的原廠 image 呢?這點各家廠牌不大相同,以 Asus 為例,他的 recovery image 應該是嵌在 boot image 裡面,在第一次用官方 boot image 開機的時候,他會把官方的 recovery image 寫到 recovery partition 中,這點其實會造成後續 TWRP 安裝的麻煩

Unlock Bootloader

OK 現在我們有了基本 bootloader 跟 partition 的知識了,這樣聽起來似乎只要把 boot partition 燒成 rooted 過後的 image 就可以成功 root,但是大部分廠商的 bootloader 是鎖起來的,想要嘗試燒入 (flash) image 進去會得到 Partition flashing is not allowed,當然沒這麼容易,因此下一步要做的是解鎖 bootloader,值得一提的是,有些廠商出廠的手機預設就是解鎖過的 bootloader,可以省掉不少麻煩。

解鎖 bootloader 主要有兩個方法,第一個是利用手機上的軟體的漏洞來提昇權限達成,因為我不是 Trust Zone / Android booting procedure 方面的專家,有興趣的讀者可以參考這篇 unlock Motorola 手機的 write-up;另外一種就是透過手機廠商官方(當然他們要有提供)的 unlock tool 來達成,例如 ASUS 與 Moto G5 Plus 都有提供官方 unlock 教學,我們以 ASUS 為例,解鎖非常簡單,只要下載 UnlockTool 然後安裝到手機上,閱讀完可能的風險如失去保固就可以解鎖了。此外大部分廠商直接提供的解鎖工具都會要求連上網路或是到官方網站登記,如 ASUS 會上傳這隻手機的 IMEI,我猜可能這樣他們之後就能以此為理由拒絕提供保固。

要注意的是 UnlockTool 會把所以資料都清除,記得先備份,下圖也可以看到 unlock 會跳出一堆警告,確保使用者真的知道自己在做什麼XD

Flash The Partition

現在我們擁有 partition 的寫入權限,回到 bootloader 的畫面我們就能透過 fastboot flash 來燒入 image 到指定的 partition 當中,那我們是不是只要找個 root 過後的 image 就能 root 了呢?理論上是,而且這是最簡單的作法,不過我不知為什麼,好像沒有什麼人會這樣做,我猜想的原因可能是 image 的差異性太大了,例如不同國家製造的同一型號的手機,出廠的硬體跟韌體也會有所不同,只要 boot 到不合適的 image,就會卡在開機畫面無法開機。其實我在 root 過程中也遇到了這個情況,一度以為手機變磚了,但好在官方有提供原始的 boot image,我可以再 flash 回去 boot partition。

因此,比較主流的作法是大家都是在原有的 image 上做 patch 來獲得 root 權限,最常見的就是用 Magisk (作者是台灣人,聽說是當兵的時候開發的XD)。在這之前,我們要先安裝 TWRP,TWRP 可以在備份/恢復/修改 partition,此外也可以用來安裝 firmware,因此一般都會先安裝 TWRP 以免之後不小心弄壞 partition (假如官方沒有提供 boot image)。

當然也可以在不安裝 TWRP 的情況下,直接用 Magisk 來 patch boot image,再用 patch 過後的 image 來開機,就可以拿到 root 了,這個步驟在 Magisk 官方 boot image patching 有提到,不過因為我的手機不符合那些要求,所以我沒有使用這個方法,而是先安裝 TWRP 再 flash Magisk。

Install TWRP

首先是安裝 TWRP,我們要把他安裝在 recovery partition 下,要寫入 partition 必須要進入手機的 fastboot 模式,以下有兩個方法可以讓手機進入 fastboot 模式開機:

  1. 透過 adb 操作, adb reboot bootloader
  2. 手機通常會有自訂的特殊開機按鍵 (每個型號不同),我們可以透過該按鍵進入選單,來選擇 fastboot 開機模式

下圖是我手機進入 fastboot (bootloader) 的畫面,基本上什麼都沒有,只能夠過電腦下 fastboot 指令溝通。

接著我們在電腦上下載該手機型號的 TWRP recovery image ,這可以在官方網站找到,這次實驗的手機型號是 Asus Zenfone Max M2,下載指定的 TWRP image 後執行 fastboot flash recovery twrp.img ,成功寫入後就可以準備用 recovery partition 來開機了。

這裡要注意的是,如同這裡提到的:

Note many devices will replace your custom recovery automatically during first boot. To prevent this, use Google to find the proper key combo to enter recovery. After typing fastboot reboot, hold the key combo and boot to TWRP. Once TWRP is booted, TWRP will patch the stock ROM to prevent the stock ROM from replacing TWRP. If you don’t follow this step, you will have to repeat the install.

這隻手機的確會這樣做,所以害的我又得再進入一次 fastboot,再 flash 一次 TWRP,再用手機特殊按鍵進入 recovery 模式,就能看到 TWRP 了。

接下來我們要做的事情是,先備份手機原有的 boot image,以免發生意外無法復原,備份完再來刷 Magisk,不過這裡要先處理 dm-verity 跟 dm-crypt (ForceEncryt)。

dm-verity and dm-crypt

dm-verity

dm-verity 是在 kernel 中的功能,他會檢查整個 boot partition 是否有被更動過,如果有的話就不允許繼續開機流程,這顯然會造成 root 手機的一大阻礙。根據 TWRP 的說明,解法是安裝新的 kernel 然後 disable 這個功能,我們才能夠修改它。不過這隻 Zenfone Max M2 貌似在解鎖 bootloader 的時候,就幫忙 disable 了 dm-verity 的功能,使得他每次開機都會警告你他無法檢查 boot image 的 integrity,官方幫我們處理掉 dm-verity 對我們而言當然是一大好事。

除了安裝 kernel,Magisk 貌似也有提供 disable dm-verity 的功能,XDA developer 似乎有開發出 disable dm-verity 的工具,可以參考這篇文章,坊間也有流傳 no-verity-opt-encrypt 幫你 patch 好,不需要用那個工具自行處理,這些我都沒有使用所以大家就參考看看吧。

dm-crypt (ForceEncrypt)

下一步要說明的是 dm-crypt (ForceEncryt),首先我要先聲明這部份的機制蠻複雜的,牽扯到太多 Android 的知識,還有 Magisk 的原理,我這裡只能嘗試解釋我知道的部份,可能有所訛誤。

ForceEncrypt 也是 kernel 中的功能,kernel 在開機後會檢查目前的檔案系統有沒有加密,沒有的話他會嘗試加密,流程可以參考官方文件。不幸的是這隻手機的 fstab 有開啟 force encryption 這個 flag,而且因為 TWRP 只有支援部份的 decrytion,這代表著我們無法存取系統資料,自然也就沒有辦法進行備份,不過沒關係,在不更動 boot image 的情況下,我們仍然可以使用 TWRP wipe + format data 的功能,把 /data 全部清除掉成為加密的狀態,反正 Android 開機後會重新對檔案系統進行加密,加密完手機還是可以正常運作。

再者,Magisk 正常情況下是可以在加密的系統下進行的,Magisk 會對 boot image 進行 patch,而不是修改目前的檔案,所以其實 ForceEncrypt 並不會對 root 造成什麼阻礙。

上述提及的 XDA developer 工具也可以 disable ForceEncrypt ,可以參考這篇文章Magisk 也有類似的功能,不過一樣我都沒有嘗試過。

Flash Magisk

最後一步就是刷入 Magisk,讓他對 boot image 進行動態 patch,首先執行 adb push Magisk-v20.4.zip /tmp/ 把Magisk 上傳到手機,然後再至 TWRP install 安裝 /tmp/ 下的 Magisk,重開機之後我們就獲得 root 權限了,大功告成!

ASUS_X01A_1:/ $ su
ASUS_X01A_1:/ # id
uid=0(root) gid=0(root) groups=0(root) context=u:r:magisk:s0

如果之後會用 adb 進行一些修改系統的操作的話,可以考慮關閉 SE Linux setenforce 0 ,permissive 他就不會跳 permission denied error 了。

Step-by-step Tutorial

整理一下步驟:

  1. 開啟 USB debugging
  2. 安裝官方 unlock tooladb install recoverytool.apk,手機會跳出詢問 Google play 保護,選擇拒絕
  3. 因為 unlock 需要連上網路,所以要連上 Wifi 或是行動網路
  4. 執行 unlock tool 並同意全部,手機會自動重開機
  5. 長按 power 重開機並同意,在手機重開機進入系統之前按下音量鍵進入選單
  6. 選擇 fastboot 模式
  7. 安裝 TWRP fastboot flash recovery twrp.img
  8. fastboot reboot 重開機,一樣在手機進入系統之前按下音量鍵進入選單
  9. 選擇 recovery 模式,會看到 TWRP 界面
  10. 如果他詢問密碼,直接取消略過
  11. 滑動並允許他 patch 系統 image
  12. 上傳 Magisk 到內部儲存空間,adb push Magisk-v20.4.zip /sdcard
  13. 在 TWRP 選擇 install 再安裝 Magisk.zip, 滑動允許安裝
  14. 回到主選單,選擇 reboot -> system -> do not install,等待手機重開機
  15. 如果有的話,忽略警告視窗,並等待背景的加密完成,完成後會自動重開機
  16. 忽略警告視窗,並檢查 MagiskManager 是否有正確安裝
  17. 如果沒有,則再透過 adb 安裝 adb install magiskmanager.apk, 可以忽略 additional setup 沒問題
  18. 開啟 USB debugging,檢查是否獲得 root 權限, adb shell su -c id