Skip to content

toString() overwrite can't call member functions #43

@nioncode

Description

@nioncode

Calling a member function of a Java Pojo inside its overridden toString() implementation raises an exception:

'TypeError: undefined not callable', 'stack': 'TypeError: undefined not callable\n    at [anon] (duk_js_call.c:842)\n    at script1.js:18\n    at call (native)\n    at toString (input:1)', 'fileName': 'script1.js', 'lineNumber': 18, 'columnNumber': 1}

Calling the same member function from a user defined method asString() works fine.

Java Pojo:

public class Pojo {

	private String str;
	private long num;

	public Pojo(String str, long num) {
		this.str = str;
		this.num = num;
	}

	public String getStr() {
		return str;
	}

	public long getNum() {
		return num;
	}

	public String asString() {
		return "Pojo[str=" + str + ", num=" + num + "]";
	}
}

Activity:

public class MainActivity extends Activity {

	static {
		System.loadLibrary("frida-gadget-10.5.14-android-x86");
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		findViewById(R.id.btn).setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View view) {
				printPojo(new Pojo("demo", System.currentTimeMillis()));
			}
		});
	}

	public void printPojo(Pojo pojo) {
		Log.d("FRIDA-android", pojo.asString());
	}
}

excerpt of frida script:

	Java.perform(function() {
		log("    hooking java");
		var pojo = Java.use('com.example.myapplication.Pojo');
		pojo['toString'].implementation = function() {
			log("toString() called");
			var i = this.getNum();
			log('num=' + i);
		  	return 'Pojo[num=' + i + ']';
		};
		pojo['asString'].implementation = function() {
			log("asString() called");
			var i = this.getNum();
			log('num=' + i);
		  	return 'Pojo[num=' + i + ']';
		};

		var hook = Java.use('com.example.myapplication.MainActivity');
		hook['printPojo'].implementation = function() {
			var pojo = arguments[0];
			log('hook num=' + pojo.getNum());
			log('\ncalling asString');
			log('asString() result: ' + pojo.asString());
			log('\ncalling toString');
			log('toString() result: ' + pojo.toString());
		}
	});

stdout output:

java available: true
    hooking java
java done
hook num=1505470146320

calling asString
asString() called
num=1505470146320
asString() result: Pojo[num=1505470146320]

calling toString
toString() called
{'type': 'error', 'description': 'TypeError: undefined not callable', 'stack': 'TypeError: undefined not callable\n    at [anon] (duk_js_call.c:842)\n    at script1.js:18\n    at call (native)\n    at toString (input:1)', 'fileName': 'script1.js', 'lineNumber': 18, 'columnNumber': 1}
None
toString() result: null

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions