GithubHelp home page GithubHelp logo

com.github.unidbg.arm.backend.BackendException: dvmObject="two", dvmClass=class java/lang/String, jmethodID=unidbg@0xffffffffd6cb375b about unidbg HOT 11 OPEN

HappyTsing avatar HappyTsing commented on July 17, 2024
com.github.unidbg.arm.backend.BackendException: dvmObject="two", dvmClass=class java/lang/String, jmethodID=unidbg@0xffffffffd6cb375b

from unidbg.

Comments (11)

ddzgy avatar ddzgy commented on July 17, 2024

用ProxyDvmObject.createObject()创建 hashMap

from unidbg.

HappyTsing avatar HappyTsing commented on July 17, 2024

用ProxyDvmObject.createObject()创建 hashMap

我就是这样创建的呀:

HashMap<String,String> map = new HashMap<String,String>(){
{
        put("1","one");
        put("2","two");
}};
DvmObject<?> mapObject = ProxyDvmObject.createObject(vm, map);

如上述代码所示,是我理解的不对吗?

from unidbg.

HappyTsing avatar HappyTsing commented on July 17, 2024

最新进展,我通过将补环境修改为:

 @Override
    public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
        switch (signature) {
            case "java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;":
                return dvmObject; // get 方法为什么要返回 dvmObject,而不是 Map 中取出的 value 呢?
            case "java/lang/Object->toString()Ljava/lang/String;":
                Map map = (Map) dvmObject.getValue();
//                Object key = vaList.getObjectArg(0).getValue(); // 现在拿不到 key了,怎么从 map 中取出值啊
                return new StringObject(vm, "mapValue");
		}
		return super.callObjectMethodV(vm, dvmObject, signature, vaList);
}

现在程序可以正常运行并输出 “mapValue”,但这并不是真实的值呀,理论上我的key=“2”,应该输出value=“two” ,如何做到?

现在有几个疑问,写在注释里了,有人能解答一下嘛?

我的 native 方法是:

public native String javaCallC(String key, HashMap<String, String> hashMap);

方法的实现就是通过传入的 id,从 Map 中拿出 value。如何通过 unidbg 调用该方法,并传入一个 hashmap,通过 key,获取 map 中的 value 呢?

另外:unidbg 有文档吗?

from unidbg.

ddzgy avatar ddzgy commented on July 17, 2024

case "java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;":
return dvmObject; // get 方法为什么要返回 dvmObject,而不是 Map 中取出的 value 呢?
unidbg不知道你map里存的键值对是什么,所以用基类java/lang/Object代指
实际你返回的就是你取出的value,
Map map = (Map) dvmObject.getValue();
String key =(String) vaList.getObjectArg(0).getValue();
reture ProxyDvmObject.createObject(vm, map.get(key));

from unidbg.

ddzgy avatar ddzgy commented on July 17, 2024

没有文档,就是网上找点入门资料学一学,然后有问题 下断跟到源码里看,
我觉得unidbg真是大杀器,我都想去录门课普及普及

from unidbg.

HappyTsing avatar HappyTsing commented on July 17, 2024

case "java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;": return dvmObject; // get 方法为什么要返回 dvmObject,而不是 Map 中取出的 value 呢? unidbg不知道你map里存的键值对是什么,所以用基类java/lang/Object代指 实际你返回的就是你取出的value, Map map = (Map) dvmObject.getValue(); String key =(String) vaList.getObjectArg(0).getValue(); reture ProxyDvmObject.createObject(vm, map.get(key));

再次修改:这样就可以通过 key 获取 value 了。

String key = "";
    @Override
    public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
        switch (signature) {
            case "java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;": // case1 获取 key,但是返回 dvmObject
                System.out.println(vaList.getObjectArg(0));
                key = (String) vaList.getObjectArg(0).getValue();
                return dvmObject;
            case "java/lang/Object->toString()Ljava/lang/String;": // case2 中再取出值。
                Map map = (Map) dvmObject.getValue();
                return ProxyDvmObject.createObject(vm, map.get(key));
        }
        return super.callObjectMethodV(vm, dvmObject, signature, vaList);
    }

疑惑的点在于 case1 就应该直接返回值呀,因为我补的是 map.get() 方法。

extern "C" JNIEXPORT jstring JNICALL
Java_com_wang_sotest_MainActivity_javaCallC(
        JNIEnv* env,
        jobject /* this */,
        jstring id,
        jobject map) {

        // 获取Map类的Class引用
        jclass mapClass = env->FindClass("java/util/HashMap");
        // 获取Map.get方法的Method ID
        jmethodID mapGet = env->GetMethodID(mapClass, "get",
                                            "(Ljava/lang/Object;)Ljava/lang/Object;");
        // 调用Map.get方法
        jobject value = env->CallObjectMethod(map, mapGet, id);

        // 将value转换为字符串
        jclass objectClass = env->FindClass("java/lang/Object");
        jmethodID toStringMethod = env->GetMethodID(objectClass, "toString", "()Ljava/lang/String;");
        jstring valueString = (jstring)env->CallObjectMethod(value, toStringMethod);
        printf("Java_com_wang_sotest_MainActivity_javaCallC is called");
        return valueString;
}

这是我的 native 方法的实现。所以我怀疑我补的是不是获取 methodid 的这个方法,而并非 map.get 这个调用呢?不知道是否表达明确,期待您的解答!!

from unidbg.

ddzgy avatar ddzgy commented on July 17, 2024
        case "java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;": // case1 获取 key,但是返回 dvmObject
            System.out.println(vaList.getObjectArg(0));
            key = (String) vaList.getObjectArg(0).getValue();
            return dvmObject;

你这样写不对,你这样return的是你的map,而这里要的是你的通过key拿到的value
你首先要明白他为什么写成"java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;" 这样:
1.java标准中 map.get()就是这么定义的,而且你c代码也是这样写的呀:
jmethodID mapGet = env->GetMethodID(mapClass, "get",
"(Ljava/lang/Object;)Ljava/lang/Object;");
// 调用Map.get方法
jobject value = env->CallObjectMethod(map, mapGet, id);
2、unidbg不知道你的map里存的是什么,map可以存任何东西,所以他也是在用java/lang/Object来代指子类。举个例子,你如果把你的map改成value 是int类型,他也是这样的。为啥?因为他不知道你的value具体类型,所以只能用object代指所有,你实际分析的是啥就给她啥

你c里写的后面我有点不懂,你为啥要拿java/lang/Object tostring,hashmap本身已经重写了 tostring了,你要调用基类的 tostring吗?

from unidbg.

ddzgy avatar ddzgy commented on July 17, 2024

你要不留个联系方式,我跟你说下,这好像也说不太清楚

from unidbg.

HappyTsing avatar HappyTsing commented on July 17, 2024
        case "java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;": // case1 获取 key,但是返回 dvmObject
            System.out.println(vaList.getObjectArg(0));
            key = (String) vaList.getObjectArg(0).getValue();
            return dvmObject;

你这样写不对,你这样return的是你的map,而这里要的是你的通过key拿到的value 你首先要明白他为什么写成"java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;" 这样: 1.java标准中 map.get()就是这么定义的,而且你c代码也是这样写的呀: jmethodID mapGet = env->GetMethodID(mapClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); // 调用Map.get方法 jobject value = env->CallObjectMethod(map, mapGet, id); 2、unidbg不知道你的map里存的是什么,map可以存任何东西,所以他也是在用java/lang/Object来代指子类。举个例子,你如果把你的map改成value 是int类型,他也是这样的。为啥?因为他不知道你的value具体类型,所以只能用object代指所有,你实际分析的是啥就给她啥

你c里写的后面我有点不懂,你为啥要拿java/lang/Object tostring,hashmap本身已经重写了 tostring了,你要调用基类的 tostring吗?

我按照你说的修改了我的native方法:

extern "C" JNIEXPORT jstring JNICALL
Java_com_wang_sotest_MainActivity_javaCallC(
        JNIEnv* env,
        jobject /* this */,
        jstring id,
        jobject map) {

        // 获取Map类的Class引用
        jclass mapClass = env->FindClass("java/util/HashMap");
        // 获取Map.get方法的Method ID
        jmethodID mapGet = env->GetMethodID(mapClass, "get",
                                            "(Ljava/lang/Object;)Ljava/lang/Object;");
        // 调用Map.get方法
        jobject value = env->CallObjectMethod(map, mapGet, id);
        printf("Java_com_wang_sotest_MainActivity_javaCallC is called");
        return (jstring) value;
}

现在我的补环境如下:

@Override
    public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
        switch (signature) {
            case "java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;":
                System.out.println("key is: " + vaList.getObjectArg(0));
                String key = (String) vaList.getObjectArg(0).getValue();
                Map map = (Map) dvmObject.getValue();
                return ProxyDvmObject.createObject(vm, map.get(key));
        }
        return super.callObjectMethodV(vm, dvmObject, signature, vaList);
    }

可以正常运行了。
但是 ============ 分割线 =============

在原来的版本的 native 方法的写法中,我必须要向之前那种方式补环境才能正常运行,也就是返回 dvmObject 这也是我之前一直疑惑的点,我也觉得应该直接返回 map.get 的结果。

但是当时如果直接返回 return ProxyDvmObject.createObject(vm, map.get(key)); 的话,就会报 methodid 报错。

现在修改 native 函数的写法后可以正常返回了,但觉得很神奇之前的必须要向我最初那么补环境才行。

ps:原来的 native 函数是chatgpt 生成的,也可以正常运行,就是补函数必须写成上述那种情况了。

from unidbg.

HappyTsing avatar HappyTsing commented on July 17, 2024

你要不留个联系方式,我跟你说下,这好像也说不太清楚

我的 qq 是 593768341,感谢!

from unidbg.

ddzgy avatar ddzgy commented on July 17, 2024

chatgpt生成的这段代码,本身就有问题,自己要写写c代码,对用好unidbg有帮助,祝好

from unidbg.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.