diff --git a/native/src/Android.mk b/native/src/Android.mk
index 165fc627a..4ab294341 100644
--- a/native/src/Android.mk
+++ b/native/src/Android.mk
@@ -37,8 +37,7 @@ LOCAL_SRC_FILES := \
     core/zygisk/module.cpp \
     core/zygisk/hook.cpp \
     core/deny/cli.cpp \
-    core/deny/utils.cpp \
-    core/deny/revert.cpp
+    core/deny/utils.cpp
 
 LOCAL_LDLIBS := -llog
 LOCAL_LDFLAGS := -Wl,--dynamic-list=src/exported_sym.txt
diff --git a/native/src/core/deny/revert.cpp b/native/src/core/deny/revert.cpp
deleted file mode 100644
index e6c56ebd2..000000000
--- a/native/src/core/deny/revert.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <set>
-#include <sys/mount.h>
-
-#include <consts.hpp>
-#include <base.hpp>
-#include <core.hpp>
-
-#include "deny.hpp"
-
-using namespace std;
-
-static void lazy_unmount(const char* mountpoint) {
-    if (umount2(mountpoint, MNT_DETACH) != -1)
-        LOGD("denylist: Unmounted (%s)\n", mountpoint);
-}
-
-void revert_unmount() {
-    set<string> targets;
-
-    // Unmount dummy skeletons and MAGISKTMP
-    // since mirror nodes are always mounted under skeleton, we don't have to specifically unmount
-    for (auto &info: parse_mount_info("self")) {
-        if (info.source == "magisk" || // magisktmp tmpfs
-            info.root.starts_with("/adb/modules")) { // bind mount from data partition
-            targets.insert(info.target);
-        }
-    }
-
-    if (targets.empty()) return;
-
-    auto last_target = *targets.cbegin() + '/';
-    for (auto iter = next(targets.cbegin()); iter != targets.cend();) {
-        if (iter->starts_with(last_target)) {
-            iter = targets.erase(iter);
-        } else {
-            last_target = *iter++ + '/';
-        }
-    }
-
-    for (auto &s : targets)
-        lazy_unmount(s.data());
-}
diff --git a/native/src/core/include/core.hpp b/native/src/core/include/core.hpp
index c68fd52c1..ee42eb80a 100644
--- a/native/src/core/include/core.hpp
+++ b/native/src/core/include/core.hpp
@@ -91,4 +91,3 @@ extern std::atomic<bool> denylist_enforced;
 int denylist_cli(int argc, char **argv);
 void initialize_denylist();
 bool is_deny_target(int uid, std::string_view process);
-void revert_unmount();
diff --git a/native/src/core/lib.rs b/native/src/core/lib.rs
index c6d1232c5..67a69ac7c 100644
--- a/native/src/core/lib.rs
+++ b/native/src/core/lib.rs
@@ -8,7 +8,7 @@ use daemon::{daemon_entry, find_apk_path, get_magiskd, MagiskD};
 use logging::{
     android_logging, magisk_logging, zygisk_close_logd, zygisk_get_logd, zygisk_logging,
 };
-use mount::{find_preinit_device, setup_mounts};
+use mount::{find_preinit_device, revert_unmount, setup_mounts};
 use resetprop::{persist_delete_prop, persist_get_prop, persist_get_props, persist_set_prop};
 
 mod cert;
@@ -90,6 +90,7 @@ pub mod ffi {
         fn read_certificate(fd: i32, version: i32) -> Vec<u8>;
         fn setup_mounts();
         fn find_preinit_device() -> String;
+        fn revert_unmount();
         unsafe fn persist_get_prop(name: Utf8CStrRef, prop_cb: Pin<&mut PropCb>);
         unsafe fn persist_get_props(prop_cb: Pin<&mut PropCb>);
         unsafe fn persist_delete_prop(name: Utf8CStrRef) -> bool;
diff --git a/native/src/core/mount.rs b/native/src/core/mount.rs
index 9d15ac7a6..36ecbb72c 100644
--- a/native/src/core/mount.rs
+++ b/native/src/core/mount.rs
@@ -1,4 +1,4 @@
-use std::path::Path;
+use std::path::{Path, PathBuf};
 use std::ptr;
 
 use num_traits::AsPrimitive;
@@ -274,3 +274,39 @@ pub fn find_preinit_device() -> String {
         .unwrap()
         .to_string()
 }
+
+pub fn revert_unmount() {
+    let mut targets = Vec::new();
+
+    // Unmount Magisk tmpfs and mounts from module files
+    for info in parse_mount_info("self") {
+        if info.source == "magisk" || info.root.starts_with("/adb/modules") {
+            targets.push(info.target);
+        }
+    }
+
+    if targets.is_empty() {
+        return;
+    }
+
+    let mut prev: Option<PathBuf> = None;
+    targets.sort();
+    targets.retain(|target| {
+        if let Some(prev) = &prev {
+            if Path::new(target).starts_with(prev) {
+                return false;
+            }
+        }
+        prev = Some(PathBuf::from(target.clone()));
+        true
+    });
+
+    for mut target in targets {
+        let target = Utf8CStr::from_string(&mut target);
+        unsafe {
+            if libc::umount2(target.as_ptr(), libc::MNT_DETACH) == 0 {
+                debug!("denylist: Unmounted ({})", target);
+            }
+        }
+    }
+}