Repository navigation
Based on upstream DFRoot 4.5 (upstream 4.2 - 4.5 merged into this fork).
Engine - vendor hardening is patched in place instead of removed (issue #21)
- The kernel module no longer runs
rmmod oplus_secure_harden,oplus_security_keventuploadand
oplus_security_guard. Removing them on an Oppo/OnePlus kernel tripped the vendor security anti-tamper path
and black-screened the device on every run - reported on a OnePlus Ace6 (ColorOS 16.0.7.101). patch_fn_ret_zero()writesmov w0, #0; retover the offending handlers instead, so the modules stay loaded
and their checks simply return allowed: the twooplus_*handlers, and Samsung'stask_defex_enforceand
task_defex_user_exec, which in 1.15 were kprobes rewritingx0on every hit. It skips a
BTI/PACIASP/PACIBSPpreamble and emitsretaa/retabonly where the SoC has pointer authentication.call_usermodehelper_execis called withUMH_WAIT_EXECinstead ofUMH_WAIT_PROC, so the module no longer
waits for the helper to exit. That wait is the other half of the MTK reboot, and the status it reported is
thereturned 256a Samsung saw in 1.15 (issue #5) - which also retires theexit 0workaround, since there
is no longer a failing command at the end of the chain to mask.- Housekeeping: the module fails its own init with
-ENODEVto get itself unloaded, and bootstrap runs
rmmod dfrootonce late-load has finished and before a soft-reboot, rather than only at the very end where a
reboot skipped it. - The
.kokeep their.note.gnu.build-id, which upstream had stopped stripping - that is what kept a Galaxy
A34 (SM-A346M, kernel 6.6.92) from loading the module at all.
Engine - the payload gets a place to live on more devices
- The shellcode no longer has to fit in the slack after the end of the executable
PT_LOADsegment. The loader
scans that segment for a run of zero bytes - the alignment padding between functions - big enough to hold it,
prints the offset it chose, and reports the largest run it found when there is none, so a log says something
useful instead of a bare[-] Failed to find a suitable code cave. - Hook-site preambles are recognised properly now:
PACIASP,PACIBSP,BTI,BTI c,BTI jandBTI jc,
up to two words deep, where before onlyPACIASPand one form ofBTIwere handled once.
App
- An Odin pill sits left of the menu button, in the same 44dp capsule as that button, and its dot says
whether this firmware will let the device into Odin - Galaxy firmwares from around April 2026 answer download
mode with a D2 error while a lock-screen credential is set. Green means not gated, red means it is, grey means
this device does not gate download mode at all. Tapping it opens the three facts behind the dot - Lockscreen,
Maintenance Mode, Device - so a dot you disagree with is arguable without a cable. It reads the two public
inputsDmcServicebuilds its decision from, not the TEE vault behind them, because DirtyFrag is the tool
that gets you root and so has to work on a device that has none.
- The version number is out of the header and the update has taken its place: when a newer release is
published, a lime capsule wipes in over the word DirtyFrag and reads Update, one tap from the release
page. The digits it replaces were 10.8sp next to a 24sp word, and reserved their width whether or not an
update was flagged, which with the wider Odin pill beside them left the title ellipsized. The version is only
relocated:version <x>to logcat on every start,app version: <x>in the run log.
- The interface keeps its own scale. Every measurement in it belongs to one screen width in dp, so a single One
UI screen-zoom step clips the title and the default font size breaks it outright;ScaleFixnow derives a
density from the real pixel width so the app always lays out at 384dp - a Galaxy S25 at 450dpi - and pins
fontScaleto 1.0. Verified on an SM-S931B at every screen zoom and font size step. The price is that Screen
zoom and Font size no longer apply inside the app, and wide screens - a foldable opened flat, a tablet - are
the known gap, because the correction is capped at 30%. - No more toasts. Flipping the KSU modules switch, resetting the layout, tapping a manager that cannot be
launched: the switch already says what it did in its own subtitle, the reset is visible in the stack, and
neither launcher can strand anyone when there is nothing to launch. run()issynchronizedand returns early when/dev/dfalready exists, so the boot autorun racing a
manual tap no longer re-hooks over the first run and corrupts it.
Managers
- zandatsu07's KernelSU-Next is no longer listed as a Samsung manager, following upstream: it only worked on
S23 and below with kernel 5.15. diabl0w's KernelSU stays the Samsung manager, and the non-Samsung list is
unchanged.
Fixed - unsafe getprop fallback
Upstream's fallback for kernels that leave the Android version out of uname -r never checked the popen()
result and rebuilt the version string with sprintf into a 15 byte stack buffer from a 5 byte read, so a long
or non-numeric property overflowed it. The property is now read into a zero-initialised buffer and only a
leading integer is accepted. The same hardening shipped in
k10halifa/Dslice.
Built
- The eight embedded kernel modules are rebuilt by CI from this source, so the APK carries exactly this engine.
- The bundled Inter variable font is subset down to the glyphs the app can render: 332,804 bytes out of the
APK - 2.26 MB down to 1.93 MB, about a seventh of the download. It is the same font: Inter carries no
hinting tables at all, so a subset cannot change how a surviving glyph rasterises, and that was checked
rather than assumed - both fonts instantiated at the two weights the app declares, every contour coordinate
and advance width compared over all 86 characters the app can put on screen, at zero differences. Anything
outside the subset falls back per character, the way emoji already did. android:debuggable="true"is gone from the manifest, where upstream has carried it since its first commit.
A debuggable APK can berun-asand ptraced by anything that has adb - readable preferences and an
injectable process sitting next to an exploit. Nothing in the app needs it, so no behaviour changes.