summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/bytecode
diff options
context:
space:
mode:
authorGravatar hg2014-08-17 10:56:17 -0400
committerGravatar hg2014-08-17 10:56:17 -0400
commit6c4440ac1133bfaa7871d1049d174528a289ef30 (patch)
treefe1142b285c5e43dbd3afe8dd3eb0189f027c6a6 /src/cuchaz/enigma/bytecode
parenttrying to get inner/anonymous classes working... I have a working heuristic i... (diff)
downloadenigma-fork-6c4440ac1133bfaa7871d1049d174528a289ef30.tar.gz
enigma-fork-6c4440ac1133bfaa7871d1049d174528a289ef30.tar.xz
enigma-fork-6c4440ac1133bfaa7871d1049d174528a289ef30.zip
added support for automatic reconstruction of inner and anonymous classes
also added class to restore bridge method flags taken out by the obfuscator
Diffstat (limited to 'src/cuchaz/enigma/bytecode')
-rw-r--r--src/cuchaz/enigma/bytecode/InnerClassWriter.java64
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
15import javassist.CtClass; 15import javassist.CtClass;
16import javassist.bytecode.AccessFlag; 16import javassist.bytecode.AccessFlag;
17import javassist.bytecode.ConstPool;
17import javassist.bytecode.Descriptor; 18import javassist.bytecode.Descriptor;
18import javassist.bytecode.InnerClassesAttribute; 19import javassist.bytecode.InnerClassesAttribute;
19import cuchaz.enigma.analysis.JarIndex; 20import 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}