Java Class.forName和模糊名称,java无法找到类

时间:2015-02-15 14:41:46

标签: java class reflection obfuscation deobfuscation

我的.jar文件没有常见的混淆名称,混淆的类看起来像:
nul.goto. ...\\.. .final.(注意:第一个间隙不是正常空间,它是不间断空间)
我不能通过Class.forName

获得这个课程 我使用这样的混淆来制作我自己的代码版本,即使我使用Class.forName(SomeClass.class.getName())(它只是代码来测试)也不起作用,在混淆之后java会抛出无法找到这个类的错误。<登记/>
如何上课?

1 个答案:

答案 0 :(得分:0)

所以一段时间后,我决定回到这一点,我使用了如下代码进行测试:
A B C D e -1.393951 -0.725751 -1.063748 -0.271371

pckg.Main

被ProGuard迷惑:

public static void main(String[] args) {
    Class<ObfuscateMe> obfuscateMeClass = ObfuscateMe.class;
    System.out.println("Class name: `" + obfuscateMeClass + "`");
    try {
        System.out.println("Class.forName: " + Class.forName(obfuscateMeClass.getName()));
    }
    catch (ClassNotFoundException exception) { System.out.println("Can't find class using Class.forName: `" + obfuscateMeClass.getName() + "`"); }
    try {
        System.out.println("ClassLoader.loadClass: " + Main.class.getClassLoader().loadClass(obfuscateMeClass.getName()));
    }
    catch (ClassNotFoundException exception) { System.out.println("Can't find class using ClassLoader.loadClass: `" + obfuscateMeClass.getName() + "`"); }
}

首先,我注意到这不再是Java 11中的问题:像这样的类将无法加载并显示错误:

-injars 'B:\Java\ProGuardTestApp\test.jar'
-outjars 'B:\Java\ProGuardTestApp\testObf.jar'
-dontshrink
-dontoptimize
-classobfuscationdictionary 'B:\Java\ProGuardTestApp\obfs.txt' # contains just one line "final"
-repackageclasses 'nul.goto. ...\\.. .final.'
-ignorewarnings
-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}

但是Error: LinkageError occurred while loading main class pckg.Main java.lang.ClassFormatError: Illegal class name "nul/goto/▒///\\// /final//final" in class file pckg/Main forName之间仍然存在不一致,loadClass仍然会抛出forName,而ClassNotFoundException会抛出loadClass。在这两种情况下,OpenJ9都抛出ClassFormatError

在Java 8热点上它可以正常工作,就像@Holger在注释中建议的那样,使用ClassLoader的版本也可以正常工作。所以我决定去挖掘一下原因。 在类加载器中,它只是转到ClassFormatErrorURLClassLoader中的一段非常简单的代码,并通过本机方法name.replace('.', '/').concat(".class");从jar加载该类而没有任何问题。
但是defineClass直接进入本机方法并验证类名称:http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/native/java/lang/Class.c

Class.forName

因此所有if (VerifyFixClassname(clname) == JNI_TRUE) { /* slashes present in clname, use name b4 translation for exception */ (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname); JNU_ThrowClassNotFoundException(env, clname); goto done; } if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */ JNU_ThrowClassNotFoundException(env, clname); goto done; } 都更改为.,然后在/中我们可以找到它:

VerifyClassname

src:http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/native/common/check_format.c#l155

这会阻止类的加载。