Frida - 访问具有所需类型的 class 属性
Frida - access to a class attribute that has the desired type
我有一个 android 程序被混淆了。并且在这个程序中 classes 具有同名的属性。
这样的反编译代码
public class d implements c
{
public int a;
public Cache$Entry a;
public Cache a;
public volatile a a;
public e a;
public ByteArrayOutputStream a;
public volatile AtomicBoolean a;
或者像这样的 smali 代码
# interfaces
.implements Le/a/x/c;
# instance fields
.field public a:I
.field public a:Lanetwork/channel/cache/Cache$Entry;
.field public a:Lanetwork/channel/cache/Cache;
.field public volatile a:Ld/a/w/a;
.field public a:Le/a/x/e;
.field public a:Ljava/io/ByteArrayOutputStream;
.field public volatile a:Ljava/util/concurrent/atomic/AtomicBoolean;
我创建了一个方法 asd() 的挂钩,我需要访问此 class 的属性 "a"。但是我需要类型为 "e.a.x.e"
的属性 "a"
Java.perform(function () {
var var_ddd = Java.use("e.a.x.d");
var_ddd.asd.implementation = function() {
this.asd();
console.log("e.a.x.d.asd()",Java.cast(this.a.value,Java.use("e.a.x.e")));
};
});
当我尝试写入 this.a.value 时 - 我得到了一个错误的属性。
当我写 Java.cast(this.a.value,Java.use("e.a.x.e"))
我收到消息
TypeError: cannot read property 'hasOwnProperty' of undefined
请告诉我如何获得正确类型的正确属性
如果方法和同名字段之间存在冲突,Frida 内置了解决方法:在字段名称前加上下划线:_a
.
If there is a name collision, method & member has the same name, an underscore will be added to member.
但我不确定此信息是否仍然有效。当前的 Frida Java 桥代码不喜欢它会重命名具有冲突字段名称的字段:https://github.com/frida/frida-java-bridge/blob/master/lib/class-factory.js#L301
我也没有看到一种以不基于名称的方式访问 Frida 中的字段的方法。
我看到的唯一机会是通过 Java 反射访问该字段:
const eaxe = Java.use("e.a.x.e");
for (f of eaxe.class.getDeclaredFields()) {
if (f.getType().getName() == "e.a.x.e") {
f.setAccessible(true);
var fieldValue = f.get(this);
console.log("Field of type e.a.x.e has value: " + fieldValue);
}
}
注意:以上代码尚未在 Frida 中进行测试,因此在实际运行之前可能需要进一步完善。
感谢 Robert,解决方案是 found.The 对代码进行了小幅修正
var lo_fld_eaxe;
var lv_found = false;
var lt_fields = this.getClass().getDeclaredFields();
for (var i = 0; i < lt_fields.length && lv_found == false; i++) {
if(lt_fields[i].getName().toString() == 'a' && lt_fields[i].getType().getName().toString() == 'e.a.x.e' ){
lo_fld_eaxe = lt_fields[i];
lv_found = true;
}
}
if(lv_found == true) {
lo_fld_eaxe.setAccessible(true);
try{
var lv_e_a_x_e = lo_fld_eaxe.get(this);
}
catch(err){
console.log("Error:"+err);
}
}
我有一个 android 程序被混淆了。并且在这个程序中 classes 具有同名的属性。 这样的反编译代码
public class d implements c
{
public int a;
public Cache$Entry a;
public Cache a;
public volatile a a;
public e a;
public ByteArrayOutputStream a;
public volatile AtomicBoolean a;
或者像这样的 smali 代码
# interfaces
.implements Le/a/x/c;
# instance fields
.field public a:I
.field public a:Lanetwork/channel/cache/Cache$Entry;
.field public a:Lanetwork/channel/cache/Cache;
.field public volatile a:Ld/a/w/a;
.field public a:Le/a/x/e;
.field public a:Ljava/io/ByteArrayOutputStream;
.field public volatile a:Ljava/util/concurrent/atomic/AtomicBoolean;
我创建了一个方法 asd() 的挂钩,我需要访问此 class 的属性 "a"。但是我需要类型为 "e.a.x.e"
的属性 "a"Java.perform(function () {
var var_ddd = Java.use("e.a.x.d");
var_ddd.asd.implementation = function() {
this.asd();
console.log("e.a.x.d.asd()",Java.cast(this.a.value,Java.use("e.a.x.e")));
};
});
当我尝试写入 this.a.value 时 - 我得到了一个错误的属性。 当我写 Java.cast(this.a.value,Java.use("e.a.x.e")) 我收到消息
TypeError: cannot read property 'hasOwnProperty' of undefined
请告诉我如何获得正确类型的正确属性
如果方法和同名字段之间存在冲突,Frida 内置了解决方法:在字段名称前加上下划线:_a
.
If there is a name collision, method & member has the same name, an underscore will be added to member.
但我不确定此信息是否仍然有效。当前的 Frida Java 桥代码不喜欢它会重命名具有冲突字段名称的字段:https://github.com/frida/frida-java-bridge/blob/master/lib/class-factory.js#L301
我也没有看到一种以不基于名称的方式访问 Frida 中的字段的方法。
我看到的唯一机会是通过 Java 反射访问该字段:
const eaxe = Java.use("e.a.x.e");
for (f of eaxe.class.getDeclaredFields()) {
if (f.getType().getName() == "e.a.x.e") {
f.setAccessible(true);
var fieldValue = f.get(this);
console.log("Field of type e.a.x.e has value: " + fieldValue);
}
}
注意:以上代码尚未在 Frida 中进行测试,因此在实际运行之前可能需要进一步完善。
感谢 Robert,解决方案是 found.The 对代码进行了小幅修正
var lo_fld_eaxe;
var lv_found = false;
var lt_fields = this.getClass().getDeclaredFields();
for (var i = 0; i < lt_fields.length && lv_found == false; i++) {
if(lt_fields[i].getName().toString() == 'a' && lt_fields[i].getType().getName().toString() == 'e.a.x.e' ){
lo_fld_eaxe = lt_fields[i];
lv_found = true;
}
}
if(lv_found == true) {
lo_fld_eaxe.setAccessible(true);
try{
var lv_e_a_x_e = lo_fld_eaxe.get(this);
}
catch(err){
console.log("Error:"+err);
}
}