Search code examples
javaandroidfrida

How to access object's fields


I am able to hook method on android app using frida:

Java.perform(function () {
    var targetClass = Java.use("X.0kI");
    targetClass.getDoneValue.overload('java.lang.Object').implementation = function (object) {
        var retval = this.getDoneValue(object);

        console.log('return: ' + retval);
        console.log('return: classname: ' + retval.$className);
        console.log('return: success: ' + retval.success);
        console.log('return: resultDataBundle: ' + retval.resultDataBundle);
        console.log('return: toString(): ' + retval.toString());

    };
})

This code prvides following log:

return: OperationResult success=true, resultDataString=, resultDataBundle=Bundle[{result=com.testapp.account.recovery.common.protocol.TestMethod$Result@a0a6954, resultType=1}], errorCode=NO_ERROR, errorDescription=, exception=
return: classname: com.testapp.service.OperationResult
return: success: undefined
return: resultDataBundle: undefined
return: toString(): OperationResult success=true, resultDataString=, resultDataBundle=Bundle[{result=com.testapp.account.recovery.common.protocol.TestMethod$Result@a0a6954, resultType=1}], errorCode=NO_ERROR, errorDescription=, exception=

Why retval.success and retval.resultDataBundle are undefined despite the log from first and last lines?

Or maybe there is another way to access those fields?

I also tried using Java.cast:

var OperationResult = Java.use('com.testapp.service.OperationResult');
if (retval.$className === 'com.testapp.service.OperationResult') {
    var result = Java.cast(retval, OperationResult);
    console.log('result: success: ' + result.success);
    console.log('result: resultDataBundle: ' + result.resultDataBundle);
}

with log:

result: success: [object Object]
result: resultDataBundle: [object Object]

JSON.stringify() gives {} instead of [object Object]

Also tired Java.choose() with pretty much same undefined results.

How should I properly access Java objects's fields using Frida?

*EDIT

Class description using Object.getOwnPropertyNames(jClass.__proto__):

_name: com.testapp.service.OperationResult
_fields: 
    public android.os.Bundle com.testapp.service.OperationResult.resultDataBundle
    public boolean com.testapp.service.OperationResult.success

Solution

  • After you cast use .value to access member's value.

    console.log(success.value)