1

Let's assume we have a such code snippet:

public class Test {
  public void testArrayValue() {
    Object[] objects = new Object[1];
    fillObject(objects);
    Log.d("test", (String)objects[0]);
  }
  public void fillObject(Object[] objects) {
    objects[0] = new String("fillObject str");
  }
}

How to hook the fillObject method to change the value of the first element in array passed to method?

Java.perform(function () {
    var clazz = Java.use("com.some.package.Test");
    clazz.fillObject.overload('[Ljava.lang.Object;').implementation = function(var_0) {
        
      // this won't work :( assigning a string value to var_0[0] 
      // does not pass it outside the hooked code
      // 
      var stringClass = Java.use("java.lang.String");
      var stringInstance = stringClass.$new("Hello World");
      var_0[0] = stringInstance
    };
});

The output of running hooked code will be "fillObject str", and not "Hello World"

4
  • yes, the hooked code is executed. I just removed all unnecessary code to make it easier to point out the code that doesn't work. Despite the fact that I assign a new value to var_0[0], it is not passed out of the hooked code.
    – alx
    Aug 12, 2023 at 5:07
  • Just for the records: is the Java code running in an JRE or inside an Android app (Dalvik VM)?
    – Robert
    Aug 12, 2023 at 16:56
  • Java bytecode is converted to Dalvik bytecode and runs inside Dalvik VM
    – alx
    Aug 12, 2023 at 17:09
  • Yes I know that. From the perspective of Java code there is no difference but from the perspective of Frida there is a difference. I just want to understand if the bug you were running into is limited to Android or if it is a general Java hooking problem.
    – Robert
    Aug 12, 2023 at 18:12

1 Answer 1

1

Frida seems to have some bugs regarding Java arrays that are modified or replaced by JavaScript code. My guess is that the conversion (and mapping of modifications) between the Java array instance and JavaScript array instance has some flaws.

Therefore the only alternative I see is using pure Java methods to modify the array content, that way you should be able to bypass this bug.

One possible way is to use the method Arrays.fill(Object[] array, int fromIndex,int toIndex, Object val)1:

var stringClass = Java.use("java.lang.String");
var stringInstance = stringClass.$new("Hello World");
var arraysClass = Java.use("java.util.Arrays");
arraysClass.fill(var_0, 0, 1, stringInstance); // equivalent to var_0[0] = stringInstance

I have not tested this code, but it should perform the array modification you want to do.

2
  • Great! It works. Only a little fix: toIndex - the index of the last element exclusive: arraysClass.fill(var_0, 0, 1, stringInstance); Thanks.
    – alx
    Aug 12, 2023 at 16:49
  • @alx Yes indeed the toIndex parameter should be 1, I have corrected that in my answer. If my answer was helpful feel free to upvote it (up arrow on the left) and/or accept it (gray arrow).
    – Robert
    Aug 12, 2023 at 16:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.