Skip to content
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

Working with Obfuscation - Duplicate Names #113

Open
MizzMaster opened this issue Mar 18, 2021 · 3 comments
Open

Working with Obfuscation - Duplicate Names #113

MizzMaster opened this issue Mar 18, 2021 · 3 comments

Comments

@MizzMaster
Copy link

MizzMaster commented Mar 18, 2021

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

@lukaseder
Copy link
Member

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()

@MizzMaster
Copy link
Author

MizzMaster commented Mar 18, 2021

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

@lukaseder
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants