frida
frida copied to clipboard
Frida doesn't catch Java exceptions in Java hooks
Frida ignore Java exception generated by NativeFunction calls and propagate (so setExceptionHandler miss them) and le the app crash when the exception is generated by the app itself.
Here an example reproducer (in the comment there is the exception from logcat):
/*
2019-12-18 16:07:56.197 17107-17107/com.example.ndktest1 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ndktest1, PID: 17107
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.ArithmeticException: divide by zero
at com.example.ndktest1.MainActivity.test_java_func(MainActivity.java:22)
at com.example.ndktest1.MainActivity.genExc(MainActivity.java:35)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
*/
Process.setExceptionHandler(function(d) {
console.log(d)
return false
})
// To be compatible with frida-fuzzer
rpc.exports.loop = function () { }
Java.perform(function() {
var MainActivity = Java.use('com.example.ndktest1.MainActivity');
MainActivity.sendMessage.implementation = function () {
console.log (" >> Button clicked!");
var activity = this;
var JString = Java.use('java.lang.String');
// decomment to try with propagate
//var test_java_func_steal = activity.test_java_func.clone({ exceptions: 'steal' });
var fuzzer_test_one_input = function (payload, size) {
var arr = Java.array('byte', Array.from(payload.readByteArray(size)));
var str = JString.$new(arr);
console.log (payload.readByteArray(size));
//test_java_func_steal.call(activity, str);
activity.test_java_func(str);
}
var mem = Memory.allocUtf8String("bbb");
fuzzer_test_one_input(mem, 1);
// input that trigger the ArithmeticException
mem = Memory.allocUtf8String("aaa");
try {
fuzzer_test_one_input(mem, 1);
} catch (err) {
// should catch here the ArithmeticException...
console.log("CATCHED!\n" + err.stack);
throw err;
}
// execute again as nothing happened
mem = Memory.allocUtf8String("bbb");
fuzzer_test_one_input(mem, 1);
}
});
I attach the code of the sample app and the APK. ndktest1.zip app-debug.apk.zip
With the button "Button" you trigger the sendMessage hook in the script, with the button "Crash" you trigger the ArithmeticException (it is simply an hardcoded call to test_java_func("aaa")).
Hi, is this solved?