From 34c1e8e64ec4575527a19fb4cb0640c57da784db Mon Sep 17 00:00:00 2001 From: jeff Date: Mon, 18 Aug 2014 00:55:30 -0400 Subject: crap-ton of bug fixes for inner classes --- src/cuchaz/enigma/bytecode/BytecodeTools.java | 57 ++++++++++++++++++++++++ src/cuchaz/enigma/bytecode/ClassTranslator.java | 53 ++++++++++++++++------ src/cuchaz/enigma/bytecode/InnerClassWriter.java | 42 +++++++++-------- 3 files changed, 116 insertions(+), 36 deletions(-) (limited to 'src/cuchaz/enigma/bytecode') diff --git a/src/cuchaz/enigma/bytecode/BytecodeTools.java b/src/cuchaz/enigma/bytecode/BytecodeTools.java index 664350e..0de9bd6 100644 --- a/src/cuchaz/enigma/bytecode/BytecodeTools.java +++ b/src/cuchaz/enigma/bytecode/BytecodeTools.java @@ -15,6 +15,7 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.List; import java.util.Map; import java.util.Set; @@ -25,6 +26,7 @@ import javassist.bytecode.CodeAttribute; import javassist.bytecode.ConstPool; import javassist.bytecode.ExceptionTable; +import com.beust.jcommander.internal.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -266,4 +268,59 @@ public class BytecodeTools ); } } + + public static List getParameterTypes( String signature ) + { + List types = Lists.newArrayList(); + for( int i=0; i 0 ) + { + type = "[" + type; + } + types.add( type ); + } + return types; + } } diff --git a/src/cuchaz/enigma/bytecode/ClassTranslator.java b/src/cuchaz/enigma/bytecode/ClassTranslator.java index 3b5beeb..9ce06a5 100644 --- a/src/cuchaz/enigma/bytecode/ClassTranslator.java +++ b/src/cuchaz/enigma/bytecode/ClassTranslator.java @@ -10,7 +10,6 @@ ******************************************************************************/ package cuchaz.enigma.bytecode; -import java.util.HashSet; import java.util.Set; import javassist.ClassMap; @@ -20,6 +19,10 @@ import javassist.CtField; import javassist.CtMethod; import javassist.bytecode.ConstPool; import javassist.bytecode.Descriptor; +import javassist.bytecode.InnerClassesAttribute; + +import com.beust.jcommander.internal.Sets; + import cuchaz.enigma.mapping.ClassEntry; import cuchaz.enigma.mapping.FieldEntry; import cuchaz.enigma.mapping.MethodEntry; @@ -133,25 +136,47 @@ public class ClassTranslator // translate all the class names referenced in the code // the above code only changed method/field/reference names and types, but not the class names themselves - Set classNames = getAllClassNames( c ); + Set classEntries = getAllClassEntries( c ); ClassMap map = new ClassMap(); - for( String className : classNames ) + for( ClassEntry obfClassEntry : classEntries ) { - String translatedName = m_translator.translateClass( className ); - if( translatedName != null ) - { - map.put( className, translatedName ); - } + map.put( obfClassEntry.getName(), m_translator.translateEntry( obfClassEntry ).getName() ); } - if( !map.isEmpty() ) + c.replaceClassName( map ); + + // translate the names in the InnerClasses attribute + InnerClassesAttribute attr = (InnerClassesAttribute)c.getClassFile().getAttribute( InnerClassesAttribute.tag ); + if( attr != null ) { - c.replaceClassName( map ); + for( int i=0; i ATTR: %s,%s,%s", + obfClassEntry, deobfClassEntry, + attr.outerClass( i ), + attr.innerClass( i ), + attr.innerName( i ) + ) ); + */ + } } } - private Set getAllClassNames( CtClass c ) + private Set getAllClassEntries( CtClass c ) { - final Set names = new HashSet(); + final Set entries = Sets.newHashSet(); ClassMap map = new ClassMap( ) { @Override @@ -159,13 +184,13 @@ public class ClassTranslator { if( obj instanceof String ) { - names.add( (String)obj ); + entries.add( new ClassEntry( (String)obj ) ); } return null; } private static final long serialVersionUID = -202160293602070641L; }; c.replaceClassName( map ); - return names; + return entries; } } diff --git a/src/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/cuchaz/enigma/bytecode/InnerClassWriter.java index b0e33ac..c412b1a 100644 --- a/src/cuchaz/enigma/bytecode/InnerClassWriter.java +++ b/src/cuchaz/enigma/bytecode/InnerClassWriter.java @@ -18,16 +18,14 @@ import javassist.bytecode.ConstPool; import javassist.bytecode.Descriptor; import javassist.bytecode.InnerClassesAttribute; import cuchaz.enigma.analysis.JarIndex; -import cuchaz.enigma.mapping.Translator; +import cuchaz.enigma.mapping.ClassEntry; public class InnerClassWriter { - private Translator m_deobfuscatingTranslator; private JarIndex m_jarIndex; - public InnerClassWriter( Translator deobfuscatingTranslator, JarIndex jarIndex ) + public InnerClassWriter( JarIndex jarIndex ) { - m_deobfuscatingTranslator = deobfuscatingTranslator; m_jarIndex = jarIndex; } @@ -44,7 +42,8 @@ public class InnerClassWriter else { // this is an inner class, rename it to outer$inner - c.setName( obfOuterClassName + "$" + obfClassName ); + ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + obfClassName ); + c.setName( obfClassEntry.getName() ); } // write the inner classes if needed @@ -62,31 +61,20 @@ public class InnerClassWriter for( String obfInnerClassName : obfInnerClassNames ) { // deobfuscate the class names - String deobfOuterClassName = m_deobfuscatingTranslator.translateClass( obfOuterClassName ); - if( deobfOuterClassName == null ) - { - deobfOuterClassName = obfOuterClassName; - } - String obfOuterInnerClassName = obfOuterClassName + "$" + obfInnerClassName; - String deobfOuterInnerClassName = m_deobfuscatingTranslator.translateClass( obfOuterInnerClassName ); - if( deobfOuterInnerClassName == null ) - { - deobfOuterInnerClassName = obfOuterInnerClassName; - } - String deobfInnerClassName = deobfOuterInnerClassName.substring( deobfOuterInnerClassName.lastIndexOf( '$' ) + 1 ); - + ClassEntry obfClassEntry = new ClassEntry( obfOuterClassName + "$" + obfInnerClassName ); + // here's what the JVM spec says about the InnerClasses attribute // append( inner, outer of inner if inner is member of outer 0 ow, name after $ if inner not anonymous 0 ow, flags ); // update the attribute with this inner class ConstPool constPool = c.getClassFile().getConstPool(); - int innerClassIndex = constPool.addClassInfo( deobfOuterInnerClassName ); + int innerClassIndex = constPool.addClassInfo( obfClassEntry.getName() ); int outerClassIndex = 0; int innerClassSimpleNameIndex = 0; if( !m_jarIndex.isAnonymousClass( obfInnerClassName ) ) { - outerClassIndex = constPool.addClassInfo( deobfOuterClassName ); - innerClassSimpleNameIndex = constPool.addUtf8Info( deobfInnerClassName ); + outerClassIndex = constPool.addClassInfo( obfClassEntry.getOuterClassName() ); + innerClassSimpleNameIndex = constPool.addUtf8Info( obfClassEntry.getInnerClassName() ); } attr.append( @@ -96,8 +84,18 @@ public class InnerClassWriter c.getClassFile().getAccessFlags() & ~AccessFlag.SUPER ); + /* DEBUG + System.out.println( String.format( "\tOBF: %s -> ATTR: %s,%s,%s (replace %s with %s)", + obfClassEntry, + attr.outerClass( attr.tableLength() - 1 ), + attr.innerClass( attr.tableLength() - 1 ), + attr.innerName( attr.tableLength() - 1 ), + obfInnerClassName, obfClassEntry.getName() + ) ); + */ + // make sure the outer class references only the new inner class names - c.replaceClassName( obfInnerClassName, deobfOuterInnerClassName ); + c.replaceClassName( obfInnerClassName, obfClassEntry.getName() ); } } } -- cgit v1.2.3