裝置是 myron,POCO F8 Ultra / Redmi K90 Pro Max,Snapdragon 8 Elite Gen 5。我手上有兩支。第一支是臺版,第二支也是臺版——會買第二支,就是因為第一支的 root 死活做不出來。

2026 年 7 月 7 日,Nebula Security 公開了 GhostLock(CVE-2026-43499):Linux 核心 futex PI requeue 路徑的 use-after-free,2011 年就存在,影響幾乎所有核心,公開 exploit 成功率 97%,還是 Google kernelCTF 強制公開的那種。大陸社群反應很快,幾天內各機型的偏移量就算好了,包成 payload 在酷安到處發。K90 Pro Max 的現成品一堆。

我的臺版,全部不能用。

十幾天的嘗試、AI 陪跑三天三夜,都算不出來。最後我放棄,買了第二支手機走另一條路。直到這個月回頭拆開三個 ROM,才看到答案:同一支手機、同一個 codename,臺版和陸版的核心根本不是同一顆 binary。而那些 payload 寫死的,恰恰是跟著 binary 走的東西。

三個 ROM,三顆核心

手上的 ROM:臺版 3.0.1.0(出廠版本)、臺版 3.0.6.0、xiaomi.eu 306 和 308(陸版底)。把 boot.img 解開,先看核心版本字串:

ROM uname -r 編譯時間
臺版 3.0.1.0.WPMTWXM ...-ga5f232d1ead0-ab14083253-4k 2025-09-11
臺版 3.0.6.0.WPMTWXM ...-g5a0e85dd9db0-ab14499855-4k 2025-11-26
陸版 306/308.WPMCNXM ...-g16e473de48a3-abogki462654244-4k 2025-11-19

base 都是 6.12.23-android16-5,但 git commit 三個都不同。更關鍵的是 build ID:陸版是 abogki 開頭,代表它貼著 Google 官方 GKI release 分支走;臺版是 ab1xxxxxxx,小米自己的整合分支自己編。

接著把三顆核心的 kallsyms 整個抽出來,各約 12.5 萬個符號,直接對:

符號 臺版(兩版相同) 陸版 差距
init_task ...823ecf00 ...823fcf00 +0x10000
init_cred ...82402a68 ...82412a68 +0x10000
selinux_state ...826684f0 ...8267a5b8 +0x120c8
random_table 三版全不同

注意 selinux_state 那行:差距是 0x120c8,不是跟別人一樣的 0x10000。這代表不是整體平移,是符號配置真的被洗亂了。而且連臺版自己 3.0.1 升 3.0.6,rt_mutex 那幾個漏洞相關函數的位置都已經換過。config 也有差:陸版多開了七個 XIAOMI_* 選項。

為什麼偏移量不能共用

GhostLock 是 data-only exploit。它要的不是 shellcode,是「這一次編譯出來的 init_cred 在哪個位址」。十幾個位址,寫死在 payload 裡。

我用核心內嵌的 BTF 把三版的 struct 布局整個解析出來:task_struct 都是 5184 bytes,cred 都在 0x900,pi_blocked_on 都在 0xA18,一個 byte 都沒差。也就是說,觸發邏輯通用、結構欄位通用,唯一不通用的就是那張位址表。

但 exploit 沒有那張表就是打空氣。打錯位址,最好的情況是沒反應,常見的情況是 kernel panic 直接重開機。

所以結論很硬:所有為陸版 ogki 核心算的 payload,在臺版核心上永遠是錯的。不是小米故意擋,是兩條發版線本來就各編各的——陸版追官方 GKI 分支求快,國際版有自己的 patch queue 和認證凍結點,加上全部用 +pgo +bolt +lto 編譯,PGO/BOLT 會依 profiling 重排函數位置,任何一點程式碼差異都會把符號表整個洗亂。會被這件事打到的人,在小米的使用者統計裡小到不存在,所以永遠不會有人有動機對齊。

我付過的三種成本

回頭看,當時擺在面前的是三條路:

蹲官方解鎖名額。 小米國際版每天零點放名額,限量,跟你競爭的是一堆腳本。今晚蹲不到,明天再蹲。成本是健康,無上限,而且付了不保證有。我的身體狀況熬夜不了,這條路對我來說等於不存在。

算臺版偏移。 成本是時間。十幾天沒結果,AI 陪跑三天三夜也沒出來。當時等於無解。

買第二支。 成本是錢,一次性,確定性交付。兩支加起來四萬六,後來第一支便宜賣給家人,回收一萬五,淨成本三萬一。

順帶一提過程裡的另一個變數:美國的模型看到 kernel exploit 就拒絕幫忙,不管你的理由是「自己的手機、要做無障礙工具、漏洞已公開」。最後是 DeepSeek 陪我耗那三天三夜。願意和能夠,是兩個獨立的軸。

事後檢討這個決策:用當時掌握的資訊,買手機是對的——三個選項裡唯一成本可預測的。但誠實說,這筆錢有一部分是知識溢價。解法當時就存在,只是我和陪我的 AI 都不知道那條路。

三天三夜和半小時的差別,不是算力,是路線

當年卡死的原因是:想在沒有 root 的手機上,從執行期 leak 出符號位址。那是難路,要靠側信道、要靠運氣。

這次走的路是靜態的:ROM 本來就躺在我自己的 Downloads 裡。boot.img 解開,完整 kallsyms 就在裡面,12.5 萬個符號全部直接可讀。不需要 root、不需要 leak、不需要運氣。

而且靜態路線還有一個意料之外的好處:乾淨。我第二支手機後來刷了第三方核心、套了 KSU,從實機 dump 出來的 kallsyms 已經是被改過的。ROM 裡的 boot.img 才是沒被汙染的 ground truth。

只抽符號還不夠,還要證明抽出來的是對的。交叉驗證的做法是:用抽出來的位址,回讀 binary 裡對應位置的內容——init_task 的 comm 欄位讀出來要是「swapper」、init_cred 的 usage 要是個小整數、init_uts_ns 的 release 欄位要逐字元等於這顆核心的 uname 字串。三個獨立來源(kallsyms 提取、BTF 欄位、原始 binary)互相對得上,臺版和陸版各自驗證都通過。到這裡,不需要實機就能信任這份偏移。

後面的組裝就很順:以 ghostlock-oneplus 為底加一個臺版 target,它內建的 struct 偏移跟我從 BTF 算的逐欄吻合;反組譯確認 pselect 的棧配置,跟已驗證可行的 Xiaomi 17 完全相同;NDK 一次編過,零警告。

從動手到編出 binary,半小時。

放出來,以及放出來的方式

東西在 github.com/jason5545/ghostlock-myron-tw:臺版偏移表、分析、編好的 binary,還有把我這次整套流程工具化的三支腳本——抽偏移、驗 struct、驗棧配置,都內建「驗證不過就不准用」的檢查。

刻意沒放的東西:小米的專有韌體、別人的 EFI 工具、FRP 相關的步驟。原因是看過前車之鑑:之前有一套同類的一鍵解鎖工具,作者的封存公告寫得很直白——極大比例的使用者拿它只是為了跑遊戲外掛,還有人拿去收錢代刷、自己不懂原理把客戶手機刷成磚,最後一個學生開發者被白嫖到心累收攤。一鍵包養出那種生態,所以我發的是教科書,不是槍。會自己編譯的人,就是這些東西該到的人手上;「要自己編」這道門檻,恰好就是過濾器。

還有一個已知限制:這份偏移只覆蓋 WPMTWXM。MIXM、EUXM 這些其他區域版本,核心可能又不同。但方法是可以帶走的,工具都公開了,任何冷門區域版本的持有者都能自己產生他那份表。

卡我最久的,不是技術難度

第一支手機現在在家人手上,我故意讓它停在 3.0.6.0 沒更新。這次編出來的東西,就是要拿去救它的。

回頭看整件事,最貴的從來不是漏洞本身。是「會算偏移的人都在陸版」這個結構:漏洞在臺版核心裡躺著,會躺到 OTA 修補把它關掉為止,期間不會有人碰它,因為沒有人有動機為小眾區域版本算那張表。如果不是這次自己拆,臺版大概永遠不會有人解。

知識不對稱的價格,是一支手機。現在臺版的表算出來了、工具也公開了,這個結構裡至少少一個要付這筆錢的人。