diff options
Diffstat (limited to 'src/cuchaz/enigma/bytecode')
| -rw-r--r-- | src/cuchaz/enigma/bytecode/InnerClassWriter.java | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/src/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/cuchaz/enigma/bytecode/InnerClassWriter.java index d4abe4e..b0e33ac 100644 --- a/src/cuchaz/enigma/bytecode/InnerClassWriter.java +++ b/src/cuchaz/enigma/bytecode/InnerClassWriter.java | |||
| @@ -14,6 +14,7 @@ import java.util.Collection; | |||
| 14 | 14 | ||
| 15 | import javassist.CtClass; | 15 | import javassist.CtClass; |
| 16 | import javassist.bytecode.AccessFlag; | 16 | import javassist.bytecode.AccessFlag; |
| 17 | import javassist.bytecode.ConstPool; | ||
| 17 | import javassist.bytecode.Descriptor; | 18 | import javassist.bytecode.Descriptor; |
| 18 | import javassist.bytecode.InnerClassesAttribute; | 19 | import javassist.bytecode.InnerClassesAttribute; |
| 19 | import cuchaz.enigma.analysis.JarIndex; | 20 | import cuchaz.enigma.analysis.JarIndex; |
| @@ -29,21 +30,33 @@ public class InnerClassWriter | |||
| 29 | m_deobfuscatingTranslator = deobfuscatingTranslator; | 30 | m_deobfuscatingTranslator = deobfuscatingTranslator; |
| 30 | m_jarIndex = jarIndex; | 31 | m_jarIndex = jarIndex; |
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | public void writeInnerClasses( CtClass c ) | 34 | public void write( CtClass c ) |
| 34 | { | 35 | { |
| 35 | // is this an outer class with inner classes? | 36 | // get the outer class name |
| 36 | String obfOuterClassName = Descriptor.toJvmName( c.getName() ); | 37 | String obfClassName = Descriptor.toJvmName( c.getName() ); |
| 38 | String obfOuterClassName = m_jarIndex.getOuterClass( obfClassName ); | ||
| 39 | if( obfOuterClassName == null ) | ||
| 40 | { | ||
| 41 | // this is an outer class | ||
| 42 | obfOuterClassName = obfClassName; | ||
| 43 | } | ||
| 44 | else | ||
| 45 | { | ||
| 46 | // this is an inner class, rename it to outer$inner | ||
| 47 | c.setName( obfOuterClassName + "$" + obfClassName ); | ||
| 48 | } | ||
| 49 | |||
| 50 | // write the inner classes if needed | ||
| 37 | Collection<String> obfInnerClassNames = m_jarIndex.getInnerClasses( obfOuterClassName ); | 51 | Collection<String> obfInnerClassNames = m_jarIndex.getInnerClasses( obfOuterClassName ); |
| 38 | if( obfInnerClassNames != null && !obfInnerClassNames.isEmpty() ) | 52 | if( obfInnerClassNames != null ) |
| 39 | { | 53 | { |
| 40 | writeInnerClasses( c, obfInnerClassNames ); | 54 | writeInnerClasses( c, obfOuterClassName, obfInnerClassNames ); |
| 41 | } | 55 | } |
| 42 | } | 56 | } |
| 43 | 57 | ||
| 44 | private void writeInnerClasses( CtClass c, Collection<String> obfInnerClassNames ) | 58 | private void writeInnerClasses( CtClass c, String obfOuterClassName, Collection<String> obfInnerClassNames ) |
| 45 | { | 59 | { |
| 46 | String obfOuterClassName = Descriptor.toJvmName( c.getName() ); | ||
| 47 | InnerClassesAttribute attr = new InnerClassesAttribute( c.getClassFile().getConstPool() ); | 60 | InnerClassesAttribute attr = new InnerClassesAttribute( c.getClassFile().getConstPool() ); |
| 48 | c.getClassFile().addAttribute( attr ); | 61 | c.getClassFile().addAttribute( attr ); |
| 49 | for( String obfInnerClassName : obfInnerClassNames ) | 62 | for( String obfInnerClassName : obfInnerClassNames ) |
| @@ -54,26 +67,37 @@ public class InnerClassWriter | |||
| 54 | { | 67 | { |
| 55 | deobfOuterClassName = obfOuterClassName; | 68 | deobfOuterClassName = obfOuterClassName; |
| 56 | } | 69 | } |
| 57 | String deobfInnerClassName = m_deobfuscatingTranslator.translateClass( obfInnerClassName ); | 70 | String obfOuterInnerClassName = obfOuterClassName + "$" + obfInnerClassName; |
| 58 | if( deobfInnerClassName == null ) | 71 | String deobfOuterInnerClassName = m_deobfuscatingTranslator.translateClass( obfOuterInnerClassName ); |
| 72 | if( deobfOuterInnerClassName == null ) | ||
| 73 | { | ||
| 74 | deobfOuterInnerClassName = obfOuterInnerClassName; | ||
| 75 | } | ||
| 76 | String deobfInnerClassName = deobfOuterInnerClassName.substring( deobfOuterInnerClassName.lastIndexOf( '$' ) + 1 ); | ||
| 77 | |||
| 78 | // here's what the JVM spec says about the InnerClasses attribute | ||
| 79 | // append( inner, outer of inner if inner is member of outer 0 ow, name after $ if inner not anonymous 0 ow, flags ); | ||
| 80 | |||
| 81 | // update the attribute with this inner class | ||
| 82 | ConstPool constPool = c.getClassFile().getConstPool(); | ||
| 83 | int innerClassIndex = constPool.addClassInfo( deobfOuterInnerClassName ); | ||
| 84 | int outerClassIndex = 0; | ||
| 85 | int innerClassSimpleNameIndex = 0; | ||
| 86 | if( !m_jarIndex.isAnonymousClass( obfInnerClassName ) ) | ||
| 59 | { | 87 | { |
| 60 | deobfInnerClassName = obfInnerClassName; | 88 | outerClassIndex = constPool.addClassInfo( deobfOuterClassName ); |
| 89 | innerClassSimpleNameIndex = constPool.addUtf8Info( deobfInnerClassName ); | ||
| 61 | } | 90 | } |
| 62 | 91 | ||
| 63 | // update the attribute | ||
| 64 | String deobfOuterInnerClassName = deobfOuterClassName + "$" + deobfInnerClassName; | ||
| 65 | attr.append( | 92 | attr.append( |
| 66 | deobfOuterInnerClassName, | 93 | innerClassIndex, |
| 67 | deobfOuterClassName, | 94 | outerClassIndex, |
| 68 | deobfInnerClassName, | 95 | innerClassSimpleNameIndex, |
| 69 | c.getClassFile().getAccessFlags() & ~AccessFlag.SUPER | 96 | c.getClassFile().getAccessFlags() & ~AccessFlag.SUPER |
| 70 | ); | 97 | ); |
| 71 | 98 | ||
| 72 | // make sure the outer class references only the new inner class names | 99 | // make sure the outer class references only the new inner class names |
| 73 | c.replaceClassName( obfInnerClassName, deobfOuterInnerClassName ); | 100 | c.replaceClassName( obfInnerClassName, deobfOuterInnerClassName ); |
| 74 | |||
| 75 | // TEMP | ||
| 76 | System.out.println( "\tInner " + obfInnerClassName + " -> " + deobfOuterInnerClassName ); | ||
| 77 | } | 101 | } |
| 78 | } | 102 | } |
| 79 | } | 103 | } |