<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jack Sparrow</title>
    <description>The latest articles on Forem by Jack Sparrow (@jack_sparrow_2386c07e8b94).</description>
    <link>https://forem.com/jack_sparrow_2386c07e8b94</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3603086%2F3f3dbe26-6719-4fa7-857e-6233515cb9e7.jpg</url>
      <title>Forem: Jack Sparrow</title>
      <link>https://forem.com/jack_sparrow_2386c07e8b94</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jack_sparrow_2386c07e8b94"/>
    <language>en</language>
    <item>
      <title>Stealth Inline Hook Detection via LR Return Address</title>
      <dc:creator>Jack Sparrow</dc:creator>
      <pubDate>Sat, 13 Dec 2025 03:15:49 +0000</pubDate>
      <link>https://forem.com/jack_sparrow_2386c07e8b94/stealth-inline-hook-detection-via-lr-return-address-52c5</link>
      <guid>https://forem.com/jack_sparrow_2386c07e8b94/stealth-inline-hook-detection-via-lr-return-address-52c5</guid>
      <description>&lt;h2&gt;
  
  
  1. Background: Why Traditional Inline Hook Detection Fails
&lt;/h2&gt;

&lt;p&gt;Inline hook detection on Android commonly relies on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CRC or code hash verification&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Comparing function prologue bytes&lt;/strong&gt; (e.g., detecting LDR/BR trampolines)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, these methods have major weaknesses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;They &lt;strong&gt;read code pages&lt;/strong&gt;, which makes them easily traceable with memory breakpoints.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attackers can hook the detection function itself.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Their “signatures” are well known and easy to bypass.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thus they are &lt;strong&gt;visible&lt;/strong&gt; and &lt;strong&gt;high-risk&lt;/strong&gt; in real offensive–defensive scenarios.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Core Idea: Detecting Hooks via the LR (Return Address)
&lt;/h2&gt;

&lt;p&gt;This article introduces a &lt;strong&gt;stealth and cross-platform&lt;/strong&gt; method that doesn't read any instructions, doesn't scan memory, and is extremely difficult for Frida to bypass.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✔ Why LR works
&lt;/h3&gt;

&lt;p&gt;Inline hook frameworks (Frida, Dobby, xhook, etc.) must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;overwrite the &lt;strong&gt;LR register&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;redirect &lt;code&gt;RET&lt;/code&gt; to a trampoline stored in a custom allocated memory page   (not inside the original module)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thus:&lt;/p&gt;

&lt;h3&gt;
  
  
  ➜ &lt;strong&gt;If a function’s LR is outside its module’s memory range → it is inline-hooked.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Does not read &lt;code&gt;.text&lt;/code&gt; code section&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cannot be traced via hardware breakpoints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Works on ARM64 and x86_64&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Detection Pipeline
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1 — Retrieve current module range
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static uint64_t g_begin = 0;
static uint64_t g_end = 0;

__attribute__((constructor))
static void init_module_range() {
    Dl_info info;
    if (dladdr((void*)init_module_range, &amp;amp;info)) {
        g_begin = (uint64_t)info.dli_fbase;
        g_end = g_begin + get_module_size(info.dli_fname);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2 — Read LR via ARM64 inline assembly
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;__attribute__((alwaysinline))
uint64_t get_lr() {
    uint64_t lr;
    asm volatile(
        "mov x10, x29 \n"
        "ldr %0, [x10, #8]\n"
        : "=r"(lr)
        :
        : "x10"
    );
    return lr;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3 — Detect inline hook
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void check_inline_hook() {
    uint64_t lr = get_lr();

    if (lr &amp;lt; g_begin || lr &amp;gt; g_end) {
        LOGD("[!] Inline-hook detected. lr = %llx", lr);
    } else {
        LOGD("[+] Function not hooked.");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Advanced Protection: Stack Corruption &amp;amp; Anti-Analysis
&lt;/h2&gt;

&lt;p&gt;To make debugging nearly impossible:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;detect hook&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;overwrite stack (FP → FP+2048)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;jump to an invalid address&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void anti_debug_crash() {
    uint64_t fp;
    asm volatile("mov %0, x29" : "=r"(fp));

    memset((void*)fp, 0xCC, 2048);
    ((void(*)())0x12345678)();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This destroys stack traces and prevents reverse engineering of your protection logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Conclusion
&lt;/h2&gt;

&lt;p&gt;This LR-based inline hook detection method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;does not read code pages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;is nearly breakpoint-proof&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;detects Frida, Dobby, xhook, and other trampoline mechanisms&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;works on Android and Windows&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It offers a new direction for mobile security, anti-cheat systems, and runtime protection.&lt;/p&gt;

&lt;p&gt;I’m H.&lt;br&gt;
Six years deep in Android reversing.&lt;br&gt;
Is this sword sharp today?&lt;br&gt;
— H&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mxncebnkbrdy02pu05w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mxncebnkbrdy02pu05w.jpg" alt="Image description style=" width="784" height="1168"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>security</category>
      <category>inlinehook</category>
      <category>detection</category>
    </item>
    <item>
      <title>You Thought Frida Was Stealth When Not Attached? Dirty Pages Beg to Differ</title>
      <dc:creator>Jack Sparrow</dc:creator>
      <pubDate>Wed, 03 Dec 2025 14:31:37 +0000</pubDate>
      <link>https://forem.com/jack_sparrow_2386c07e8b94/you-thought-frida-was-stealth-when-not-attached-dirty-pages-beg-to-differ-8f6</link>
      <guid>https://forem.com/jack_sparrow_2386c07e8b94/you-thought-frida-was-stealth-when-not-attached-dirty-pages-beg-to-differ-8f6</guid>
      <description>&lt;p&gt;All the classic Frida checks in 2025 — maps, thread names, CRC, ports — are dead.&lt;br&gt;&lt;br&gt;
Today I’m dropping the one that still kills 99 % of setups: &lt;strong&gt;Dirty-Page Detection&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Key point:  &lt;strong&gt;As long as frida-server is running on the device — even if it never attaches to your app — you can detect it globally.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Dirty-Page Detection Is Almost Unbypassable
&lt;/h3&gt;

&lt;p&gt;To listen for zygote forks and signals, frida-server inline-hooks three critical modules inside &lt;strong&gt;system_server&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;libc.so&lt;/li&gt;
&lt;li&gt;libselinux.so&lt;/li&gt;
&lt;li&gt;libandroid_runtime.so&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inline-hooking the read-only .text section triggers &lt;strong&gt;Copy-On-Write&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
The original file-backed pages become &lt;strong&gt;private dirty pages&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Even if Frida later restores the original bytes in the on_leave callback, the pages stay private forever.&lt;/p&gt;

&lt;p&gt;That’s the permanent fingerprint we hunt.&lt;/p&gt;
&lt;h3&gt;
  
  
  Method 1 – smaps  file detection
&lt;/h3&gt;

&lt;p&gt;Sample code is used to demonstrate the thought process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;frida_detected_smaps&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;libc.so&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;libselinux.so&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;libandroid_runtime.so&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/proc/self/smaps&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;smaps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;lib&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Find the library mapping
&lt;/span&gt;        &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;smaps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;smaps&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="c1"&gt;# Private_Dirty &amp;gt; 0 → COW happened → Frida was here
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Private_Dirty:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;dirty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Private_Dirty:\s+(\d+)&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dirty&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dirty&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Method 2 – pagemap (nuclear option, bit 61)
&lt;/h3&gt;

&lt;p&gt;Linux pagemap entry (64 bit):bit 63 → page present&lt;br&gt;&lt;br&gt;
bit 61 → soft-dirty (set on COW)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;page_is_dirty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vaddr&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/proc/self/pagemap&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seek&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;vaddr&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unpack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Q&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;))[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;present&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;soft_dirty&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;61&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="c1"&gt;# ← this is the killer bit 
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;present&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;soft_dirty&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  

&lt;span class="c1"&gt;# Example: check fork()
&lt;/span&gt;&lt;span class="n"&gt;libc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CDLL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;libc.so&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fork_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;libc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_void_p&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;page_is_dirty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fork_addr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;# True → Frida present
# you can add more function for detection, such as : vfork/opendir/abort/closedir/close/signal/sigaction/exit
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Bottom LineIn
&lt;/h1&gt;

&lt;p&gt;2025, if you’re still checking /proc/self/maps or thread names, you’re fighting 2022 battles.&lt;br&gt;
Dirty-page detection is the current meta.&lt;/p&gt;

&lt;p&gt;I’m H.&lt;br&gt;
Six years deep in Android reversing.&lt;br&gt;
The real game has just started.&lt;br&gt;
— H&lt;/p&gt;

</description>
      <category>frida</category>
      <category>android</category>
      <category>security</category>
      <category>detection</category>
    </item>
  </channel>
</rss>
