1

我尝试使用 Frida 和位于 Android 虚拟设备(模拟)上的服务器读取堆上的内存,但一直出现内存access violation错误。

首先,我正在寻找一个有趣的类的实例:

Java.performNow(function() {
    Java.choose("com.example.model.interestingObject", {
        onMatch: function(instance) {
            console.log(instance.toString());                   
        }, onComplete: function() {
        }
    });
});

作为输出,我在内存中得到(我想)地址: com.example.model.interestingObject@d735e35

但是当我尝试从该地址读取时: Memory.readByteArray(ptr("0xd735e35"), 64);然后我收到以下错误:

Error: access violation accessing 0xd735e35
    at frida/runtime/core.js:282
    at /repl18.js:26

问题是,如何从该地址读取字节?我对弗里达很陌生,所以可能做错了什么。很高兴有任何帮助!

4

2 回答 2

1

查看 Java 函数Object.toString()可以看到该值d735e35不是地址而是对象的哈希码:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

因此,您正在查看导致access violation您观察到的错误内存地址。

一般来说,对于 Java/Android,您永远不应该尝试直接访问内存。改为使用 Frida 的可用函数来列出所有字段及其值。

于 2019-01-11T15:16:00.910 回答
1

我认为您只需要转换您找到的实例@onMatch

Java.cast(instance,Java.use("com.example.model.interestingObject")).toString()

文档中的其他一切都很好;

  • Java.choose(className, callbacks): 通过扫描 Java 堆枚举 className 类的活动实例,其中 callbacks 是一个对象,指定:

    • onMatch: function (instance): 为每个使用现成实例找到的活动实例调用一次,就像您使用该特定实例的原始句柄调用 Java.cast() 一样。该函数可能会返回字符串 stop 以提前取消枚举。

    • onComplete: function(): 枚举完所有实例后调用

要打印班级成员,您可以使用Object.getOwnPropertyNames(obj.__proto__).join('\n\t')

于 2019-01-21T09:35:35.177 回答