Command `is` gives inaccurate information for methods in APK
Hi, there. I recently found the is command gives incomplete return types for some methods in APKs. Since that information may mislead the user to incorrect classes, I think it could be considered an issue.
Work environment
| Questions | Answers |
|---|---|
| OS/arch/bits (mandatory) | Ubuntu 22.04 |
| File format of the file you reverse (mandatory) | APK |
| Architecture/bits of the file (mandatory) | Dalvik |
rizin -v full output, not truncated (mandatory) |
rizin 0.4.0 @ linux-x86-64 commit: 0950e823a4502677cbf77cfd0266e8de64875fc0, build: 2022-05-30__05:44:10 |
Expected behavior
Command is gives the return type and parameters of a method in full.
Actual behavior
Command is truncates the return type or parameters of some methods.
For example, according to the dexs command, we find the method Lokhttp3/internal/platform/OptionalMethod; getMethod in this APK has a return type Ljava/lang/reflect/Method;.
[0x100041174]> dexs
...
#1 : (in Lokhttp3/internal/platform/OptionalMethod;)
name : 'getMethod'
type : '(Ljava/lang/Class;)Ljava/lang/reflect/Method;'
access : 0x0002 (PRIVATE)
method_idx : 2768
code : (available)
...
However, command is shows that the method returns an object of reflect.Method.
[0x100041174]> is~2768
2768 0x000697c8 0x1000697c8 LOCAL METH 66 okhttp3.internal.platform.OptionalMethod reflect.Method getMethod(Class)
The is command seems to remove the java.lang part from the return type. However, the binary may already have another class named reflect.Method.Thus, this inaccurate output might mislead the user to the incorrect one. I think it could be considered an issue.
Steps to reproduce the behavior
- Open this sample with Rizin.
- Run the following commands.
aaa
is~2768
After tracing the code, I found the issue probably originated from the Java demangler in rz_libdemangle. Moreover, it seems like the demangler tries to remove any "java/lang" strings from a mangled method.
Here is part of the code of the demangler (link). The full name of the method (the name, the arguments, and the return type) will be passed in as a string named mangled. And we can see the deletion behavior in line 274 below.
char *libdemangle_handler_java(const char *mangled) {
if (!mangled) {
return NULL;
}
char *name = NULL;
char *arguments = NULL;
char *return_type = NULL;
name = strdup(mangled);
if (!name) {
return NULL;
}
name = dem_str_replace(name, "java/lang/", "", 1); // <--- Line 274
if ((arguments = strchr(name, '(')) && (return_type = strchr(arguments, ')'))) {
return demangle_method(name, arguments, return_type);
} else if (name[0] == 'L' && (arguments = strchr(name, '.'))) {
return demangle_class_object(name, arguments);
} else if ((arguments = strchr(name, '.'))) {
return demangle_object_with_type(name, arguments);
}
return demangle_any(name);
}
Besides, after using gdb, I also confirm that the issue happened in this function.

@haeter525 this should be fixed, right?
@wargio Yes. Fixed in v0.4.1. I'm going to close this issue. Thanks!