summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/bytecode/InnerClassWriter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/bytecode/InnerClassWriter.java')
-rw-r--r--src/cuchaz/enigma/bytecode/InnerClassWriter.java103
1 files changed, 39 insertions, 64 deletions
diff --git a/src/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/cuchaz/enigma/bytecode/InnerClassWriter.java
index 5e59307..f52c31a 100644
--- a/src/cuchaz/enigma/bytecode/InnerClassWriter.java
+++ b/src/cuchaz/enigma/bytecode/InnerClassWriter.java
@@ -23,105 +23,80 @@ import cuchaz.enigma.analysis.JarIndex;
23import cuchaz.enigma.mapping.BehaviorEntry; 23import cuchaz.enigma.mapping.BehaviorEntry;
24import cuchaz.enigma.mapping.ClassEntry; 24import cuchaz.enigma.mapping.ClassEntry;
25 25
26public class InnerClassWriter 26public class InnerClassWriter {
27{ 27
28 private JarIndex m_jarIndex; 28 private JarIndex m_jarIndex;
29 29
30 public InnerClassWriter( JarIndex jarIndex ) 30 public InnerClassWriter(JarIndex jarIndex) {
31 {
32 m_jarIndex = jarIndex; 31 m_jarIndex = jarIndex;
33 } 32 }
34 33
35 public void write( CtClass c ) 34 public void write(CtClass c) {
36 { 35
37 // is this an inner or outer class? 36 // is this an inner or outer class?
38 String obfInnerClassName = new ClassEntry( Descriptor.toJvmName( c.getName() ) ).getSimpleName(); 37 String obfInnerClassName = new ClassEntry(Descriptor.toJvmName(c.getName())).getSimpleName();
39 String obfOuterClassName = m_jarIndex.getOuterClass( obfInnerClassName ); 38 String obfOuterClassName = m_jarIndex.getOuterClass(obfInnerClassName);
40 if( obfOuterClassName == null ) 39 if (obfOuterClassName == null) {
41 {
42 // this is an outer class 40 // this is an outer class
43 obfOuterClassName = Descriptor.toJvmName( c.getName() ); 41 obfOuterClassName = Descriptor.toJvmName(c.getName());
44 } 42 } else {
45 else
46 {
47 // this is an inner class, rename it to outer$inner 43 // this is an inner class, rename it to outer$inner
48 ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + obfInnerClassName ); 44 ClassEntry obfClassEntry = new ClassEntry(obfOuterClassName + "$" + obfInnerClassName);
49 c.setName( obfClassEntry.getName() ); 45 c.setName(obfClassEntry.getName());
50 46
51 BehaviorEntry caller = m_jarIndex.getAnonymousClassCaller( obfInnerClassName ); 47 BehaviorEntry caller = m_jarIndex.getAnonymousClassCaller(obfInnerClassName);
52 if( caller != null ) 48 if (caller != null) {
53 {
54 // write the enclosing method attribute 49 // write the enclosing method attribute
55 if( caller.getName().equals( "<clinit>" ) ) 50 if (caller.getName().equals("<clinit>")) {
56 { 51 c.getClassFile().addAttribute(new EnclosingMethodAttribute(c.getClassFile().getConstPool(), caller.getClassName()));
57 c.getClassFile().addAttribute( new EnclosingMethodAttribute( 52 } else {
58 c.getClassFile().getConstPool(), 53 c.getClassFile().addAttribute(new EnclosingMethodAttribute(c.getClassFile().getConstPool(), caller.getClassName(), caller.getName(), caller.getSignature()));
59 caller.getClassName()
60 ) );
61 }
62 else
63 {
64 c.getClassFile().addAttribute( new EnclosingMethodAttribute(
65 c.getClassFile().getConstPool(),
66 caller.getClassName(),
67 caller.getName(),
68 caller.getSignature()
69 ) );
70 } 54 }
71 } 55 }
72 } 56 }
73 57
74 // write the inner classes if needed 58 // write the inner classes if needed
75 Collection<String> obfInnerClassNames = m_jarIndex.getInnerClasses( obfOuterClassName ); 59 Collection<String> obfInnerClassNames = m_jarIndex.getInnerClasses(obfOuterClassName);
76 if( obfInnerClassNames != null && !obfInnerClassNames.isEmpty() ) 60 if (obfInnerClassNames != null && !obfInnerClassNames.isEmpty()) {
77 { 61 writeInnerClasses(c, obfOuterClassName, obfInnerClassNames);
78 writeInnerClasses( c, obfOuterClassName, obfInnerClassNames );
79 } 62 }
80 } 63 }
81 64
82 private void writeInnerClasses( CtClass c, String obfOuterClassName, Collection<String> obfInnerClassNames ) 65 private void writeInnerClasses(CtClass c, String obfOuterClassName, Collection<String> obfInnerClassNames) {
83 { 66 InnerClassesAttribute attr = new InnerClassesAttribute(c.getClassFile().getConstPool());
84 InnerClassesAttribute attr = new InnerClassesAttribute( c.getClassFile().getConstPool() ); 67 c.getClassFile().addAttribute(attr);
85 c.getClassFile().addAttribute( attr ); 68 for (String obfInnerClassName : obfInnerClassNames) {
86 for( String obfInnerClassName : obfInnerClassNames )
87 {
88 // get the new inner class name 69 // get the new inner class name
89 ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + obfInnerClassName ); 70 ClassEntry obfClassEntry = new ClassEntry(obfOuterClassName + "$" + obfInnerClassName);
90 71
91 // here's what the JVM spec says about the InnerClasses attribute 72 // here's what the JVM spec says about the InnerClasses attribute
92 // append( inner, outer of inner if inner is member of outer 0 ow, name after $ if inner not anonymous 0 ow, flags ); 73 // append( inner, outer of inner if inner is member of outer 0 ow, name after $ if inner not anonymous 0 ow, flags );
93 74
94 // update the attribute with this inner class 75 // update the attribute with this inner class
95 ConstPool constPool = c.getClassFile().getConstPool(); 76 ConstPool constPool = c.getClassFile().getConstPool();
96 int innerClassIndex = constPool.addClassInfo( obfClassEntry.getName() ); 77 int innerClassIndex = constPool.addClassInfo(obfClassEntry.getName());
97 int outerClassIndex = 0; 78 int outerClassIndex = 0;
98 int innerClassSimpleNameIndex = 0; 79 int innerClassSimpleNameIndex = 0;
99 if( !m_jarIndex.isAnonymousClass( obfInnerClassName ) ) 80 if (!m_jarIndex.isAnonymousClass(obfInnerClassName)) {
100 { 81 outerClassIndex = constPool.addClassInfo(obfClassEntry.getOuterClassName());
101 outerClassIndex = constPool.addClassInfo( obfClassEntry.getOuterClassName() ); 82 innerClassSimpleNameIndex = constPool.addUtf8Info(obfClassEntry.getInnerClassName());
102 innerClassSimpleNameIndex = constPool.addUtf8Info( obfClassEntry.getInnerClassName() );
103 } 83 }
104 84
105 attr.append( 85 attr.append(innerClassIndex, outerClassIndex, innerClassSimpleNameIndex, c.getClassFile().getAccessFlags() & ~AccessFlag.SUPER);
106 innerClassIndex,
107 outerClassIndex,
108 innerClassSimpleNameIndex,
109 c.getClassFile().getAccessFlags() & ~AccessFlag.SUPER
110 );
111 86
112 /* DEBUG 87 /* DEBUG
113 System.out.println( String.format( "\tOBF: %s -> ATTR: %s,%s,%s (replace %s with %s)", 88 System.out.println(String.format("\tOBF: %s -> ATTR: %s,%s,%s (replace %s with %s)",
114 obfClassEntry, 89 obfClassEntry,
115 attr.outerClass( attr.tableLength() - 1 ), 90 attr.outerClass(attr.tableLength() - 1),
116 attr.innerClass( attr.tableLength() - 1 ), 91 attr.innerClass(attr.tableLength() - 1),
117 attr.innerName( attr.tableLength() - 1 ), 92 attr.innerName(attr.tableLength() - 1),
118 Constants.NonePackage + "/" + obfInnerClassName, 93 Constants.NonePackage + "/" + obfInnerClassName,
119 obfClassEntry.getName() 94 obfClassEntry.getName()
120 ) ); 95 ));
121 */ 96 */
122 97
123 // make sure the outer class references only the new inner class names 98 // make sure the outer class references only the new inner class names
124 c.replaceClassName( Constants.NonePackage + "/" + obfInnerClassName, obfClassEntry.getName() ); 99 c.replaceClassName(Constants.NonePackage + "/" + obfInnerClassName, obfClassEntry.getName());
125 } 100 }
126 } 101 }
127} 102}