Root without unlocking. Gone after reboot.
An ephemeral Android root utility powered by CVE-2026-43284.
Built for Samsung devices, with a One UI-inspired interface, KernelSU integration,
and no custom kernel or unlocked bootloader required on vulnerable devices.
Important
Compatibility depends on the device's kernel and security patches. Root is ephemeral. The kernel module, su and any loaded modules are gone the moment the
device reboots. A reboot always returns the phone to a clean, unrooted state - which is also the
recovery path if a run goes wrong.
- Install the DirtyFrag APK from Releases.
- Install an SU manager that ships
libksud.so:- Samsung - required:
- Other:
- KernelSU
- KernelSU-Next
- KowSU
- BakaSU (formerly ReSukiSU)
- Open DirtyFrag, pick your manager in the SU Manager card, then press Run exploit.
Warning
Since 1.10 (upstream 3.2) DirtyFrag no longer bundles ksud - it is staged from the selected
manager's own libksud.so. A manager that does not ship that library cannot give you root. The
older advice to install a CI / Actions build of the manager no longer applies.
Note
Pre-release builds of master are not published to Releases. Take the DFRoot artifact of the
latest green Build run: it is a
signed release build - the workflow restores the KEYSTORE secret into app/keystore.jks and runs
assembleRelease - and inside the artifact the APK is at
app/build/outputs/apk/release/dirtyfrag.apk. Tagged and untagged builds go through that same
keystore step, so a master build carries the released app's signing key and installs over it as an
update rather than a fresh install.
A fresh install of DirtyFrag gets a new Android UID, so the grant in the manager has to be given again after every reinstall.
- Choose your SU manager inside the app
- Autorun (start on boot), gated behind Expert mode, with a failed-run interlock that disables itself after a failed attempt so a bad run cannot boot-loop you
- Auto reboot (soft reboot) - since 1.11 (upstream 4.1) this works with every KernelSU
derivative:
dfroot.kois unloaded after late-load and ksud's ownsoft-rebootis run - KernelSU Modules on/off - works without root, applied by the kernel module before ksud starts
- RO Partition Protection
- Advanced log, with one tap to save it to Downloads
- Odin pill in the toolbar: its dot says whether the device will answer a download-mode request on this boot, and tapping it opens the three facts that decision is made from
- Odin access you can write - since 1.17, behind Expert mode and needing root: the Recovery Writer switch on that same pill authorises or clears download mode for the current boot by changing one authorisation byte in Samsung's vault, then reading it back to confirm the write actually took. The vendor clears that byte on its own schedule and a reboot drops DirtyFrag's root with it, so Autorun Writer asks for the same write again at every reroot
- When a newer release is published, the headline itself becomes a lime Update pill - one tap from the release
- Shizuku not needed
Q: Log says patching failed and that my device isn't vulnerable
A: Sorry, there is no fix. Either:
- your device's kernel is too new
- your device manufacturer backported the official mitigation
- accidental mitigation (typically seen on kernel 6.1)
Q: Log says "SUCCESS" or "ksud exited with error", but I don't have root
A: Turn off Auto reboot on the Autorun card if it is enabled - a soft reboot that the manager cannot complete leaves the loaded module unloaded again. Otherwise see upstream discussion 69.
Q: I installed a module and now I can't launch root without crashing
A: Set the KernelSU Modules card to Disabled and reroot. The switch works without root, which is the point - it is the escape hatch when a module is the thing that is crashing the run.
Q: Module + Autorun and now I am bootlooping
A: Android usually detects the bootloop and offers Safe Mode; otherwise hold Volume Down during
boot. From Safe Mode turn Autorun off and set KernelSU Modules to Disabled, or just uninstall
DirtyFrag until you stabilise. If you cannot get far enough into the system, adb uninstall df.root
from any PC works on user builds without root.
Q: The progress bar sits at 0 percent
A: That is the app's log-marker mapping, not the exploit. The run window is 70 seconds - do not re-run a "slow" run, the daemon may still be working.
Q: How do I remove root cleanly?
A: Before unrooting, use file manager with root and delete /data/adb/ksu, ksud, module residue.
JAVA_HOME="<Android Studio jbr>" ./gradlew assembleReleaseThe APK is written to app/build/outputs/apk/release/dirtyfrag.apk.
Release builds are signed with app/keystore.jks, which is gitignored (the signing config expects
alias dirtyfrag and dirtyfrag for both passwords). Generate your own before building:
keytool -genkeypair -v -keystore app/keystore.jks -alias dirtyfrag \
-keyalg RSA -keysize 2048 -validity 10000 \
-storepass dirtyfrag -keypass dirtyfragThe eight prebuilt kernel modules are committed under app/src/main/jni/ko/. Upstream gitignores
them and builds them per-KMI in CI; this fork commits them so a plain clone builds without a DDK
toolchain. They are built by this repo's Build workflow (the LKMs / <kmi> jobs) from the
current lkm/dfroot.c, so they must be rebuilt whenever that file changes: run the workflow,
download the df-lkm-<kmi> artifacts and drop them in this directory. To build them yourself
instead, use upstream's make / podman DDK flow.
The Android kernel decrypts AES-CBC ESP packets directly into the page cache of files open for
splice(). By crafting IV = AES_ECB_DEC(key, current_content) XOR desired_content, any
16-byte-aligned block in a mapped shared library can be overwritten without write permission and
without copy-on-write.
The exploit uses this primitive to patch shellcode into libc++.so in the kernel's page cache. The
next privileged call to the hooked function runs the shellcode, which loads the kernel module via
insmod.
- IpSec transform - the app allocates a
UdpEncapsulationSocketplus an SPI and builds an AES-CBC/HMAC-SHA256 ESP transform throughIpSecManager. - splicehelper -> crash_dump64 - splicehelper is spliced into
crash_dump64using the CBC primitive.crash_dump64runs in thecrash_dumpSELinux domain, which can openvendor_filelabelled files thatuntrusted_appcannot read - the bridge we need. - dfroot.ko -> vendor_file - the kernel module is written through that bridge into a
vendor_file-labelled file. - libc++ hook (fires in init, uid=0, tid=1) - shellcode patched at
std::ostream::sentry::sentry(). It checks uid and tid, creates/dev/dfas a one-shot mutex so it cannot re-enter, then execsinsmodin thevendor_modprobedomain. - dfroot.ko init - sets SELinux permissive, bypasses DEFEX via kprobes where present, then uses
call_usermodehelperto run the bootstrap. - bootstrap - reads the app's device-protected settings, adopts the zygote environment, sets partitions read-only, optionally disables all modules, and finally launches the SU daemon from your installed SU manager.
- Upstream project and exploit chain: https://github.com/diabl0w/DFRoot
- Original PoC and various code: https://github.com/lsposed/lspromise
- SELinux permissive kernel modules and various code: https://github.com/polygraphene/DFReroot
- Unprivileged XFRM socket method: https://github.com/combeng6th/DirtyInit
GPL-2.0-only - the full text is in LICENSE, the file upstream added in 4ec133c because
the upstream maintainer asked for one. Upstream keeps its own copyright on its code; everything this
fork adds on top of it is licensed under the same GPL-2.0-only, from the 1.17 merge onward.
That single licence has one consequence worth stating before anyone ports code in: GPL-2.0-only cannot absorb GPL-3.0-only code. A GPL-3 reference - the Samsung download-mode (Odin) work, for example - may be read for behaviour, record formats and API naming, and none of its code may be copied, translated or linked into this tree. The same rule is written down in docs/d2-download-mode-writer.md.