Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

frida-inject injects too late #1

Open
msmuenchen opened this issue Sep 17, 2023 · 1 comment
Open

frida-inject injects too late #1

msmuenchen opened this issue Sep 17, 2023 · 1 comment

Comments

@msmuenchen
Copy link

msmuenchen commented Sep 17, 2023

In some cases, particularly apps that are very fast in early root detection scripts, frida-inject is too slow. For me, it breaks at Samsung Health (apk available in result.downloadURI of this XML).

When launching tethered using frida -U -l com.sec.android.app.shealth.js -f com.sec.android.app.shealth, the script works because it begins to run at the same time as the process spawns and then can do a race against the classloader initialization, but it seems like the way frida-inject works (listening on the global eventlog and then spawning an external process) is too slow, and the root detection has already run by the time the payload script runs. This also applies if using Java.perform.

Ideally (assuming that's even possible?), frida-inject should hook in zygote and execute very early in the app creation process, or it should offer some way of hooking the load procedures of dalvik.system.PathClassLoader to catch when the paths of the apk directory are added.

I attached an example run log of the script from my PC and the source of my hotpatch script both when racing the ClassLoader and when using Frida bridge's Java.perform.

$ frida -U -l com.sec.android.app.shealth.js -f com.sec.android.app.shealth
     ____
    / _  |   Frida 16.1.4 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to SM T575 (id=xxx:5555)
Spawning `com.sec.android.app.shealth`...
Initializing com.sec.android.app.shealth anti-anti-root patcher
Attempting to check with dalvik.system.PathClassLoader[DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /system/system_ext/lib64, /system/lib64, /system/system_ext/lib64]]]
Class not found, attempting next loader
Attempting to check with java.lang.BootClassLoader@8a0e187
Class not found, attempting next loader
Spawned `com.sec.android.app.shealth`. Resuming main thread!
Attempting to check with dalvik.system.PathClassLoader[DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /system/system_ext/lib64, /system/lib64, /system/system_ext/lib64]]]
Class not found, attempting next loader
Attempting to check with java.lang.BootClassLoader@8a0e187
[SM T575::com.sec.android.app.shealth ]-> Class not found, attempting next loader
--- SNIP, it's ~30x just the two "Attempting to check" messages ---
Attempting to check with dalvik.system.PathClassLoader[DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /system/system_ext/lib64, /system/lib64, /system/system_ext/lib64]]]
Class not found, attempting next loader
Attempting to check with java.lang.BootClassLoader@8a0e187
Class not found, attempting next loader
Attempting to check with dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/~~h3dzJSNtExEFLu57JzJ5IA==/com.sec.android.app.shealth-8Pg-v9-ba8xGlXIv_TNTBw==/base.apk"],nativeLibraryDirectories=[/data/app/~~h3dzJSNtExEFLu57JzJ5IA==/com.sec.android.app.shealth-8Pg-v9-ba8xGlXIv_TNTBw==/lib/arm64, /data/app/~~h3dzJSNtExEFLu57JzJ5IA==/com.sec.android.app.shealth-8Pg-v9-ba8xGlXIv_TNTBw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]]
Found KnoxControl, hooking functions
console.log("Initializing com.sec.android.app.shealth anti-anti-root patcher");

global.t = setInterval(function() { // avoid java.lang.ClassNotFoundException
    Java.enumerateClassLoaders({
        onMatch: function(loader) {
            console.log("Attempting to check with", loader);
            Java.classFactory.loader = loader;
            var TestClass;

            // Hook the class if found, else try next classloader.
            try {
                TestClass = Java.use("com.samsung.android.sdk.healthdata.privileged.KnoxControl");
                console.log("Found KnoxControl, hooking functions");
                clearInterval(global.t);
                Java.use("com.samsung.android.sdk.healthdata.privileged.KnoxControl").checkKnoxCompromised.implementation = () => false;
                Java.use("com.samsung.android.app.shealth.tracker.stress.tile.StressHService").loadData.implementation = function() {
                    return;
                }
                Java.use("com.samsung.android.app.shealth.tracker.stress.tile.StressHService").isMeasurementEnabled.implementation = function() {
                    return false;
                }
                Java.use("android.os.Build").MODEL.value = "SM-G990B";
            } catch (error) {
                if (error.message.includes("ClassNotFoundException")) {
                    console.log("Class not found, attempting next loader");
                }
            }

        },
        onComplete: function() {}
    });
}, 0);
Java.perform(() => {
                console.log("App class loader should be present, hooking functions");
                Java.use("com.samsung.android.sdk.healthdata.privileged.KnoxControl").checkKnoxCompromised.implementation = () => false;
                Java.use("com.samsung.android.app.shealth.tracker.stress.tile.StressHService").loadData.implementation = function() { return; }
                Java.use("com.samsung.android.app.shealth.tracker.stress.tile.StressHService").isMeasurementEnabled.implementation = function() { return false; }
                Java.use("android.os.Build").MODEL.value="SM-G990B";
});
@nitanmarcel
Copy link
Owner

I'm not even sure it can hook into the app at initialization since it might break due to magisk's hide ptrace login

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants