
GhostLock (CVE-2026-43499) Galaxy S26 시리즈용 앱
indev.ghostlock.s26)polygraphene/ghostlock-s26용 원클릭 Android 래퍼: GhostLock(CVE-2026-43499)을 삼성 Galaxy S26 시리즈 전체 (Android 16 / GKI 6.12)에 포팅했습니다. APK 하나, 세 개의 커널 라인, 런타임 매개변수 매칭 - 빌드별 앱 변형은 없습니다.
소유한 기기 또는 명시적으로 테스트 권한을 받은 기기에서만 사용하세요. 임시 루트는 재부팅 시 사라집니다. 같은 부팅 세션에서 익스플로잇을 두 번째로 실행하면 기기가 크래시될 수 있습니다 - 재시도 전에 재부팅하세요.
면책 조항: 이 소프트웨어를 실험하는 것은 저수준 커널 익스플로잇, 루트, 부팅 시점 클레임을 수반합니다. 이 소프트웨어는 어떠한 종류의 보증도 없이 있는 그대로(AS IS) 제공됩니다. 전적으로 사용자 본인의 책임하에 사용하세요. 작성자는 벽돌이 되거나 부팅 루프에 빠지거나 그 밖의 방식으로 손상된 기기, 또는 데이터 손실, 보증 무효화, 사용으로 인해 발생하는 모든 손해에 대해 책임지지 않습니다.
익스플로잇은 개별 빌드가 아닌 커널 라인으로 매칭합니다
(exploit/src/params_table.c가 기준이며, ParamsTable.kt는 UI 판정용으로만
이를 미러링합니다):
| 기기 코드명 | 마케팅명 | SoC | 커널 라인 |
|---|---|---|---|
| m1q | Galaxy S26 (SM-S942x) | Snapdragon | cn 또는 intl (CSC 기준) |
| m2q | Galaxy S26+ (SM-S947x) | Snapdragon | cn 또는 intl (CSC 기준) |
| m3q | Galaxy S26 Ultra (SM-S948x) | Snapdragon | cn 또는 intl (CSC 기준) |
| m1s | Galaxy S26 (SM-S942B) | Exynos | exynos |
| m2s | Galaxy S26+ (SM-S947B) | Exynos | exynos |
테스트된 빌드 (17): S9420ZCS4AZG1, S9470ZCS4AZG1, S9480ZCS3AZF1, S9480ZCS4AZG1, S942BXXS4AZG5, S947BXXS3AZF1, S947BXXS4AZG5, S942QOPU1AZDE, S942U1UES4AZG3, S942USQS4AZG3, S947USQS4AZG3, S9480ZHS4AZG1, S948BXXS4AZG5/6, S948NKSS4AZG3, S948U1UES2AZE1, S948USQS4AZG3.
알 수 없는 OTA는 업스트림 params.c와 정확히 동일하게 폴백합니다: 정확한 빌드 우선,
그다음 동일 모델 + 3자리 CSC(OTA 재사용), 그다음 동일 기기의 최신 항목
(미검증으로 표시), 그 외에는 fail-closed(앱은 UNSUPPORTED를 표시하고
네이티브 레이어는 종료 코드 2로 종료). 완전히 알 수 없는 모델은 거부됩니다 - 절대 강제하지 않습니다.
큰 버튼 하나 - Root my S26 - 가 전체 파이프라인을 실행하고 Output 카드에 진행 상황을 설명합니다:
adb shell 흐름과
같은 컨텍스트 계열). 권한은 실행 시 한 번 요청되며(서버가 재시작되면 다시 요청),
Root 흐름은 포기하지 않고 부여를 기다립니다. 서버가 내려가 있으면 앱이
Shizuku 관리자를 열어 시작할 수 있게 한 뒤, 인앱 shell로 폴백합니다.
앱을 Shizuku의 허용 목록에 추가하면 프롬프트가 완전히 사라집니다.preload.so, su_daemon, ksud를 /data/local/tmp로 복사하고
(preload.so, cve-2026-43499-root, ksud) chmod합니다. 업스트림 README대로
이미 adb push한 파일이 있다면 그 자리에서 그대로 사용됩니다.env LD_PRELOAD=/data/local/tmp/preload.so sh (.so 생성자가 체인을 실행하고
_exit함; stdout이 곧 익스플로잇 로그), 최대 5회 시도 -
레이스는 확률적입니다. BOOT_FORCE=1 스위치도 있지만
재부팅이 더 안전합니다.id가 uid=0을 보고하는지 확인합니다:
먼저 임시 데몬 소켓, 그다음 KernelSU 방식의 su. 이는 완전히 성공한 경우 su_daemon이
설계상 소켓을 unlink하고 종료하기 때문에( KernelSU로 핸드오버) 중요합니다 -
임시 소켓은 죽었지만 su가 동작한다면 루팅된 것이지 고장 난 것이 아닙니다.
부팅 클레임 로그 꼬리를 출력하고 루팅됨 /
종료 코드 관련 조언을 보고합니다.그 아래에는 단일 명령 필드 + root로 실행 행(su 데몬의 C 프로토콜을 통한 원샷 명령, 대화형 PTY는 v1 범위 밖)과, /data/local/tmp/ghostlock-boot.log를 지워 재부팅 없이 실행을 재시도할 수 있게 하는 작은 재설정 링크가 있습니다(업스트림에서는 이로 인해 패닉이 발생할 수 있다고 경고하며, 재부팅이 안전한 경로입니다).
exploit/ vendored upstream (Makefile + src/, authoritative)
ksud upstream prebuilt KernelSU loader (ARM64 PIE, also in assets)
app/src/main/assets/ksud staged copy shipped in the APK
app/src/main/assets/ + preload.so / su_daemon after stage-assets.sh
app/src/main/cpp/ optional CMake rebuild of preload.so from exploit/src
app/src/main/java/indev/ghostlock/s26/
MainActivity.kt UI (device / stage / run / shell / boot guard)
ParamsTable.kt series table mirror (17 builds, 3 lines, 5 codenames)
DeviceCompat.kt Build.* identity + series verdict
ShellRunner.kt Shizuku (uid 2000) + local fallback, staging
SuClient.kt /data/local/tmp/temp_su.sock 'C'-mode client
GhostlockManager.kt exit-code interpreter (0/1/2/3/4)
PORTING.upstream.md porting notes (new firmware = new device_map row)
요구 사항: Android Studio (JBR 21) / SDK 35 / NDK r26+ / CMake 3.22.1 / JDK 17.
# 1. Build the native payloads with the NDK (upstream flow):
cd exploit && make preload
# -> build/bin/preload.so, build/embed/su_daemon_aarch64_pie
# 2. Stage them into the APK assets:
./stage-assets.sh
# 3. Build the app:
./gradlew :app:assembleDebug
# -> app/build/outputs/apk/debug/app-debug.apk
ksud는 이미 벤더링되어 있으므로(ksud + app/src/main/assets/ksud) 1–2단계에서는 두 개의 NDK 출력물만 생성됩니다. app/src/main/cpp/CMakeLists.txt의 CMake 타깃은 폴백으로서 APK 내부의 동일한 소스에서 libpreload.so를 추가로 재빌드할 수 있습니다.
.github/workflows/build.yml 워크플로는 대상 기기 코드네임 / 프로세서 유형에 맞춰 앱을 빌드합니다 - 로컬에 SDK, NDK, Docker가 필요하지 않습니다. 저장소를 포크한 뒤 저장소의 Actions 탭 → GhostLock-S26 Device Build → Run workflow로 이동하여 다음을 설정하세요:
| 입력 | 선택지 | 기본값 | 효과 |
|---|---|---|---|
device | all / m1q / m2q / m3q / m1s / m2s | all | 기기 코드네임 (빌드 대상) |
processor | all / snapdragon / exynos | all | SoC 계열 (커널 라인 필터링) |
kernel_line | auto / cn / intl / exynos | auto | 정확한 params 라인 고정 (auto는 device/processor에서 도출) |
tailor | on / off | off | 더 작은 단일 대상 페이로드를 위해 params_table.c + ParamsTable.kt를 선택한 기기/라인으로 정리 |
build_type | debug / release | debug | APK 변형 |
rebuild_ksud | on / off | on | ksud_ref의 polygraphene/KernelSU에서 ksud + kernelsu.ko를 재빌드하거나, 벤더링된 사전 빌드를 유지 |
kmi | android16-6.12 / android15-6.6 | android16-6.12 | 모듈이 컴파일되는 KMI (S26 = GKI 6.12) |
samsung_hardening | on / off | on | CONFIG_KSU_SAMSUNG_KDP/RKP/DEFEX=y (Samsung kdp creds, RKP/DEFEX sync) |
no_patch_text | on / off | off | 라이브 텍스트 패칭 비활성화 (Samsung Exynos EL2 대상) |
추가로 KernelSU 소스 ref / DDK 이미지 / 번들 Manager APK를 고정하기 위한 ksud_ref, ddk_release, ksu_manager_apk, 그리고 KEYSTORE_BASE64 / KEY_ALIAS / 시크릿으로 서명하기 위한 sign_release가 있습니다.
예를 들어, Snapdragon 전용 Galaxy S26 Ultra 빌드(커널 라인 cn + intl, 다른 기기는 정리하여 제외)는 device=m3q, processor=snapdragon, tailor=on이 됩니다.
파이프라인은 NDK clang으로 네이티브 페이로드(preload.so + su_daemon)를 크로스 컴파일하고, 에셋을 스테이징하며, Gradle로 APK를 조립합니다. 아티팩트(ghostlock-s26-<devices>-<lines>-<tailored|full>-debug.apk와 preload.so, su_daemon, ksud 아티팩트 및 체크섬)는 실행의 Summary 페이지에 업로드됩니다. GitHub Actions가 체크아웃 + Gradle/SDK 설정을 처리하며 - 위 시크릿이 구성된 경우 Release 빌드는 자동으로 서명됩니다.
KernelSU Manager APK(me.weishu.kernelsu)는 앱 내 "Install KernelSU Manager" 흐름을 위해 app/src/main/assets/kernelsu-manager.apk에 번들됩니다. CI는 이를 자동으로 가져오며, 로컬 빌드의 경우 ./stage-assets.sh를 실행하기 전에 Manager APK를 exploit/build/bin/kernelsu-manager.apk에 놓으세요(없으면 경고가 표시됩니다 - 없으면 설치 프롬프트가 나타날 수 없습니다).
SDK의 aapt2/NDK는 x86_64이므로 온디바이스에서 실행할 수 없습니다. 검증된 절차(SDK는 ~/android-sdk, Gradle 8.9 - AGP 8.5.2는 시스템 Gradle 9.x를 거부함):
# Native payloads with the Termux toolchain (API 35 target, system liblog):
cd exploit
clang -O2 --target=aarch64-linux-android35 -fPIE -pie -Isrc src/su_daemon.c \
-o build/embed/su_daemon_aarch64_pie
clang -O2 --target=aarch64-linux-android35 -fPIC -Isrc \
-Wno-unused-parameter -Wno-sign-compare -Wno-unused-function -Wno-macro-redefined \
src/main.c src/util.c src/bootclaim.c src/slide.c src/fops.c src/attr.c \
src/root.c src/params.c src/params_table.c src/preload.c \
-L/system/lib64 -llog -shared -o build/bin/preload.so
cd .. && ./stage-assets.sh
# APK (CMake native step auto-skips without SDK cmake; Termux aarch64 aapt2
# is injected via -P so checked-in files stay workstation-clean):
env ANDROID_HOME=~/android-sdk ANDROID_SDK_ROOT=~/android-sdk \
JAVA_HOME=$PREFIX/lib/jvm/java-21-openjdk \
~/gradle-dists/gradle-8.9/bin/gradle :app:assembleDebug --console=plain \
-Pandroid.aapt2FromMavenOverride=$(command -v aapt2)