frida/frida-java-bridge

canInvokeWith throws error for some methods

BLuFeNiX opened this issue · 0 comments

Observed on Frida 15.1.13 and 15.1.12:

When calling canInvokeWith on a Java method wrapper, I get the following error.

TypeError: Cannot read property '5' of undefined
    at Function.value (frida/node_modules/frida-java-bridge/lib/class-factory.js:1029:1)
    at foo (agent/index.ts:525:18)
    at agent/index.ts:630:24
    at c.perform (frida/node_modules/frida-java-bridge/lib/vm.js:11:1)
    at y.perform (frida/node_modules/frida-java-bridge/index.js:193:1)
    at Object.foo (agent/index.ts:628:14)
    at frida/runtime/message-dispatcher.js:13:1
    at c (frida/runtime/message-dispatcher.js:23:1)

If I print the contents of the canlnvokeWith function, I get the code that's failing:

value(e) {
      const t = this._p[5];
      return e.length === t.length && t.every(((t, n) => t.isCompatible(e[n])));
    }

So, it seems to be a problem with this._p being undefined. Am I doing something wrong, or is this a bug?


Further testing:

console.log(`Java.available: ${Java.available}\n`);
Java.perform(function() {

	console.log('--------------------');
	console.log('String.format');
	console.log('--------------------');

	var String = Java.use('java.lang.String');
	let a = String.$new("hi %s");
	let b = String.$new("there");
	let result = String.format(a, [b]);
	console.log(`format("hi %s", "there"): ${result}`);

	var formatMethod = String.format.overload('java.lang.String', '[Ljava.lang.Object;');
	console.log(`canInvokeWith result: ${formatMethod.canInvokeWith([a, [b]])}`);


	console.log('');


	console.log('--------------------');
	console.log('String.equals');
	console.log('--------------------');

	var strInstance = String.$new("hello world");
	console.log(`sanity check: ${strInstance.toCharArray()}`);
	console.log(`strInstance.equals(null): ${strInstance.equals(null)}`);
	console.log(`strInstance.equals(strInstance): ${strInstance.equals(strInstance)}`);

	console.log(`canInvokeWith result: ${strInstance.equals.canInvokeWith([null])}`);

});

output:

$ frida -U -n system_server -l foo.js
     ____
    / _  |   Frida 15.1.13 - 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/
Attaching...                                                            
Java.available: true

--------------------
String.format
--------------------
format("hi %s", "there"): hi there
canInvokeWith result: true

--------------------
String.equals
--------------------
sanity check: h,e,l,l,o, ,w,o,r,l,d
strInstance.equals(null): false
strInstance.equals(strInstance): true
TypeError: cannot read property '5' of undefined
    at value (frida/node_modules/frida-java-bridge/lib/class-factory.js:1029)
    at <anonymous> (/foo.js:30)
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/vm.js:16)
    at _performPendingVmOps (frida/node_modules/frida-java-bridge/index.js:238)
    at <anonymous> (frida/node_modules/frida-java-bridge/index.js:213)
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/vm.js:16)
    at _performPendingVmOpsWhenReady (frida/node_modules/frida-java-bridge/index.js:232)
    at perform (frida/node_modules/frida-java-bridge/index.js:192)
    at <eval> (/foo.js:32)
[Android Emulator 5554::system_server]->

This leads me to believe that the problem is specific to instance methods, rather than static methods, but my tests are limited to the above.