Estoy conectando una determinada función en Frida que usa el código:
this.carrier.getId()
Sin embargo, en este momento this.carrier aún no se ha configurado, lo que hace que la aplicación se bloquee.
Así que estoy pensando en configurar manualmente este miembro en la función actual de la clase. Entonces ese transportista existirá en el momento en que se produzca el código.
El problema es que encuentro un problema al hacer eso.
Hasta ahora esto es lo que tengo:
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 }; });
Código de transportista:
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; } }
Parece que el problema común en Frida es que la forma de acceder a los campos es diferente en Frida.
Frida usa código JavaScript, por lo que no puede manejar objetos que no sean JavaScript directamente. Por lo tanto, envuelve objetos "nativos" (objetos Android Java en este caso) en objetos JavaScript.
Si ahora llama a Frida this.carrier
, obtendrá el contenedor de JavaScript de Frida, no la instancia de Java Carrier a la que apunta.
Por supuesto, el contenedor Frida JavaScript no tiene los métodos que intenta llamar, por lo tanto, this.carrier.setId(123);
siempre fallará.
Para acceder a un campo, siempre debe llamar a .value
para obtener el valor real:
Entonces, si desea this.carrier
, debe usar this.carrier.value
.
Además, se recomienda acceder a un campo por su nombre con un guión bajo adicional al frente. De lo contrario, en aplicaciones ofuscadas, puede ocurrir que haya un campo y un método con el mismo nombre. En tal caso, Frida no sabe si desea acceder al carrier
de campo o al portador de método.
Conclusión si desea acceder a un campo de una instancia de clase Java en una aplicación de Android usando Frida, la forma recomendada es
this._carrier.value
Entonces, para escribir un valor de campo, debe llamar
this._carrier.value = ...
Y lo mismo para la lectura.
Esto también se describe en las páginas de Frida, por ejemplo, aquí :
Tenga en cuenta que usamos
this.m.value = 0
en lugar dethis.m = 0
para establecer el valor del campo. Si también hay un método en esta clase llamado m, necesitamos usarthis._m.value = 0
para establecer el valor del campo m. En general, al mirar las propiedades de los objetos, será necesario usar.value
para acceder a los valores a los que se refieren esos campos.
Pero en tu caso puedes simplificar todo simplemente usando una variable local:
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; }; });