#javascript #java #android #reverse-engineering #frida
Вопрос:
Я подключаю определенную функцию в Frida, которая использует код:
this.carrier.getId()
Однако на данный момент this.carrier еще не установлен, что приводит к сбою приложения.
Итак, я подумываю о том, чтобы вручную установить этот член в текущей функции в классе. Таким образом, этот носитель будет существовать к моменту выполнения кода.
Проблема в том, что при этом я сталкиваюсь с проблемой.
Пока это то, что я получил:
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;
}
}
Ответ №1:
Похоже, что общая проблема в Frida заключается в том, что способ доступа к полям в Frida отличается.
Frida использует код JavaScript, поэтому он не может напрямую обрабатывать объекты, отличные от JavaScript. Поэтому он оборачивает «собственные» объекты (в данном случае объекты Android Java) в объекты JavaScript.
Если вы сейчас вызовете Frida this.carrier
, вы получите оболочку JavaScript Frida, а не экземпляр Java Carrier, на который вы нацелены.
Конечно, оболочка JavaScript Frida не имеет методов, которые вы пытаетесь вызвать, поэтому this.carrier.setId(123);
всегда будет терпеть неудачу.
Доступ к полю Java с помощью Frida
Чтобы получить доступ к полю, вам всегда нужно обращаться .value
к нему, чтобы получить фактическое значение:
Так что, если вы хотите this.carrier
, вы должны использовать this.carrier.value
.
Кроме того, рекомендуется обращаться к полю по его имени с дополнительным подчеркиванием впереди. В противном случае в запутанных приложениях может оказаться, что есть поле и метод с тем же именем. В таком случае Frida не знает, хотите ли вы получить доступ к полю carrier
или носителю метода.
Заключение если вы хотите получить доступ к полю экземпляра класса Java в приложении для Android с помощью Frida, рекомендуемый способ
this._carrier.value
Итак, для записи значения поля вы должны вызвать
this._carrier.value = ...
И то же самое для чтения.
Ссылка на страницы справки Frida
Это также описано на страницах Frida, например, здесь:
Обратите внимание, что мы используем
this.m.value = 0
вместоthis.m = 0
для установки значения поля. Если в этом классе также есть метод с именем m, нам нужно использоватьthis._m.value = 0
для установки значения поля m . В общем, при просмотре свойств объектов необходимо будет использовать.value
для доступа к значениям, на которые ссылаются эти поля.
Завершите упрощенный код
Но в вашем случае вы можете упростить все, просто используя локальную переменную:
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;
};
});