#Requires -Version 5.1 # ============================================================================= # XeraX Root Tool v1.4 # Root with Locked Bootloader — GBL / EFISP Exploit # # Exploit research : superturtlee # github.com/superturtlee/gbl_root_canoe # PowerShell automation : XeraX Team # xeraxapp.com/root # # Supports: OnePlus 15 / 15T / 13, Xiaomi 17 Ultra, RedMagic 11 Pro, # Nubia Z80 Ultra, Lenovo Legion Y700, and more # Requires: Snapdragon 8 Elite, firmware BEFORE March 2026 # ============================================================================= $ProgressPreference = 'SilentlyContinue' # ── Colour helpers ───────────────────────────────────────────────────────────── function W { param($m,$c='White') Write-Host $m -ForegroundColor $c } function Ok { param($m) Write-Host " [+] $m" -ForegroundColor Green } function Info { param($m) Write-Host " [*] $m" -ForegroundColor Cyan } function Warn { param($m) Write-Host " [!] $m" -ForegroundColor Yellow } function Err { param($m) Write-Host " [X] $m" -ForegroundColor Red } function Hr { W ('─' * 60) DarkGray } function Pause{ Read-Host "`n Press ENTER to close"; exit 1 } # ── Enable TLS 1.2 for all web requests ──────────────────────────────────────── [Net.ServicePointManager]::SecurityProtocol = ` [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 # ── GitHub API helper (adds required User-Agent header) ──────────────────────── function Get-GhRelease { param($repo) try { return Invoke-RestMethod ` -Uri "https://api.github.com/repos/$repo/releases/latest" ` -Headers @{'User-Agent'='XeraX-Root-Tool'} ` -ErrorAction Stop } catch { return $null } } # ── Safe download helper ──────────────────────────────────────────────────────── function Get-File { param($url, $dest, $label) Info "Downloading $label ..." try { Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing -ErrorAction Stop return $true } catch { Warn "Download failed for $label : $_" return $false } } # ── Unblock this script (removes Windows Mark-of-the-Web) ───────────────────── try { if ($MyInvocation.MyCommand.Path) { Unblock-File -Path $MyInvocation.MyCommand.Path -ErrorAction SilentlyContinue } } catch {} # ── Banner ───────────────────────────────────────────────────────────────────── Clear-Host W "" W " ██╗ ██╗███████╗██████╗ █████╗ ██╗ ██╗" Cyan W " ╚██╗██╔╝██╔════╝██╔══██╗██╔══██╗╚██╗██╔╝" Cyan W " ╚███╔╝ █████╗ ██████╔╝███████║ ╚███╔╝ " Cyan W " ██╔██╗ ██╔══╝ ██╔══██╗██╔══██║ ██╔██╗ " Cyan W " ██╔╝ ██╗███████╗██║ ██║██║ ██║██╔╝ ██╗" Cyan W " ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝" Cyan W "" W " Root Tool v1.4 — xeraxapp.com/root" DarkGray W " Exploit: superturtlee/gbl_root_canoe | Automation: XeraX Team" DarkGray W "" Hr W "" # ============================================================================= # STEP 1 — Prerequisites Check # ============================================================================= W " STEP 1 of 6 — Prerequisites Check" White Hr Info "Checking PowerShell version..." if ($PSVersionTable.PSVersion.Major -lt 5) { Err "PowerShell 5.1 or later is required." W " Download: https://aka.ms/wmf5latest" Gray Pause } Ok "PowerShell $($PSVersionTable.PSVersion) ✓" Info "Checking internet connection..." $hasInternet = $false try { $null = Invoke-WebRequest -Uri "https://clients3.google.com/generate_204" ` -TimeoutSec 5 -UseBasicParsing -ErrorAction Stop $hasInternet = $true } catch {} if ($hasInternet) { Ok "Internet connected ✓" } else { Warn "No internet — auto-download features disabled" } # Resolve script directory (works in all launch scenarios) if ($PSScriptRoot -and $PSScriptRoot -ne '') { $scriptDir = $PSScriptRoot } elseif ($MyInvocation.MyCommand.Definition -and $MyInvocation.MyCommand.Definition -ne '') { $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition } else { $scriptDir = (Get-Location).Path } $ptDir = Join-Path $scriptDir "platform-tools" $toolsDir = Join-Path $scriptDir "xerax-tools" function Find-Tool { param($name) $local = Join-Path $scriptDir "$name.exe" $inPT = Join-Path $ptDir "$name.exe" $cmd = Get-Command $name -ErrorAction SilentlyContinue $inPath = if ($cmd) { $cmd.Source } else { $null } foreach ($p in @($local, $inPT, $inPath)) { if ($p -and (Test-Path $p)) { return $p } } return $null } $adbPath = Find-Tool "adb" $fbPath = Find-Tool "fastboot" if (-not $adbPath -or -not $fbPath) { W "" Warn "ADB / Fastboot not found." if (-not $hasInternet) { Err "No internet — cannot auto-download." W " Get Platform Tools: https://developer.android.com/tools/releases/platform-tools" Gray Pause } $choice = Read-Host " Auto-download ADB from Google now? (Y/N)" if ($choice -notmatch '^[Yy]') { Pause } $zipPath = Join-Path $env:TEMP "pt-tools.zip" if (-not (Get-File "https://dl.google.com/android/repository/platform-tools-latest-windows.zip" $zipPath "Platform Tools")) { Pause } try { Expand-Archive -Path $zipPath -DestinationPath $scriptDir -Force -ErrorAction Stop Remove-Item $zipPath -Force -ErrorAction SilentlyContinue } catch { Err "Extraction failed: $_"; Pause } $adbPath = Join-Path $ptDir "adb.exe" $fbPath = Join-Path $ptDir "fastboot.exe" if (-not (Test-Path $adbPath)) { Err "adb.exe not found after extraction."; Pause } Ok "Platform Tools installed ✓" } Ok "ADB: $adbPath" Ok "Fastboot: $fbPath" # ============================================================================= # STEP 2 — USB Debugging Setup # ============================================================================= W "" W " STEP 2 of 6 — Enable USB Debugging on Your Phone" White Hr W "" W " ① Settings → About Phone → tap Build Number 7 times" Gray W " ② Settings → Developer Options → USB Debugging ON" Gray W " ③ Connect phone via USB data cable → tap ALLOW on the popup" Gray W "" W " No USB driver? Install: https://developer.android.com/studio/run/win-usb" Gray W "" Read-Host " Press ENTER when connected and USB Debugging is enabled" # ============================================================================= # STEP 3 — Device Detection # ============================================================================= W "" W " STEP 3 of 6 — Device Detection" White Hr try { & $adbPath start-server 2>&1 | Out-Null } catch {} $maxWait = 45; $waited = 0; $deviceSerial = $null while ($waited -lt $maxWait) { $adbOut = & $adbPath devices 2>&1 $authorized = $adbOut | Where-Object { $_ -match '\tdevice$' } $unauth = $adbOut | Where-Object { $_ -match 'unauthorized' } if ($authorized) { $deviceSerial = ($authorized[0] -split '\t')[0].Trim() break } elseif ($unauth) { Warn "Tap ALLOW on the USB Debugging popup on your phone..." } else { Info "Waiting for device ($waited/$maxWait sec)..." } Start-Sleep -Seconds 3; $waited += 3 } if (-not $deviceSerial) { Err "No device found after $maxWait seconds." W " → Try a different USB cable or port" Gray W " → Check Developer Options → Revoke USB debugging authorizations, then retry" Gray W " → Install USB driver: https://developer.android.com/studio/run/win-usb" Gray Pause } $brand = (& $adbPath -s $deviceSerial shell getprop ro.product.brand 2>&1).Trim() $model = (& $adbPath -s $deviceSerial shell getprop ro.product.model 2>&1).Trim() $android = (& $adbPath -s $deviceSerial shell getprop ro.build.version.release 2>&1).Trim() $chip = (& $adbPath -s $deviceSerial shell getprop ro.hardware 2>&1).Trim() W "" Ok "Device : $brand $model" Ok "Android : $android" Ok "Chip : $chip" Ok "Serial : $deviceSerial" # ============================================================================= # STEP 4 — Firmware Compatibility # ============================================================================= W "" W " STEP 4 of 6 — Firmware Compatibility" White Hr $patch = (& $adbPath -s $deviceSerial shell getprop ro.build.version.security_patch 2>&1).Trim() Ok "Security patch: $patch" $cutoff = [datetime]"2026-03-01"; $patchDate = $null try { $patchDate = [datetime]::ParseExact($patch, "yyyy-MM-dd", $null) } catch {} if (-not $patchDate) { Warn "Could not parse patch date — proceeding." } elseif ($patchDate -ge $cutoff) { Err "PATCHED FIRMWARE — exploit closed in March 2026." W " Your patch ($patch) is at or after the cutoff. This tool cannot root this firmware." Yellow W " Check xeraxapp.com/root for updates." Gray Pause } else { Ok "Firmware is compatible — before March 2026 cutoff ✓" } # ============================================================================= # STEP 5 — Auto-acquire EFI + init_boot (the magic step) # ============================================================================= W "" W " STEP 5 of 6 — Auto-acquiring Required Files" White Hr if (-not (Test-Path $toolsDir)) { New-Item -ItemType Directory -Path $toolsDir -Force | Out-Null } # ── 5A: Download EFI toolkit from superturtlee/gbl_root_canoe ───────────────── W "" W " [A] EFI Toolkit" White $efiFile = $null # Check if EFI already exists from a previous run $existingEfi = Get-ChildItem -Path $scriptDir, $toolsDir -Filter "*.efi" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 if ($existingEfi) { $efiFile = $existingEfi.FullName Ok "EFI already present: $($existingEfi.Name) ✓" } elseif ($hasInternet) { Info "Fetching latest gbl_root_canoe release from GitHub..." $ghRel = Get-GhRelease "superturtlee/gbl_root_canoe" if ($ghRel) { $tkAsset = $ghRel.assets | Where-Object { $_.name -like "*windows*" } if (-not $tkAsset) { $tkAsset = $ghRel.assets | Select-Object -First 1 } if ($tkAsset) { $tkZip = Join-Path $toolsDir "gbl-toolkit.zip" if (Get-File $tkAsset.browser_download_url $tkZip "gbl-toolkit ($($tkAsset.name))") { try { Expand-Archive -Path $tkZip -DestinationPath $toolsDir -Force Remove-Item $tkZip -Force -ErrorAction SilentlyContinue Ok "Toolkit extracted ✓" } catch { Warn "Extraction failed: $_" } } } } else { Warn "Could not reach GitHub API — check connection" } # Scan extracted toolkit for EFI, prefer device-specific match $allEfi = Get-ChildItem -Path $toolsDir -Filter "*.efi" -Recurse -ErrorAction SilentlyContinue if ($allEfi) { $brandLow = $brand.ToLower(); $modelLow = $model.ToLower() $specific = $allEfi | Where-Object { $n = $_.BaseName.ToLower() $n -match $brandLow -or $n -match $modelLow -or $n -match ($model -split '\s' | Select-Object -First 1).ToLower() } $efiFile = if ($specific) { ($specific | Select-Object -First 1).FullName } else { ($allEfi | Where-Object { $_.Name -notmatch '^generic_' } | Select-Object -First 1)?.FullName } if (-not $efiFile) { $efiFile = ($allEfi | Select-Object -First 1).FullName } if ($efiFile) { Ok "EFI selected: $(Split-Path -Leaf $efiFile) ✓" } } } if (-not $efiFile) { # Manual fallback — check if user placed EFI in script dir $manual = Get-ChildItem -Path $scriptDir -Filter "*.efi" -ErrorAction SilentlyContinue | Select-Object -First 1 if ($manual) { $efiFile = $manual.FullName Ok "EFI found in script folder: $($manual.Name) ✓" } else { Err "No EFI file found." W "" W " Download manually from:" Yellow W " https://github.com/superturtlee/gbl_root_canoe/releases" Gray W " Place the .efi file in the same folder as XeraX-Root.ps1" Gray Pause } } # ── 5B: Extract init_boot.img directly from the device ──────────────────────── W "" W " [B] init_boot.img — Extracting from your device" White $initBootFile = Join-Path $toolsDir "init_boot.img" $initBootExists = $false # Check for previously patched file first $patchedFile = @( (Join-Path $scriptDir "init_boot_patched.img"), (Join-Path $toolsDir "init_boot_patched.img") ) | Where-Object { Test-Path $_ } | Select-Object -First 1 if ($patchedFile) { $initBootPatched = $patchedFile Ok "Patched init_boot already present: $patchedFile ✓ (skipping extraction)" $initBootExists = $true } else { Info "Reading active slot..." $slot = (& $adbPath -s $deviceSerial shell getprop ro.boot.slot_suffix 2>&1).Trim() if (-not $slot) { $slot = "_a" } Ok "Active slot: $slot" # Try multiple block device paths used across OEMs $blkPaths = @( "/dev/block/bootdevice/by-name/init_boot$slot", "/dev/block/by-name/init_boot$slot", "/dev/block/bootdevice/by-name/init_boot", "/dev/block/by-name/init_boot" ) $extracted = $false foreach ($blk in $blkPaths) { Info "Trying: $blk ..." # Remove any stale file first & $adbPath -s $deviceSerial shell "rm -f /sdcard/xerax_init_boot.img" 2>&1 | Out-Null $ddOut = & $adbPath -s $deviceSerial shell ` "dd if=$blk of=/sdcard/xerax_init_boot.img bs=4096 2>&1" 2>&1 $ddStr = ($ddOut -join " ").Trim() # dd succeeds when output contains block count (e.g. "xxx+0 records in") if ($ddStr -match '\d+\+\d+ records' -or $ddStr -match 'copied') { $pullOut = & $adbPath -s $deviceSerial pull /sdcard/xerax_init_boot.img $initBootFile 2>&1 if (Test-Path $initBootFile) { $sz = [math]::Round((Get-Item $initBootFile).Length / 1MB, 1) if ($sz -gt 5) { Ok "init_boot.img extracted from device ($sz MB) ✓" $extracted = $true break } else { Remove-Item $initBootFile -Force -ErrorAction SilentlyContinue } } } } if (-not $extracted) { Warn "Could not read init_boot directly (permission denied on this device)." W "" W " Falling back to firmware-based extraction." Gray W "" W " Please place your device's stock firmware ZIP in this folder:" White W " $scriptDir" Gray W "" W " Where to get firmware:" Yellow W " • OnePlus : https://www.oneplus.com/global/support/softwareupgrade" Gray W " • Xiaomi : https://miuirom.org or https://xmfirmwareupdater.com" Gray W " • RedMagic: https://www.nubia.com/en/article/?id=1526" Gray W " • XDA thread for your device model" Gray W "" $ans = Read-Host " Have you placed the firmware ZIP in the folder above? (Y/N)" if ($ans -notmatch '^[Yy]') { Warn "Skipping firmware extraction — you will need to patch init_boot manually." } else { # Auto-extract using payload-dumper-go $fwZip = Get-ChildItem -Path $scriptDir -Filter "*.zip" -ErrorAction SilentlyContinue | Where-Object { $_.Name -notmatch 'platform-tools|gbl-toolkit|xerax' } | Sort-Object LastWriteTime -Descending | Select-Object -First 1 if ($fwZip) { Info "Found firmware ZIP: $($fwZip.Name)" # Download payload-dumper-go if needed $pdPath = Join-Path $toolsDir "payload-dumper-go.exe" if (-not (Test-Path $pdPath) -and $hasInternet) { Info "Downloading payload-dumper-go (extracts init_boot from firmware ZIP)..." $pdRel = Get-GhRelease "ssut/payload-dumper-go" if ($pdRel) { $pdAsset = $pdRel.assets | Where-Object { $_.name -like "*windows*amd64*" -or $_.name -like "*amd64*windows*" } if ($pdAsset) { $pdZip = Join-Path $env:TEMP "payload-dumper.zip" if (Get-File $pdAsset.browser_download_url $pdZip "payload-dumper-go") { try { Expand-Archive -Path $pdZip -DestinationPath $toolsDir -Force Remove-Item $pdZip -Force -ErrorAction SilentlyContinue # Find the exe $found = Get-ChildItem -Path $toolsDir -Filter "payload-dumper-go*.exe" -Recurse | Select-Object -First 1 if ($found) { $pdPath = $found.FullName } } catch {} } } } } if (Test-Path $pdPath) { Info "Extracting init_boot.img from firmware ZIP..." $fwExtDir = Join-Path $toolsDir "fw-extracted" New-Item -ItemType Directory -Path $fwExtDir -Force | Out-Null & $pdPath -p init_boot -o $fwExtDir $fwZip.FullName 2>&1 | Out-Null $extractedIb = Get-ChildItem -Path $fwExtDir -Filter "init_boot*" -Recurse | Select-Object -First 1 if ($extractedIb) { Copy-Item $extractedIb.FullName $initBootFile -Force $sz = [math]::Round((Get-Item $initBootFile).Length / 1MB, 1) Ok "init_boot.img extracted from firmware ($sz MB) ✓" $extracted = $true } else { Warn "init_boot.img not found in firmware ZIP. The ZIP may need to be fully extracted first." } } else { Warn "Could not get payload-dumper-go. Manual extraction needed." } } else { Warn "No firmware ZIP found in: $scriptDir" } } } # ── 5C: Patch init_boot using magiskboot on PC ───────────────────────────── $initBootPatched = $null if ($extracted -and (Test-Path $initBootFile)) { W "" W " [C] Patching init_boot.img with Magisk" White # Download magiskboot.exe (Windows port by svoboda18) $mbPath = Join-Path $toolsDir "magiskboot.exe" if (-not (Test-Path $mbPath) -and $hasInternet) { Info "Downloading magiskboot for Windows (svoboda18/magiskboot)..." $mbRel = Get-GhRelease "svoboda18/magiskboot" if ($mbRel) { $mbAsset = $mbRel.assets | Where-Object { $_.name -like "*.exe" -or $_.name -like "*windows*" -or $_.name -like "*win64*" } | Select-Object -First 1 if ($mbAsset) { Get-File $mbAsset.browser_download_url $mbPath "magiskboot.exe" | Out-Null } } # If no release asset found, try direct known path pattern if (-not (Test-Path $mbPath)) { Get-File "https://github.com/svoboda18/magiskboot/releases/latest/download/magiskboot.exe" ` $mbPath "magiskboot.exe" | Out-Null } } # Download Magisk APK to extract patching binaries $magiskApk = Join-Path $toolsDir "Magisk.apk" if (-not (Test-Path $magiskApk) -and $hasInternet) { Info "Downloading Magisk APK (topjohnwu/Magisk)..." $mgRel = Get-GhRelease "topjohnwu/Magisk" if ($mgRel) { $mgAsset = $mgRel.assets | Where-Object { $_.name -like "Magisk-v*.apk" } | Select-Object -First 1 if ($mgAsset) { Get-File $mgAsset.browser_download_url $magiskApk "Magisk.apk" | Out-Null } } } $patchedOnPc = $false if ((Test-Path $mbPath) -and (Test-Path $magiskApk)) { # Extract Magisk binaries from APK (APK is a ZIP) $magiskBins = Join-Path $toolsDir "magisk-bins" New-Item -ItemType Directory -Path $magiskBins -Force | Out-Null Info "Extracting Magisk binaries from APK..." try { Add-Type -AssemblyName System.IO.Compression.FileSystem $apkZip = [System.IO.Compression.ZipFile]::OpenRead($magiskApk) $needed = @{ 'lib/arm64-v8a/libmagiskinit.so' = 'magiskinit' 'lib/arm64-v8a/libmagisk64.so' = 'magisk64' 'lib/armeabi-v7a/libmagisk32.so' = 'magisk32' 'assets/stub.apk' = 'stub.apk' } foreach ($entry in $apkZip.Entries) { $key = $entry.FullName -replace '\\','/' if ($needed.ContainsKey($key)) { $dest = Join-Path $magiskBins $needed[$key] [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $dest, $true) } } $apkZip.Dispose() $initBin = Join-Path $magiskBins "magiskinit" if (Test-Path $initBin) { Ok "Magisk binaries extracted ✓" } } catch { Warn "Could not extract Magisk bins: $_" } # Run magiskboot patching $patchWork = Join-Path $toolsDir "patch-work" New-Item -ItemType Directory -Path $patchWork -Force | Out-Null Copy-Item $initBootFile (Join-Path $patchWork "init_boot.img") -Force Copy-Item (Join-Path $magiskBins "*") $patchWork -ErrorAction SilentlyContinue Push-Location $patchWork try { Info "Unpacking init_boot.img..." & $mbPath unpack init_boot.img 2>&1 | Out-Null if (Test-Path "ramdisk.cpio") { Info "Injecting Magisk into ramdisk..." & $mbPath cpio ramdisk.cpio ` "add 0750 init magiskinit" ` "mkdir 0750 overlay.d" ` "mkdir 0750 overlay.d/sbin" ` "add 0644 overlay.d/sbin/magisk64 magisk64" ` "add 0644 overlay.d/sbin/magisk32 magisk32" ` "add 0644 overlay.d/sbin/stub.apk stub.apk" ` "patch" 2>&1 | Out-Null Info "Repacking..." & $mbPath repack init_boot.img 2>&1 | Out-Null $repacked = Join-Path $patchWork "new-boot.img" if (Test-Path $repacked) { $dest = Join-Path $toolsDir "init_boot_patched.img" Copy-Item $repacked $dest -Force $sz = [math]::Round((Get-Item $dest).Length / 1MB, 1) $initBootPatched = $dest $patchedOnPc = $true Ok "init_boot.img patched on PC ($sz MB) ✓" } else { Warn "magiskboot repack did not produce output file." } } else { Warn "magiskboot unpack did not produce ramdisk.cpio." } } catch { Warn "magiskboot error: $_" } finally { Pop-Location } } # ── Fallback: patch on-device using Magisk app ───────────────────────── if (-not $patchedOnPc) { W "" Warn "On-PC patching unavailable — using Magisk app on device (1 manual step)." W "" # Push init_boot.img to device sdcard Info "Pushing init_boot.img to your phone..." & $adbPath -s $deviceSerial push $initBootFile /sdcard/xerax_init_boot.img 2>&1 | Out-Null # Install Magisk APK if available if (Test-Path $magiskApk) { Info "Installing Magisk app on your phone..." $installOut = & $adbPath -s $deviceSerial install -r $magiskApk 2>&1 if (($installOut -join "") -match "Success") { Ok "Magisk installed ✓" } else { Warn "APK install may have failed — install Magisk manually if needed" } } else { Warn "Magisk APK not downloaded — install Magisk manually from magiskapp.com" } W "" W " ─── ONE MANUAL STEP REQUIRED ───────────────────────────────" Yellow W "" W " The file /sdcard/xerax_init_boot.img is now on your phone." White W "" W " ① Open Magisk on your phone" White W " ② Tap Install → Select and patch a file" White W " ③ Navigate to Internal Storage → xerax_init_boot.img" White W " ④ Tap LET'S GO — patching takes about 10 seconds" White W " ⑤ Come back here and press ENTER" White W "" Read-Host " Press ENTER after Magisk finishes patching" # Pull patched file back from device Downloads Info "Looking for patched file in device Downloads..." $dlFiles = & $adbPath -s $deviceSerial shell "ls /sdcard/Download/magisk_patched_*.img 2>/dev/null" 2>&1 $dlStr = ($dlFiles -join "").Trim() if ($dlStr -and $dlStr -notmatch 'No such file') { $newest = ($dlStr -split '\s+' | Select-Object -Last 1).Trim() $dest = Join-Path $toolsDir "init_boot_patched.img" & $adbPath -s $deviceSerial pull $newest $dest 2>&1 | Out-Null if (Test-Path $dest) { $sz = [math]::Round((Get-Item $dest).Length / 1MB, 1) $initBootPatched = $dest Ok "Patched file pulled from device ($sz MB) ✓" } } if (-not $initBootPatched) { Warn "Could not auto-detect patched file." W "" W " Please manually copy the magisk_patched_*.img from your phone's Downloads" Yellow W " to this folder: $scriptDir" Yellow W " Rename it: init_boot_patched.img" Yellow W "" Read-Host " Press ENTER when init_boot_patched.img is in the folder" $manual = @( Join-Path $scriptDir "init_boot_patched.img", Join-Path $toolsDir "init_boot_patched.img" ) | Where-Object { Test-Path $_ } | Select-Object -First 1 if ($manual) { $initBootPatched = $manual } else { Err "init_boot_patched.img not found."; Pause } } } } else { # No extraction at all — check for manually placed patched file $manualPatched = @( Join-Path $scriptDir "init_boot_patched.img", Join-Path $toolsDir "init_boot_patched.img" ) | Where-Object { Test-Path $_ } | Select-Object -First 1 if ($manualPatched) { $initBootPatched = $manualPatched Ok "init_boot_patched.img found (manually placed) ✓" } else { Err "Could not obtain init_boot.img — no patched file available." W "" W " Refer to xeraxapp.com/root for the manual patching guide." Gray Pause } } $initBootExists = $true } if (-not (Test-Path $initBootPatched)) { Err "Patched init_boot not found at: $initBootPatched"; Pause } $imgFile = $initBootPatched $sz = [math]::Round((Get-Item $imgFile).Length / 1MB, 1) Ok "init_boot_patched.img ready ($sz MB) ✓" # ============================================================================= # STEP 6 — OEM Unlock Check # ============================================================================= W "" W " STEP 6 of 6 — OEM Unlock Check" White Hr $oemVal = (& $adbPath -s $deviceSerial shell settings get global oem_unlock_enabled 2>&1).Trim() if ($oemVal -ne "1") { Warn "OEM Unlock does not appear to be enabled (value: '$oemVal')." W " Settings → Developer Options → OEM Unlocking → ON" Yellow W " Note: Xiaomi/Redmi may require unlocking via account at unlock.update.miui.com" Gray $go = Read-Host " Continue anyway? (Y/N)" if ($go -notmatch '^[Yy]') { exit 1 } } else { Ok "OEM Unlock is enabled ✓" } # ============================================================================= # FINAL CONFIRMATION # ============================================================================= W "" Hr W " READY TO ROOT — EVERYTHING IS AUTOMATED FROM HERE" White Hr W "" W (" Device : {0} {1}" -f $brand, $model) White W (" Android : {0}" -f $android) White W (" Patch : {0} (compatible)" -f $patch) White W (" EFI : {0}" -f (Split-Path -Leaf $efiFile)) White W (" Image : {0} ({1} MB)" -f (Split-Path -Leaf $imgFile), $sz) White W "" W " ① Phone reboots to Fastboot (~10 sec)" Gray W " ② EFI loads — GBL bypass (~20 sec)" Gray W " ③ init_boot flashed (~30 sec)" Gray W " ④ Phone reboots to Android (~90 sec)" Gray W " ⑤ Root active — BL stays LOCKED" Gray W "" Warn "CRITICAL: Do NOT unplug USB during this process" Warn "CRITICAL: Decline all OTA updates after rooting" W "" $confirm = Read-Host " Type YES to begin" if ($confirm -ne "YES") { Warn "Cancelled."; exit 0 } # ============================================================================= # PHASE 1 — Reboot to Fastboot # ============================================================================= W "" W " PHASE 1 — REBOOTING TO FASTBOOT" White Hr Info "Sending reboot-to-bootloader command..." & $adbPath -s $deviceSerial reboot bootloader 2>&1 | Out-Null Info "Waiting for Fastboot mode (up to 40 sec)..." $fbSerial = $null for ($i = 0; $i -lt 40; $i += 3) { Start-Sleep -Seconds 3 foreach ($line in (& $fbPath devices 2>&1)) { if ($line -match '^(\S+)\s+fastboot') { $fbSerial = $Matches[1]; break } } if ($fbSerial) { break } $raw = (& $fbPath devices 2>&1 | Where-Object { $_ -notmatch '^\s*$' -and $_ -notmatch '^List of' }) -join "" if ($raw.Length -gt 3) { $fbSerial = "auto"; break } Write-Host " ." -NoNewline -ForegroundColor DarkGray } W "" if (-not $fbSerial) { Err "Device did not enter Fastboot mode." W " Check phone screen for 'FASTBOOT MODE'. Try: Power + Vol Down 10 sec." Gray Pause } Ok "Fastboot mode ✓ (serial: $fbSerial)" $fbArgs = if ($fbSerial -ne "auto") { @('-s', $fbSerial) } else { @() } # ============================================================================= # PHASE 2 — Load patched EFI (GBL bypass) # ============================================================================= W "" W " PHASE 2 — QUALCOMM GBL BYPASS" White Hr Info "Loading $(Split-Path -Leaf $efiFile) via fastboot boot..." $efiOut = & $fbPath @fbArgs boot "$efiFile" 2>&1 $efiStr = $efiOut -join "`n" if ($efiStr -match '(?i)Failed to patch ABL GBL') { Err "Device is NOT vulnerable — 'Failed to patch ABL GBL'" W " Your device or firmware variant cannot be patched by this exploit." Yellow W " See xeraxapp.com/root for alternative methods." Gray & $fbPath @fbArgs reboot 2>&1 | Out-Null; Pause } $efiFailed = (($LASTEXITCODE -ne 0) -and ($efiStr -notmatch '(?i)okay|finished|booting')) ` -or ($efiStr -match '(?i)\bFAILED\b') if ($efiFailed) { Err "EFI boot failed. Output: $efiStr" W " Try a device-specific EFI from github.com/superturtlee/gbl_root_canoe/releases" Gray & $fbPath @fbArgs reboot 2>&1 | Out-Null; Pause } Ok "GBL bypass active ✓" Info "Waiting for superfastboot environment (up to 25 sec)..." $sfbSerial = $null for ($i = 0; $i -lt 25; $i += 2) { Start-Sleep -Seconds 2 foreach ($line in (& $fbPath devices 2>&1)) { if ($line -match '^(\S+)\s+fastboot') { $sfbSerial = $Matches[1]; break } } if ($sfbSerial) { break } Write-Host " ." -NoNewline -ForegroundColor DarkGray } W "" if ($sfbSerial) { $fbArgs = @('-s', $sfbSerial) Ok "Superfastboot ready ✓ (serial: $sfbSerial)" } else { $fbArgs = @() Warn "Serial not re-detected — flashing anyway..." } # ============================================================================= # PHASE 3 — Flash init_boot # ============================================================================= W "" W " PHASE 3 — FLASHING PATCHED INIT_BOOT" White Hr Info "Flashing to active slot..." $flashOut = & $fbPath @fbArgs flash init_boot "$imgFile" 2>&1 $flashStr = $flashOut -join "`n" $flashFailed = (($LASTEXITCODE -ne 0) -and ($flashStr -notmatch '(?i)okay|finished')) ` -or ($flashStr -match '(?i)\bFAILED\b') if ($flashFailed) { Err "Flash failed. Output: $flashStr" & $fbPath @fbArgs reboot 2>&1 | Out-Null; Pause } Ok "Flashed successfully ✓" W " $flashStr" DarkGray # ============================================================================= # PHASE 4 — Reboot and Verify # ============================================================================= W "" W " PHASE 4 — REBOOTING TO ANDROID" White Hr Info "Rebooting..." & $fbPath @fbArgs reboot 2>&1 | Out-Null W " First boot may take 2–3 minutes — this is normal." Gray W "" Info "Waiting for device to come back online (up to 3 min)..." $came_back = $false for ($i = 0; $i -lt 36; $i++) { Start-Sleep -Seconds 5 if ((& $adbPath devices 2>&1) | Where-Object { $_ -match "$deviceSerial\s+device" }) { $came_back = $true; break } Write-Host " ." -NoNewline -ForegroundColor DarkGray } W "" if ($came_back) { Ok "Device online ✓" Start-Sleep -Seconds 5 Info "Verifying root..." $magiskVer = (& $adbPath -s $deviceSerial shell "magisk --version 2>/dev/null" 2>&1 -join "").Trim() $suCheck = (& $adbPath -s $deviceSerial shell "su -c 'echo ROOT_OK' 2>/dev/null" 2>&1 -join "").Trim() if ($magiskVer -match '^\d+') { Ok "ROOT CONFIRMED — Magisk $magiskVer ✓" } elseif ($suCheck -match 'ROOT_OK') { Ok "ROOT CONFIRMED via su ✓" } else { Warn "Auto-check inconclusive — open Magisk on your phone to confirm." W " A second reboot is sometimes needed to initialize root manager." Gray } } else { Warn "Device not seen on ADB in 3 min — check your phone screen." W " Normal home screen = root likely succeeded. Open Magisk to confirm." Gray } # ============================================================================= # SUCCESS # ============================================================================= W "" W " ╔════════════════════════════════════════════════════╗" Green W " ║ XERAX ROOT COMPLETE ║" Green W " ╠════════════════════════════════════════════════════╣" Green W (" ║ Device : {0,-40}║" -f "$brand $model") Green W " ║ Method : GBL/EFISP exploit (Qualcomm bypass) ║" Green W " ║ BL Lock : LOCKED — STRONG integrity preserved ║" Green W " ╚════════════════════════════════════════════════════╝" Green W "" W " ─── Next Steps ────────────────────────────────────────" White W "" W " 1. Open Magisk → confirm Installed version" Gray W " 2. Play Integrity API Checker app → STRONG should pass" Gray W " 3. BLOCK OTA UPDATES NOW:" Yellow W " adb shell settings put global auto_update_time -1" Cyan W " adb shell settings put global ota_disable_automatic_update 1" Cyan W " Install 'OTA Survival Script' in Magisk modules" Gray W "" W " 4. Full remote device control: xeraxapp.com" Gray W "" W " ─── Credits ────────────────────────────────────────────" DarkGray W " Exploit: superturtlee (github.com/superturtlee/gbl_root_canoe)" DarkGray W " Tool: XeraX Team (xeraxapp.com/root)" DarkGray W "" Hr Read-Host "`n Press ENTER to close"