All the classic Frida checks in 2025 — maps, thread names, CRC, ports — are dead.
Today I’m dropping the one that still kills 99 % of setups: Dirty-Page Detection.
Key point: As long as frida-server is running on the device — even if it never attaches to your app — you can detect it globally.
Why Dirty-Page Detection Is Almost Unbypassable
To listen for zygote forks and signals, frida-server inline-hooks three critical modules inside system_server:
- libc.so
- libselinux.so
- libandroid_runtime.so
Inline-hooking the read-only .text section triggers Copy-On-Write.
The original file-backed pages become private dirty pages.
Even if Frida later restores the original bytes in the on_leave callback, the pages stay private forever.
That’s the permanent fingerprint we hunt.
Method 1 – smaps file detection
Sample code is used to demonstrate the thought process.
import re
def frida_detected_smaps():
targets = ['libc.so', 'libselinux.so', 'libandroid_runtime.so']
with open('/proc/self/smaps', 'r') as f:
smaps = f.read()
for lib in targets:
# Find the library mapping
pos = smaps.find(lib)
if pos == -1:
continue
segment = smaps[pos:pos+800]
# Private_Dirty > 0 → COW happened → Frida was here
if 'Private_Dirty:' in segment:
dirty = re.search(r'Private_Dirty:\s+(\d+)', segment)
if dirty and int(dirty.group(1)) > 0:
return True
return False
Method 2 – pagemap (nuclear option, bit 61)
Linux pagemap entry (64 bit):bit 63 → page present
bit 61 → soft-dirty (set on COW)
import struct, ctypes
def page_is_dirty(vaddr):
with open('/proc/self/pagemap', 'rb') as f:
f.seek((vaddr // 4096) * 8)
entry = struct.unpack('Q', f.read(8))[0]
present = (entry >> 63) & 1
soft_dirty = (entry >> 61) & 1 # ← this is the killer bit
return present == 1 and soft_dirty == 1
# Example: check fork()
libc = ctypes.CDLL('libc.so')
fork_addr = ctypes.cast(libc.fork, ctypes.c_void_p).value
print(page_is_dirty(fork_addr)) # True → Frida present
# you can add more function for detection, such as : vfork/opendir/abort/closedir/close/signal/sigaction/exit
Bottom LineIn
2025, if you’re still checking /proc/self/maps or thread names, you’re fighting 2022 battles.
Dirty-page detection is the current meta.
I’m H.
Six years deep in Android reversing.
The real game has just started.
— H
Top comments (0)