1

Looking to modify the return value of a method that is calling from an enum type. I am able to call the method and properly display the enum value into console, but then it crashes the application complaining on a compatible implementation. Example code below with error:

Java.perform(() => {
const Class = Java.use('com.package.class');
Class.getMethod.implementation = function() {
 
var str = this.getMethod();
 
send('getMethod() value for enum is: ' + str);
 
};
});
[Pixel 5::com.package ]-> message: {'type': 'send', 'payload': 'getMethod() value for enum is: EnumContent'} data: None
Error: Implementation for getMethod expected return value compatible with [Lcom.com.package.EnumType;
    at ne (frida/node_modules/frida-java-bridge/lib/class-factory.js:674)
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/class-factory.js:651)
Process terminated

My final goal is to obtain the initial enum value, change the enum return value ingested by the method and display the results in console.

I found a few reference here: https://github.com/frida/frida/issues/1256 and here: https://neo-geo2.gitbook.io/adventures-on-security/frida-scripting-guide/enums but was ultimately unsuccessful in helping.

Edit: To elaborate with an example. Say you are attempting to use JS script like below with return or console.log:

Java.perform(() => {
var enumContent = Java.use('com.some.package.Enum');
return enumContent.values();
)};

or

Java.perform(() => {
var enumContent = Java.use('com.some.package.Enum');
console.log(enumContent.A.value);
)};

Assuming your Java code looks like this:

package com.some.package;

import kotlin.Metadata;

public enum Enum {
    A,
    B,
    C,
    D
}

Edit 2:

Here is a snippet of that class.

package com.package.class;
[TRUNCATED]
...
[TRUNCATED]
    @NotNull
    public final Enum[] getMethod() {
        return this.selection;
    }
}
sloan
  • 11
  • 2
  • If you hook and replace a Java method using `Class.getMethod.implementation = function() {..}` you have to provide a return value that matches the Java declaration of the method you hook. But your code doe not return anything, as you have seen this causes an error `Implementation for getMethod expected return value compatible with [Lcom.com.package.EnumType;`. – Robert Aug 11 '23 at 07:19
  • Another problem is that you only look at the Java code, but you should better look at the smali code (and may be post the relevant parts of your enum here). I have seem decompiled code of enum instances where each enum value was saved as field of the enum name (just like you try). But in other obfuscated classes the enum values were saved in fields that are always named `a` `b` `c` `d` independent of the original enum name. – Robert Aug 11 '23 at 11:36
  • @Robert I have attached a little snippet of what the class looks like. Let me know your thoughts. I have been able to use a Java.choose (className, callback) and read the values from the selection instance of A, B, C, D. – sloan Aug 11 '23 at 22:11

1 Answers1

0

Your main problem is that if you hook a Java method you automaticalyl replace the method. Therefore is the method has a return type other than void you are forced to somehow provide a return value that matches the return type:

Not sure if the following code directly works, but it demonstrates whyt you have to do to return a new Enum[]:

Java.perform(() => {
    const myClass = Java.use('com.package.class');
    const enumContent = Java.use('com.some.package.Enum');
    myClass.getMethod.implementation = function() {
        var enumArr = this.getMethod();
        send('getMethod() value for enum is: ' + enumArr);

        // you need to return a value of the type Enum[]
        // you have the choice to return enumArr or 
        // create a new Enum array with a content of your choice:

        return Java.array('com.some.package.Enum', [ enumContent.A.value ]);

        // return enumArr; // alternative solution return the unmodified array
    };
});
Robert
  • 39,162
  • 17
  • 99
  • 152
  • Thanks for the help! This was definitely useful and I was able to obtain a partial working script. For now I can dump the original getMethod and enumContent from the enum type. If I uncomment the `return enumArr` and run in frida the application does not crash, but no change in the UI sadly. If I uncomment `return Java.array` and comment out the `return Java.array` line the application crashes and displays a `process terminated` in the terminal. In `adb logcat` I get the following error. `java.lang.IllegalArgumentException: vectorIndex out of range` – sloan Aug 14 '23 at 02:26
  • @sloan Sounds like `getMethod` usually returns an array with more than one entry and the code that makes use of the result depends on having more than one entry. Check the length original array and make sure you return the same number of elements. – Robert Aug 14 '23 at 06:47