Skip to content

MASTG-DEMO-0038: Detecting StrictMode Uses with Frida

Download MASTG-DEMO-0038 APK Open MASTG-DEMO-0038 Folder Build MASTG-DEMO-0038 APK

Sample

This sample demonstrates the detection of StrictMode uses at runtime using Frida. The app enables a StrictMode policy to detect leaked SQLite objects and intentionally leaves a cursor unclosed to trigger the policy.

../MASTG-DEMO-0037/MastgTest.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package org.owasp.mastestapp

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.os.StrictMode


class MastgTest (private val context: Context){

    fun mastgTest(): String {
        enableStrictMode()
        triggerSqliteCursorLeak()

        System.gc() // Force garbage collection to trigger leak detection

        return "SUCCESS!!\n\nSQL Cursor leaked."
    }

    private fun enableStrictMode() {
        StrictMode.setVmPolicy(
            StrictMode.VmPolicy.Builder()
                .detectLeakedClosableObjects() // Detect leaked/unclosed SQLite objects
                .penaltyLog()                 // Log violations
                .build()
        )
    }

    private fun triggerSqliteCursorLeak() {
        val db: SQLiteDatabase = context.openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null)
        db.execSQL("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)")
        db.execSQL("INSERT INTO users (name) VALUES ('Alice'), ('Bob')")

        // Create cursor, and intentionally do not close it
        val cursor = db.rawQuery("SELECT * FROM users", null)
    }
}

Steps

  1. Install the app on a device ( Installing Apps)
  2. Make sure you have Frida for Android installed on your machine and the frida-server running on the device
  3. Run run.sh to spawn the app with Frida
  4. Click the Start button
  5. Stop the script by pressing Ctrl+C
1
2
#!/bin/bash
frida -U -f org.owasp.mastestapp -l ./script.js -o output.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Java.perform(() => {

    // Function to print backtrace with a configurable number of lines (default: 8)
    function printBacktrace(maxLines = 8) {
        let Exception = Java.use("java.lang.Exception");
        let stackTrace = Exception.$new().getStackTrace().toString().split(",");

        console.log("\nBacktrace:");
        for (let i = 0; i < Math.min(maxLines, stackTrace.length); i++) {
            console.log(stackTrace[i]);
        }
    }

    // Hook StrictMode.setVmPolicy
    let StrictMode = Java.use('android.os.StrictMode');

    StrictMode.setVmPolicy.implementation = function (policy) {
        console.log("\n[*] StrictMode.setVmPolicy() called\n");

        // Java stack trace
        printBacktrace();

        console.log("Policy: " + policy);
        this.setVmPolicy(policy);
    };

    // Hook StrictMode.VmPolicy.Builder.penaltyLog
    let VmPolicyBuilder = Java.use('android.os.StrictMode$VmPolicy$Builder');

    VmPolicyBuilder.penaltyLog.implementation = function () {
        console.log("\n[*] StrictMode.VmPolicy.Builder.penaltyLog() called\n");

        // Java stack trace
        printBacktrace();

        return this.penaltyLog();
    };

    console.log("\n[+] Frida script loaded to detect StrictMode usage and penaltyLog calls.\n");
});

Observation

The Frida script output reveals the runtime usage of StrictMode.

output.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[+] Frida script loaded to detect StrictMode usage and penaltyLog calls.


[*] StrictMode.VmPolicy.Builder.penaltyLog() called


Backtrace:
android.os.StrictMode$VmPolicy$Builder.penaltyLog(Native Method)
android.os.StrictMode$VmPolicy$Builder.build(StrictMode.java:1226)
android.os.StrictMode.initVmDefaults(StrictMode.java:1522)
android.app.ActivityThread.handleBindApplication(ActivityThread.java:6844)
android.app.ActivityThread.handleBindApplication(Native Method)
android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236)
android.os.Handler.dispatchMessage(Handler.java:106)

[*] StrictMode.setVmPolicy() called


Backtrace:
android.os.StrictMode.setVmPolicy(Native Method)
android.os.StrictMode.initVmDefaults(StrictMode.java:1522)
android.app.ActivityThread.handleBindApplication(ActivityThread.java:6844)
android.app.ActivityThread.handleBindApplication(Native Method)
android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236)
android.os.Handler.dispatchMessage(Handler.java:106)
android.os.Looper.loopOnce(Looper.java:205)
Policy: [StrictMode.VmPolicy; mask=1082130464]

Evaluation

The test fails because the Frida script output shows the runtime usage of StrictMode, specifically:

  • StrictMode.VmPolicy.Builder.penaltyLog
  • StrictMode.setVmPolicy