summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/Deobfuscator.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/Deobfuscator.java')
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java102
1 files changed, 85 insertions, 17 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index 9c84532..03c3511 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -22,6 +22,7 @@ import java.util.jar.JarFile;
22 22
23import javassist.bytecode.Descriptor; 23import javassist.bytecode.Descriptor;
24 24
25import com.google.common.collect.Lists;
25import com.google.common.collect.Maps; 26import com.google.common.collect.Maps;
26import com.google.common.collect.Sets; 27import com.google.common.collect.Sets;
27import com.strobel.assembler.metadata.MetadataSystem; 28import com.strobel.assembler.metadata.MetadataSystem;
@@ -44,6 +45,7 @@ import cuchaz.enigma.mapping.ClassMapping;
44import cuchaz.enigma.mapping.ConstructorEntry; 45import cuchaz.enigma.mapping.ConstructorEntry;
45import cuchaz.enigma.mapping.Entry; 46import cuchaz.enigma.mapping.Entry;
46import cuchaz.enigma.mapping.FieldEntry; 47import cuchaz.enigma.mapping.FieldEntry;
48import cuchaz.enigma.mapping.FieldMapping;
47import cuchaz.enigma.mapping.Mappings; 49import cuchaz.enigma.mapping.Mappings;
48import cuchaz.enigma.mapping.MappingsRenamer; 50import cuchaz.enigma.mapping.MappingsRenamer;
49import cuchaz.enigma.mapping.MethodEntry; 51import cuchaz.enigma.mapping.MethodEntry;
@@ -113,41 +115,107 @@ public class Deobfuscator
113 val = new Mappings(); 115 val = new Mappings();
114 } 116 }
115 117
116 // make sure all the mappings match the classes in the jar 118 // look for any classes that got moved to inner classes
119 Map<String,String> renames = Maps.newHashMap();
117 for( ClassMapping classMapping : val.classes() ) 120 for( ClassMapping classMapping : val.classes() )
118 { 121 {
119 ClassEntry classEntry = new ClassEntry( classMapping.getObfName() ); 122 String outerClassName = m_jarIndex.getOuterClass( classMapping.getObfName() );
120 if( !m_jarIndex.getObfClassEntries().contains( classEntry ) ) 123 if( outerClassName != null )
121 { 124 {
122 throw new Error( "Class " + classEntry + " not found in Jar!" ); 125 // build the composite class name
126 String newName = outerClassName + "$" + new ClassEntry( classMapping.getObfName() ).getSimpleName();
127
128 // add a rename
129 renames.put( classMapping.getObfName(), newName );
130
131 System.out.println( String.format( "Converted class mapping %s to %s", classMapping.getObfName(), newName ) );
123 } 132 }
124 133 }
125 // and method implementations 134 for( Map.Entry<String,String> entry : renames.entrySet() )
126 for( MethodMapping methodMapping : classMapping.methods() ) 135 {
136 val.renameObfClass( entry.getKey(), entry.getValue() );
137 }
138
139 // drop mappings that don't match the jar
140 List<ClassEntry> unknownClasses = Lists.newArrayList();
141 for( ClassMapping classMapping : val.classes() )
142 {
143 checkClassMapping( unknownClasses, classMapping );
144 }
145 if( !unknownClasses.isEmpty() )
146 {
147 throw new Error( "Unable to find classes in jar: " + unknownClasses );
148 }
149
150 m_mappings = val;
151 m_renamer = new MappingsRenamer( m_jarIndex, m_mappings );
152 m_translatorCache.clear();
153 }
154
155 private void checkClassMapping( List<ClassEntry> unknownClasses, ClassMapping classMapping )
156 {
157 // check the class
158 ClassEntry classEntry = new ClassEntry( classMapping.getObfName() );
159 String outerClassName = m_jarIndex.getOuterClass( classMapping.getObfName() );
160 if( outerClassName != null )
161 {
162 classEntry = new ClassEntry( outerClassName + "$" + classEntry.getSimpleName() );
163 }
164 if( !m_jarIndex.getObfClassEntries().contains( classEntry ) )
165 {
166 unknownClasses.add( classEntry );
167 }
168
169 // check the fields
170 for( FieldMapping fieldMapping : Lists.newArrayList( classMapping.fields() ) )
171 {
172 FieldEntry fieldEntry = new FieldEntry( classEntry, fieldMapping.getObfName() );
173 if( m_jarIndex.getAccess( fieldEntry ) == null )
174 {
175 System.err.println( "WARNING: unable to find field " + fieldEntry + ". dropping mapping." );
176 classMapping.removeFieldMapping( fieldMapping );
177 }
178 }
179
180 // check methods
181 for( MethodMapping methodMapping : Lists.newArrayList( classMapping.methods() ) )
182 {
183 if( methodMapping.getObfName().equals( "<clinit>" ) )
184 {
185 // skip static initializers
186 continue;
187 }
188 else if( methodMapping.getObfName().equals( "<init>" ) )
127 { 189 {
128 if( methodMapping.getObfName().startsWith( "<" ) ) 190 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, methodMapping.getObfSignature() );
191 if( m_jarIndex.getAccess( constructorEntry ) == null )
129 { 192 {
130 // skip constructors and static initializers 193 System.err.println( "WARNING: unable to find constructor " + constructorEntry + ". dropping mapping." );
131 continue; 194 classMapping.removeMethodMapping( methodMapping );
132 } 195 }
133 196 }
197 else
198 {
134 MethodEntry methodEntry = new MethodEntry( 199 MethodEntry methodEntry = new MethodEntry(
135 classEntry, 200 classEntry,
136 methodMapping.getObfName(), 201 methodMapping.getObfName(),
137 methodMapping.getObfSignature() 202 methodMapping.getObfSignature()
138 ); 203 );
139 if( !m_jarIndex.isMethodImplemented( methodEntry ) ) 204 if( m_jarIndex.getAccess( methodEntry ) == null )
140 { 205 {
141 throw new Error( "Method " + methodEntry + " not found in Jar!" ); 206 System.err.println( "WARNING: unable to find method " + methodEntry + ". dropping mapping." );
207 classMapping.removeMethodMapping( methodMapping );
142 } 208 }
143 } 209 }
144 } 210 }
145 211
146 m_mappings = val; 212 // check inner classes
147 m_renamer = new MappingsRenamer( m_jarIndex, m_mappings ); 213 for( ClassMapping innerClassMapping : classMapping.innerClasses() )
148 m_translatorCache.clear(); 214 {
215 checkClassMapping( unknownClasses, innerClassMapping );
216 }
149 } 217 }
150 218
151 public Translator getTranslator( TranslationDirection direction ) 219 public Translator getTranslator( TranslationDirection direction )
152 { 220 {
153 Translator translator = m_translatorCache.get( direction ); 221 Translator translator = m_translatorCache.get( direction );