Code Monkey home page Code Monkey logo

Comments (11)

ddzgy avatar ddzgy commented on August 27, 2024

用ProxyDvmObject.createObject()创建 hashMap

from unidbg.

HappyTsing avatar HappyTsing commented on August 27, 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 August 27, 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 August 27, 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 August 27, 2024

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

from unidbg.

HappyTsing avatar HappyTsing commented on August 27, 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 August 27, 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 August 27, 2024

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

from unidbg.

HappyTsing avatar HappyTsing commented on August 27, 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 August 27, 2024

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

我的 qq 是 593768341,感谢!

from unidbg.

ddzgy avatar ddzgy commented on August 27, 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.