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);
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 wayfrida-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 usingJava.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
.