使用 Frida 在当前 class 中设置成员

Setting a member in current class using Frida

我正在使用代码挂钩 Frida 中的某个函数:

this.carrier.getId()

但是此时this.carrier还没有设置,导致应用崩溃
所以我想在class中的当前函数中手动设置这个成员。因此,该运营商将在代码生成时存在。
问题是我这样做遇到了问题。

到目前为止,这是我得到的:

Java.perform(function () {
    var SignUpActivity = Java.use('com.app.features.authentication.SignUpActivity');
    SignUpActivity.validatePhoneNumber.implementation = function() {
        
        var Carrier = Java.use("com.app.Carrier");
        this.carrier = Carrier.$new();
        console.log(this.carrier) // This prints "[object Object]"
        console.log(this.carrier.setId) // This prints "undefined"
        this.carrier.setId(123); // crashes

    };
});

承运人代码:

package com.app;

import android.os.Parcel;
import android.os.Parcelable;

public class Carrier implements Parcelable {

    private int id;
    private String name;
    private String officeTerminalAddress;

    public Carrier() {
    }

    protected Carrier(Parcel parcel) {
        this.id = parcel.readInt();
        this.name = parcel.readString();
        this.officeTerminalAddress = parcel.readString();
    }

    public int getId() {
        return this.id;
    }

    public void setId(int i) {
        this.id = i;
    }

}

好像是Frida的通病,Frida访问字段的方式不一样。

Frida 使用 JavaScript 代码,因此它无法直接处理非 JavaScript 对象。 因此,它将“本机”对象(在本例中为 Android Java 对象)包装在 JavaScript 对象中。

如果您现在调用 Frida this.carrier,您将获得 Frida Java脚本包装器,而不是您瞄准的 Java 载体实例。

当然,Frida Java脚本包装器没有您尝试调用的方法,因此 this.carrier.setId(123); 总是会失败。

使用 Frida 访问 Java 字段

要访问一个字段,您总是必须对其调用 .value 以获取实际值:

所以如果你想要 this.carrier 你必须使用 this.carrier.value.

此外,建议通过名称访问字段并在其前面添加下划线。否则在混淆的应用程序中,可能会出现同名的字段和方法。在这种情况下,Frida 不知道您是想访问字段 carrier 还是方法 carrier.

结论如果您想使用 Frida 访问 Android 应用程序中 Java class 实例的字段,推荐的方法是

this._carrier.value

所以为了写一个字段值你应该调用

this._carrier.value = ...

阅读方式相同

参考 Frida 帮助页面

这在 Frida 页面上也有描述,例如here:

Note we use this.m.value = 0 instead of this.m = 0 to set the field’s value. If there is also a method in this class called m, we need to use this._m.value = 0 to set the value of field m. In general, when looking at the properties of objects it will be necessary to use .value to access the values those fields refer to.

完整的简化代码

但在你的情况下,你可以通过使用局部变量来简化一切:

Java.perform(function () {
    var SignUpActivity = Java.use('com.app.features.authentication.SignUpActivity');
    SignUpActivity.validatePhoneNumber.implementation = function() {
        
        const Carrier = Java.use("com.app.Carrier");
        const c = Carrier.$new();
        c.setId(123);
        this._carrier.value = c;
    };
});