From 5f44aac70f59898197c2a7625b74f901c3b31106 Mon Sep 17 00:00:00 2001 From: jeff Date: Tue, 26 Aug 2014 00:27:44 -0400 Subject: implemented proper support for interfaces --- src/cuchaz/enigma/analysis/JarIndex.java | 107 +++++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 7 deletions(-) (limited to 'src/cuchaz/enigma/analysis/JarIndex.java') diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java index cb7508e..eaf6352 100644 --- a/src/cuchaz/enigma/analysis/JarIndex.java +++ b/src/cuchaz/enigma/analysis/JarIndex.java @@ -93,7 +93,12 @@ public class JarIndex for( CtClass c : JarClassIterator.classes( jar ) ) { fixClass( c ); - m_ancestries.addSuperclass( c.getName(), c.getClassFile().getSuperclass() ); + String className = Descriptor.toJvmName( c.getName() ); + m_ancestries.addSuperclass( className, Descriptor.toJvmName( c.getClassFile().getSuperclass() ) ); + for( String interfaceName : c.getClassFile().getInterfaces() ) + { + m_ancestries.addInterface( className, Descriptor.toJvmName( interfaceName ) ); + } for( CtBehavior behavior : c.getDeclaredBehaviors() ) { indexBehavior( behavior ); @@ -354,7 +359,6 @@ public class JarIndex } else if( callerClasses.size() > 1 ) { - // TEMP System.out.println( "WARNING: Illegal constructor called by more than one class!" + callerClasses ); } } @@ -542,6 +546,13 @@ public class JarIndex return rootNode; } + public ClassImplementationsTreeNode getClassImplementations( Translator deobfuscatingTranslator, ClassEntry obfClassEntry ) + { + ClassImplementationsTreeNode node = new ClassImplementationsTreeNode( deobfuscatingTranslator, obfClassEntry ); + node.load( m_ancestries ); + return node; + } + public MethodInheritanceTreeNode getMethodInheritance( Translator deobfuscatingTranslator, MethodEntry obfMethodEntry ) { // travel to the ancestor implementation @@ -577,6 +588,90 @@ public class JarIndex return rootNode; } + public MethodImplementationsTreeNode getMethodImplementations( Translator deobfuscatingTranslator, MethodEntry obfMethodEntry ) + { + MethodEntry interfaceMethodEntry; + + // is this method on an interface? + if( m_ancestries.isInterface( obfMethodEntry.getClassName() ) ) + { + interfaceMethodEntry = obfMethodEntry; + } + else + { + // get the interface class + List methodInterfaces = Lists.newArrayList(); + for( String interfaceName : m_ancestries.getInterfaces( obfMethodEntry.getClassName() ) ) + { + // is this method defined in this interface? + MethodEntry methodInterface = new MethodEntry( + new ClassEntry( interfaceName ), + obfMethodEntry.getName(), + obfMethodEntry.getSignature() + ); + if( isMethodImplemented( methodInterface ) ) + { + methodInterfaces.add( methodInterface ); + } + } + if( methodInterfaces.isEmpty() ) + { + return null; + } + if( methodInterfaces.size() > 1 ) + { + throw new Error( "Too many interfaces define this method! This is not yet supported by Enigma!" ); + } + interfaceMethodEntry = methodInterfaces.get( 0 ); + } + + MethodImplementationsTreeNode rootNode = new MethodImplementationsTreeNode( deobfuscatingTranslator, interfaceMethodEntry ); + rootNode.load( this ); + return rootNode; + } + + public Set getRelatedMethodImplementations( MethodEntry obfMethodEntry ) + { + Set methodEntries = Sets.newHashSet(); + getRelatedMethodImplementations( methodEntries, getMethodInheritance( null, obfMethodEntry ) ); + return methodEntries; + } + + private void getRelatedMethodImplementations( Set methodEntries, MethodInheritanceTreeNode node ) + { + MethodEntry methodEntry = node.getMethodEntry(); + if( isMethodImplemented( methodEntry ) ) + { + // collect the entry + methodEntries.add( methodEntry ); + } + + // look at interface methods too + getRelatedMethodImplementations( methodEntries, getMethodImplementations( null, methodEntry ) ); + + // recurse + for( int i=0; i methodEntries, MethodImplementationsTreeNode node ) + { + MethodEntry methodEntry = node.getMethodEntry(); + if( isMethodImplemented( methodEntry ) ) + { + // collect the entry + methodEntries.add( methodEntry ); + } + + // recurse + for( int i=0; i> getFieldReferences( FieldEntry fieldEntry ) { return m_fieldReferences.get( fieldEntry ); @@ -626,16 +721,14 @@ public class JarIndex { // for each key/value pair... Set> entriesToAdd = Sets.newHashSet(); - Iterator> iter = map.entries().iterator(); - while( iter.hasNext() ) + for( Map.Entry entry : map.entries() ) { - Map.Entry entry = iter.next(); - iter.remove(); entriesToAdd.add( new AbstractMap.SimpleEntry( renameClassesInThing( renames, entry.getKey() ), renameClassesInThing( renames, entry.getValue() ) ) ); } + map.clear(); for( Map.Entry entry : entriesToAdd ) { map.put( entry.getKey(), entry.getValue() ); @@ -761,5 +854,5 @@ public class JarIndex return thing; } return thing; - } + } } -- cgit v1.2.3