summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java16
-rw-r--r--src/cuchaz/enigma/analysis/JarIndex.java31
-rw-r--r--src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java17
-rw-r--r--src/cuchaz/enigma/bytecode/InnerClassWriter.java14
-rw-r--r--src/cuchaz/enigma/mapping/SignatureUpdater.java2
5 files changed, 46 insertions, 34 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index 1d6f02c..9c84532 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -232,7 +232,7 @@ public class Deobfuscator
232 sourceTree.acceptVisitor( new SourceIndexVisitor(), index ); 232 sourceTree.acceptVisitor( new SourceIndexVisitor(), index );
233 233
234 // DEBUG 234 // DEBUG
235 //root.acceptVisitor( new TreeDumpVisitor( new File( "tree.txt" ) ), null ); 235 //sourceTree.acceptVisitor( new TreeDumpVisitor( new File( "tree.txt" ) ), null );
236 236
237 /* DEBUG 237 /* DEBUG
238 for( Token token : index.referenceTokens() ) 238 for( Token token : index.referenceTokens() )
@@ -420,19 +420,7 @@ public class Deobfuscator
420 { 420 {
421 if( obfEntry instanceof ClassEntry ) 421 if( obfEntry instanceof ClassEntry )
422 { 422 {
423 ClassEntry obfClassEntry = (ClassEntry)obfEntry; 423 return m_jarIndex.getObfClassEntries().contains( obfEntry );
424 if( obfClassEntry.isInnerClass() )
425 {
426 // both classes must be in the list
427 return m_jarIndex.getObfClassEntries().contains( obfClassEntry.getOuterClassEntry() )
428 && m_jarIndex.getObfClassEntries().contains( obfClassEntry.getInnerClassName() );
429 // TODO: make sure this works for the inner class!!
430 }
431 else
432 {
433 // class must be in the list
434 return m_jarIndex.getObfClassEntries().contains( obfEntry );
435 }
436 } 424 }
437 else 425 else
438 { 426 {
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java
index c36e9cb..8ebce35 100644
--- a/src/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/cuchaz/enigma/analysis/JarIndex.java
@@ -63,7 +63,7 @@ public class JarIndex
63 private Multimap<FieldEntry,EntryReference<FieldEntry,BehaviorEntry>> m_fieldReferences; 63 private Multimap<FieldEntry,EntryReference<FieldEntry,BehaviorEntry>> m_fieldReferences;
64 private Multimap<String,String> m_innerClasses; 64 private Multimap<String,String> m_innerClasses;
65 private Map<String,String> m_outerClasses; 65 private Map<String,String> m_outerClasses;
66 private Set<String> m_anonymousClasses; 66 private Map<String,BehaviorEntry> m_anonymousClasses;
67 private Map<MethodEntry,MethodEntry> m_bridgeMethods; 67 private Map<MethodEntry,MethodEntry> m_bridgeMethods;
68 68
69 public JarIndex( ) 69 public JarIndex( )
@@ -78,7 +78,7 @@ public class JarIndex
78 m_fieldReferences = HashMultimap.create(); 78 m_fieldReferences = HashMultimap.create();
79 m_innerClasses = HashMultimap.create(); 79 m_innerClasses = HashMultimap.create();
80 m_outerClasses = Maps.newHashMap(); 80 m_outerClasses = Maps.newHashMap();
81 m_anonymousClasses = Sets.newHashSet(); 81 m_anonymousClasses = Maps.newHashMap();
82 m_bridgeMethods = Maps.newHashMap(); 82 m_bridgeMethods = Maps.newHashMap();
83 } 83 }
84 84
@@ -161,9 +161,10 @@ public class JarIndex
161 m_innerClasses.put( outerClassName, innerClassName ); 161 m_innerClasses.put( outerClassName, innerClassName );
162 m_outerClasses.put( innerClassName, outerClassName ); 162 m_outerClasses.put( innerClassName, outerClassName );
163 163
164 if( isAnonymousClass( c, outerClassName ) ) 164 BehaviorEntry enclosingBehavior = isAnonymousClass( c, outerClassName );
165 if( enclosingBehavior != null )
165 { 166 {
166 m_anonymousClasses.add( innerClassName ); 167 m_anonymousClasses.put( innerClassName, enclosingBehavior );
167 168
168 // DEBUG 169 // DEBUG
169 //System.out.println( "ANONYMOUS: " + outerClassName + "$" + innerClassName ); 170 //System.out.println( "ANONYMOUS: " + outerClassName + "$" + innerClassName );
@@ -188,6 +189,7 @@ public class JarIndex
188 EntryRenamer.renameClassesInMultimap( renames, m_methodImplementations ); 189 EntryRenamer.renameClassesInMultimap( renames, m_methodImplementations );
189 EntryRenamer.renameClassesInMultimap( renames, m_behaviorReferences ); 190 EntryRenamer.renameClassesInMultimap( renames, m_behaviorReferences );
190 EntryRenamer.renameClassesInMultimap( renames, m_fieldReferences ); 191 EntryRenamer.renameClassesInMultimap( renames, m_fieldReferences );
192 EntryRenamer.renameClassesInMap( renames, m_bridgeMethods );
191 } 193 }
192 194
193 // step 6: update other indices with bridge method info 195 // step 6: update other indices with bridge method info
@@ -618,7 +620,7 @@ public class JarIndex
618 return true; 620 return true;
619 } 621 }
620 622
621 private boolean isAnonymousClass( CtClass c, String outerClassName ) 623 private BehaviorEntry isAnonymousClass( CtClass c, String outerClassName )
622 { 624 {
623 ClassEntry innerClassEntry = new ClassEntry( Descriptor.toJvmName( c.getName() ) ); 625 ClassEntry innerClassEntry = new ClassEntry( Descriptor.toJvmName( c.getName() ) );
624 626
@@ -631,13 +633,13 @@ public class JarIndex
631 // is abstract? 633 // is abstract?
632 if( Modifier.isAbstract( c.getModifiers() ) ) 634 if( Modifier.isAbstract( c.getModifiers() ) )
633 { 635 {
634 return false; 636 return null;
635 } 637 }
636 638
637 // is there exactly one constructor? 639 // is there exactly one constructor?
638 if( c.getDeclaredConstructors().length != 1 ) 640 if( c.getDeclaredConstructors().length != 1 )
639 { 641 {
640 return false; 642 return null;
641 } 643 }
642 CtConstructor constructor = c.getDeclaredConstructors()[0]; 644 CtConstructor constructor = c.getDeclaredConstructors()[0];
643 645
@@ -646,7 +648,7 @@ public class JarIndex
646 Collection<EntryReference<BehaviorEntry,BehaviorEntry>> references = getBehaviorReferences( constructorEntry ); 648 Collection<EntryReference<BehaviorEntry,BehaviorEntry>> references = getBehaviorReferences( constructorEntry );
647 if( references.size() != 1 ) 649 if( references.size() != 1 )
648 { 650 {
649 return false; 651 return null;
650 } 652 }
651 653
652 // does the caller use this type? 654 // does the caller use this type?
@@ -657,7 +659,7 @@ public class JarIndex
657 if( fieldClass != null && fieldClass.equals( innerClassEntry ) ) 659 if( fieldClass != null && fieldClass.equals( innerClassEntry ) )
658 { 660 {
659 // caller references this type, so it can't be anonymous 661 // caller references this type, so it can't be anonymous
660 return false; 662 return null;
661 } 663 }
662 } 664 }
663 for( BehaviorEntry behaviorEntry : getReferencedBehaviors( caller ) ) 665 for( BehaviorEntry behaviorEntry : getReferencedBehaviors( caller ) )
@@ -668,12 +670,12 @@ public class JarIndex
668 if( className.equals( innerClassEntry.getName() ) ) 670 if( className.equals( innerClassEntry.getName() ) )
669 { 671 {
670 // caller references this type, so it can't be anonymous 672 // caller references this type, so it can't be anonymous
671 return false; 673 return null;
672 } 674 }
673 } 675 }
674 } 676 }
675 677
676 return true; 678 return caller;
677 } 679 }
678 680
679 public Set<ClassEntry> getObfClassEntries( ) 681 public Set<ClassEntry> getObfClassEntries( )
@@ -905,7 +907,12 @@ public class JarIndex
905 907
906 public boolean isAnonymousClass( String obfInnerClassName ) 908 public boolean isAnonymousClass( String obfInnerClassName )
907 { 909 {
908 return m_anonymousClasses.contains( obfInnerClassName ); 910 return m_anonymousClasses.containsKey( obfInnerClassName );
911 }
912
913 public BehaviorEntry getAnonymousClassCaller( String obfInnerClassName )
914 {
915 return m_anonymousClasses.get( obfInnerClassName );
909 } 916 }
910 917
911 public Set<String> getInterfaces( String className ) 918 public Set<String> getInterfaces( String className )
diff --git a/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
index a1dac4b..6238b1e 100644
--- a/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
+++ b/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
@@ -177,14 +177,17 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor
177 public Void visitObjectCreationExpression( ObjectCreationExpression node, SourceIndex index ) 177 public Void visitObjectCreationExpression( ObjectCreationExpression node, SourceIndex index )
178 { 178 {
179 MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE ); 179 MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE );
180 ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); 180 if( ref != null )
181 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, ref.getSignature() );
182 if( node.getType() instanceof SimpleType )
183 { 181 {
184 index.addReference( 182 ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() );
185 ((SimpleType)node.getType()).getIdentifierToken(), 183 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, ref.getSignature() );
186 new EntryReference<Entry,Entry>( constructorEntry, m_behaviorEntry ) 184 if( node.getType() instanceof SimpleType )
187 ); 185 {
186 index.addReference(
187 ((SimpleType)node.getType()).getIdentifierToken(),
188 new EntryReference<Entry,Entry>( constructorEntry, m_behaviorEntry )
189 );
190 }
188 } 191 }
189 192
190 return recurse( node, index ); 193 return recurse( node, index );
diff --git a/src/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/cuchaz/enigma/bytecode/InnerClassWriter.java
index 5044e06..f94a85d 100644
--- a/src/cuchaz/enigma/bytecode/InnerClassWriter.java
+++ b/src/cuchaz/enigma/bytecode/InnerClassWriter.java
@@ -16,8 +16,10 @@ import javassist.CtClass;
16import javassist.bytecode.AccessFlag; 16import javassist.bytecode.AccessFlag;
17import javassist.bytecode.ConstPool; 17import javassist.bytecode.ConstPool;
18import javassist.bytecode.Descriptor; 18import javassist.bytecode.Descriptor;
19import javassist.bytecode.EnclosingMethodAttribute;
19import javassist.bytecode.InnerClassesAttribute; 20import javassist.bytecode.InnerClassesAttribute;
20import cuchaz.enigma.analysis.JarIndex; 21import cuchaz.enigma.analysis.JarIndex;
22import cuchaz.enigma.mapping.BehaviorEntry;
21import cuchaz.enigma.mapping.ClassEntry; 23import cuchaz.enigma.mapping.ClassEntry;
22 24
23public class InnerClassWriter 25public class InnerClassWriter
@@ -44,6 +46,18 @@ public class InnerClassWriter
44 // this is an inner class, rename it to outer$inner 46 // this is an inner class, rename it to outer$inner
45 ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + new ClassEntry( obfClassName ).getSimpleName() ); 47 ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + new ClassEntry( obfClassName ).getSimpleName() );
46 c.setName( obfClassEntry.getName() ); 48 c.setName( obfClassEntry.getName() );
49
50 BehaviorEntry caller = m_jarIndex.getAnonymousClassCaller( obfClassName );
51 if( caller != null )
52 {
53 // write the enclosing method attribute
54 c.getClassFile().addAttribute( new EnclosingMethodAttribute(
55 c.getClassFile().getConstPool(),
56 caller.getClassName(),
57 caller.getName(),
58 caller.getSignature()
59 ) );
60 }
47 } 61 }
48 62
49 // write the inner classes if needed 63 // write the inner classes if needed
diff --git a/src/cuchaz/enigma/mapping/SignatureUpdater.java b/src/cuchaz/enigma/mapping/SignatureUpdater.java
index 528a743..d1216bd 100644
--- a/src/cuchaz/enigma/mapping/SignatureUpdater.java
+++ b/src/cuchaz/enigma/mapping/SignatureUpdater.java
@@ -14,7 +14,7 @@ import java.io.IOException;
14import java.io.StringReader; 14import java.io.StringReader;
15import java.util.List; 15import java.util.List;
16 16
17import com.beust.jcommander.internal.Lists; 17import com.google.common.collect.Lists;
18 18
19public class SignatureUpdater 19public class SignatureUpdater
20{ 20{