jOOR
jOOR copied to clipboard
Working with Obfuscation - Duplicate Names
Versions:
- jOOR: for Java 8+
- Java: 8
Reflection is actually helpful most of the time, even with obfuscation, but there is a problem while working against obfuscation. Some obfuscators make member names duplicate so we can't directly access it just by giving the name and maybe arguments. As an example, this is allowed at both compile time and runtime:
public void foo(String str) {
System.out.println(str);
}
public void foo() {
System.out.println("Legit");
}
public void random() {
this.foo();
this.foo("Legit");
}
This example is not allowed at compile time but allowed at runtime:
public int duplicate() {
return 0;
}
public String duplicate() {
return "Duplicate";
}
public void random() {
int i = this.duplicate(); //INVOKEVIRTUAL randomPackage/randomClass.duplicate()I
String str = this.duplicate(); //INVOKEVIRTUAL randomPackage/randomClass.duplicate()Ljava/lang/String;
}
There should be some additional methods that considers return types to fully recognize method signatures (name
and description
) to solve this problem.
By the way I am not talking about runtime compilation, this issue is about calling duplicate methods
Yes, we could do that at some point, also to call bridge methods explicitly for whatever reason. In the meantime, you can try to look up the Method
by iterating Class.getMethods()
I didn't tested this code yet but this would do the job
public Reflect callDuplicate(Class<?> returnType, String name, Object... args) throws ReflectException {
Class<?>[] types = types(args);
try {
Method method = duplicateMethod(returnType, name, types);
return on(method, object, args);
} catch (NoSuchMethodException e) {
throw new ReflectException(e);
}
}
private Method duplicateMethod(Class<?> returnType, String name, Class<?>[] types) throws NoSuchMethodException {
Class<?> t = type();
for(Method method : t.getMethods()) {
if (method.getName().equals(name) &&
method.getReturnType().equals(returnType) &&
Arrays.equals(method.getParameterTypes(), types))
{
return method;
}
}
do {
for(Method method : t.getDeclaredMethods()) {
if (method.getName().equals(name) &&
method.getReturnType().equals(returnType) &&
Arrays.equals(method.getParameterTypes(), types))
{
return method;
}
}
t = t.getSuperclass();
}
while (t != null);
throw new NoSuchMethodException();
}
onClass("randomPackage.randomClass")
.create()
.callDuplicate(int.class, "duplicate")
.get();
onClass("randomPackage.randomClass")
.create()
.callDuplicate(String.class, "duplicate")
.get();
Please double check the code if you want to commit, i am kinda sleepy and not sure about this code
Sure, but then again "at some point" means that I really wouldn't want to rush adding API for such a rare edge case. It is extremely rare having to call an overload-by-return-type on the JVM, let alone having to call it via reflection.
I don't think such a feature will make it into this library very soon.