skylot / jadx

Dex to Java decompiler
Apache License 2.0
41.81k stars 4.88k forks source link

Frida snippet don't work for constructors anymore #1714

Closed daMatz closed 2 years ago

daMatz commented 2 years ago

When generating a Frida snippet via jadx for a constructor, the code looks like this:

let MyClass = Java.use("com.MyClass");
MyClass["$init"].implementation = function () {
    console.log('$init is called');
    let ret = this.$new();
    console.log('$init ret value is ' + ret);
    return ret;
};

This generates the following error in the latest frida versions (haven't tested how far back that dates):

Error: Implementation for MyClass expected return value compatible with void

When using let ret = this.$init(); instead, it works for me.

let MyClass = Java.use("com.MyClass");
MyClass["$init"].implementation = function () {
    console.log('$init is called');
    let ret = this.$init();
    console.log('$init ret value is ' + ret);
    return ret;
};
jpstotz commented 2 years ago

According to https://github.com/skylot/jadx/pull/1605 $new should the the correct way to call an constructor.

What version of Frida and frida-server do you use?

daMatz commented 2 years ago

The current one, 16.0.2. $new also used to work for me in the past, but currently I get the error above.

skylot commented 2 years ago

Hm. I am not a Frida expert, but I believe that a $new is a correct call here. Unfortunately, error message is not very helpful, so it is hard to understand what is the main cause of the issue. I will try to reproduce it, so I will keep this issue open for some time.

As a workaround, I can move template for this snippet to the preferences, so it will be possible to edit it, but this solution is not flexible enough, because a lot of code used to form a strings in snippet. So maybe script for that will be better (I will try to make it).

daMatz commented 2 years ago

@skylot I created a controlled environment to test this.

I created new Android Studio Project with a basic Activity and a basic class with constructor. Here is the working example with $init:

image

Here is the failing example with $new:

image

I am happy to provide the code or condunct further tests.

Seems like the frida workflow here is strange, created a ticket for it in the frida repo: https://github.com/frida/frida/issues/2302

xxr0ss commented 2 years ago

Hi @skylot @daMatz @jpstotz ,

See https://github.com/frida/frida/issues/2302#issuecomment-1303073610 and $init's document:

image

So I think even $new should not be called in the $init, because the instance is already created.

daMatz commented 2 years ago

@xxr0ss thank you for clarifying

image

Therefore the FridaAction needs to be adapted further.

skylot commented 2 years ago

@daMatz I commit additional changes including separate template for constructors and void methods. Please check :slightly_smiling_face:

@xxr0ss thank you for your help :+1:

daMatz commented 2 years ago

Thanks @skylot! Just tried the nightly build jadx-1.4.5.95-bb4d88cc.zip.

The generated code for the example above is now

    let MyClass = Java.use("com.jadx.test.MyClass");
    MyClass["$init"].implementation = function (str) {
        console.log('MyClass.$init is called' + ', ' + 'str: ' + str);
                this["$init"](str);
    };

Looking good!

skylot commented 2 years ago

Great! Thanks for verify.