GhostLock
1.2 · GitHub
More about this app
One-tap CVE-2026-43499 privilege-escalation app granting temporary uid 0 across many stock devices; Shizuku-required kernel profiles run through a shell Shizuku.
GhostLock-App
中文: README_ZH.md
Documentation
- Kernel Profile Porting Guide - add support for a new kernel. GhostLock matches kernels by exact
uname -rand rejects unsupported builds, showing the status at the top. Built-in profiles live inapp/src/main/assets/kernel_profiles/: one HOCON file per release,index.confas the runtime index, and<major.minor>-template.confversion-family templates. - Supported devices - the built-in kernel list.
- Shared execution defaults - every execution-tuning field, its default, and why.
- Profile schema - full profile structure and data flow.
- Adding a component - developer guide for a new native middleware / backend / frontend (Chinese).
For the complete device-porting workflow, kernel-family template links, and tuning rationale, see the Kernel Profile Porting Guide.
Rows explicitly marked Shizuku required run through a shell UserService. Start Shizuku with ADB and tap the status card to grant access; all other rows use the app's normal execution path.
Quick Start
Open GhostLock and tap Run. KernelSU (me.weishu.kernelsu), ReSukiSU (com.resukisu.resukisu), or KowSU (com.kowx712.supermanager) provides ksud for module loading; without it, W1/W2 still grant uid 0 but no module is loaded.
The execution chain is a pipeline of three components: a frontend (root_child startup/handoff), a backend (the CVE-2026-43499 futex primitive), and a middleware route. The catalogued combinations are instantiated at build time; the resolved profile selects which one runs. The route races two cores: on the 6.6/6.12 tree-waiter kernels the main thread hammers select while a consumer thread perturbs the waiter's priority; on the 6.1 compact-waiter kernels it drives getsockopt(TCP_ZEROCOPY_RECEIVE) through a punched-hole page; the 5.15 kernels use the multicast waiter. The CPU pair also comes from the resolved profile.
Command-Line Debugging
adb/shell has no seccomp filter, so W3 is skipped - handy for quick verification:
make -C src ghostlock
./gradlew exportKernelProfiles
adb push build/native/ghostlock /data/local/tmp/ghostlock
adb push build/kernel-profiles/<release>.bin /data/local/tmp/profile.bin
adb shell chmod 755 /data/local/tmp/ghostlock
adb shell /data/local/tmp/ghostlock --load-prebuilt-profile /data/local/tmp/profile.bin
Offset Extraction
tools/extract_rs derives offsets from a boot.img (plus optional xbl_config.img), a full OTA ZIP, or an http(s) URL pointing at one. kallsyms come from --kallsyms or are recovered from the image's embedded table. pselect_waiter_shift and off_slide_loggers_0_1 are derived by the built-in arm64 disassembler. MediaTek images have no xbl_config.img and usually no BTF: the physical load address is derived from kallsyms _text (override with --phys).
Push-Location tools/extract_rs
cargo build --release
Pop-Location
build/extract/release/ghostlock-extract.exe boot.img --xbl-config xbl_config.img --format conf --out profile.conf
build/extract/release/ghostlock-extract.exe OTA.zip --format conf --out profile.conf
--format conf is the extractor output: a flattened, self-contained profile (no include lines, the shared 6.x credential/KernelSnitch constants inlined, the route selected from --analysis evidence unless --route overrides it). The extractor emits every field the image actually yields and omits the rest; it never fills gaps from a neighbouring kernel family's guesses (unverified-family 6.6, the default -2, the 5.15 multicast constants, or a phys default). Every output is an unverified candidate: importable and parseable, with missing or invalid fields blocked by the app's pre-execution validation, so a successful run never implies device support. On 5.x it also derives the credential reference repair from init_cred and the multicast geometry from BTF (see docs/analysis/extractor-5x-derivation-plan.md). --format json stays for the v1 import path. To add a built-in profile, complete and validate the matching version-family template, save it as a standalone .conf profile, and add it to kernel_profiles/index.conf. The old C offsets.h registry is deprecated and removed.
MediaTek
MediaTek images have no xbl_config.img and usually no embedded BTF, so the
extractor cannot derive the two physical addresses (kernel_phys_load,
kernel_phys_offset) from the image and leaves them null. The runtime then
falls back to the SoC formula, which fails at W1 on MediaTek. Fill both by
running the separate tools/mtk-phys/ extractor on a rooted device (it reads
/proc/iomem) and pasting the values into the app's advanced overrides. See
MEDIATEK.md.
Preflight
The extractor disassembles remove_waiter() before extracting offsets. Kernels with the fix are rejected with exit code 6; only vulnerable kernels continue.
On-device analysis
A full OTA can be analyzed entirely on the phone: boot plus xbl_config
are extracted automatically. Pass --work-dir an app-writable dir when
running inside the app sandbox. Cross-compile and push:
rustup target add aarch64-linux-android
$ndk = "$env:ANDROID_HOME\ndk\<version>\toolchains\llvm\prebuilt\windows-x86_64\bin"
$env:CC_aarch64_linux_android = "$ndk\aarch64-linux-android35-clang.cmd"
$env:AR_aarch64_linux_android = "$ndk\llvm-ar.exe"
$env:CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER = $env:CC_aarch64_linux_android
Push-Location tools/extract_rs
cargo build --release --target aarch64-linux-android
Pop-Location
adb push build/extract/aarch64-linux-android/release/ghostlock-extract /data/local/tmp/
adb shell /data/local/tmp/ghostlock-extract /sdcard/OTA.zip
Importing offsets without rebuilding the app
New kernels no longer need an app rebuild: tap Import offsets.conf (HOCON)
and pick the extractor's flattened .conf, or use Import offsets.json (v1)
for an older JSON report. v1 JSON is converted in-app, so nothing has to be
pushed to the device: native always starts from the GLK1 document the app sends
on stdin, and matches the current uname -r against the resolved profile
before rejecting the kernel. Imports merge across files; a release already
stored prompts before overwrite.
The app can also generate the profile itself — Parse OTA link (full OTA ZIP
URL) and Parse image (boot.img + optional xbl_config.img) run the
extractor in-process and write a flattened .conf into the app data dir on
success:
# GhostLock kernel profile: 6.12.38-android16-5-g844001fb8721-ab14552068-4k (HOCON, self-contained).
release = "6.12.38-android16-5-g844001fb8721-ab14552068-4k"
schema_version = 1
kernel_major = 6
recommend_shizuku = 0
kernel_phys_load = 0xC7800000
route {
select_stack {
waiter_shift = 0
}
}
fallback {
to = "none"
}
kernelsnitch {
collisions = 4
}
task_struct {
prio = 148
cred = 2304
}
cred {
caps_offset = 48
copy_size = 136
usage_value = 1
caps_count = 5
caps_value = -1
}
offset {
init_task = 37801728
init_cred = 37891184
}
Credits & License
Based on the following projects, licensed under Apache License 2.0 (see LICENSE):
How Shizuku is used
Can run one-tap kernel exploit for temporary uid 0 via `Shizuku user service`.
This is an AI-assisted analysis of Shizuku-related usages in the app's public source code. It is best effort, so it may not catch every single usage.
How this app uses Shizuku
Shizuku is used to run the one-tap privilege escalation with shell identity so the exploit can succeed where the normal app identity cannot.
- Run privilege escalation: tapping Run with the Shizuku option starts the bundled native exploit inside the Shizuku service (shell identity, without seccomp filtering) using the selected CPU pair, safety mode choice, force attack test flag and the matched kernel profile for the running kernel, then shows its log and completion status in the app.
Android APIs or commands used
android.os.Process.myUidandroid.os.Process.SHELL_UID
Notable details
The same Run action also offers a base mode without Shizuku that runs the same exploit with the normal app identity. The Shizuku run requires a matching kernel profile for the running kernel, otherwise it stops with a profile unavailable message.
Changelog
What's new for version 1.2
注意:该版本不是稳定版ghostlock-app,而是dev分支的测试版。如需下载稳定版本,请前往另外一个pre-release下载
Attention: this is not a stable version of ghostlock-app, instead, it is the alpha testing version from dev branch. To download the stable version, please go to another pre-release.
此版本加入 vivo/iQOO 设备的 vr.ko 探针中和处理,修复临时获取 root 后 ksud 及其派生 shell 被终止的问题。同时改进了 5.15 multicast route、内核配置提取和 App 配置编辑功能。
需要使用vivo设备的志愿者参与测试。请开启高级选项中的日志导出;遇到问题时,请将日志和内核版本提交到 Issues。欢迎符合条件的设备用户反馈测试结果。
The dev branch has been merged into main.
This build adds a vr.ko probe mitigation for vivo/iQOO devices, addressing the termination of ksud and its child shells after temporary root access is obtained. It also improves the 5.15 multicast route, kernel profile extraction, and in-app profile editing.
We are looking for volunteers with vivo devices to test this build. Please enable debug log export in Advanced settings. If you encounter a problem, report it in Issues with the logs and kernel version. So feedback from users with eligible devices is welcome.
更新日志/Change logs :
v1.2.567 build date: 2026-10-2
initial release
Permissions
3 permissions requested
Sources
2 sources
Sources
2 sources