-
Notifications
You must be signed in to change notification settings - Fork 952
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
com.github.unidbg.arm.backend.BackendException: dvmObject="two", dvmClass=class java/lang/String, jmethodID=unidbg@0xffffffffd6cb375b #628
Comments
用ProxyDvmObject.createObject()创建 hashMap |
我就是这样创建的呀: HashMap<String,String> map = new HashMap<String,String>(){
{
put("1","one");
put("2","two");
}};
DvmObject<?> mapObject = ProxyDvmObject.createObject(vm, map); 如上述代码所示,是我理解的不对吗? |
最新进展,我通过将补环境修改为: @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 有文档吗? |
case "java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;": |
没有文档,就是网上找点入门资料学一学,然后有问题 下断跟到源码里看, |
再次修改:这样就可以通过 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 这个调用呢?不知道是否表达明确,期待您的解答!! |
你这样写不对,你这样return的是你的map,而这里要的是你的通过key拿到的value 你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 方法的写法中,我必须要向之前那种方式补环境才能正常运行,也就是返回 但是当时如果直接返回 现在修改 native 函数的写法后可以正常返回了,但觉得很神奇之前的必须要向我最初那么补环境才行。 ps:原来的 native 函数是chatgpt 生成的,也可以正常运行,就是补函数必须写成上述那种情况了。 |
感谢! |
chatgpt生成的这段代码,本身就有问题,自己要写写c代码,对用好unidbg有帮助,祝好 |
为 HashMap 补了一个环境后报错,说是 methodid问题?如何解决呢?
The text was updated successfully, but these errors were encountered: