summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/Deobfuscator.java
diff options
context:
space:
mode:
authorGravatar jeff2014-09-24 01:00:54 -0400
committerGravatar jeff2014-09-24 01:00:54 -0400
commit8776a8ba38123c822530e5f659c626c8db616217 (patch)
tree8138a4e4447552e598bb99cfd8fb23a5f27f840b /src/cuchaz/enigma/Deobfuscator.java
parenttrying to figure out why some mappings to correspond to anything in the jar f... (diff)
downloadenigma-fork-8776a8ba38123c822530e5f659c626c8db616217.tar.gz
enigma-fork-8776a8ba38123c822530e5f659c626c8db616217.tar.xz
enigma-fork-8776a8ba38123c822530e5f659c626c8db616217.zip
HOW DO I WRITE SO MANY BUGS?!?
Diffstat (limited to 'src/cuchaz/enigma/Deobfuscator.java')
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java102
1 files changed, 80 insertions, 22 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index 03c3511..f7f7448 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -39,6 +39,7 @@ import cuchaz.enigma.analysis.EntryReference;
39import cuchaz.enigma.analysis.JarIndex; 39import cuchaz.enigma.analysis.JarIndex;
40import cuchaz.enigma.analysis.SourceIndex; 40import cuchaz.enigma.analysis.SourceIndex;
41import cuchaz.enigma.analysis.SourceIndexVisitor; 41import cuchaz.enigma.analysis.SourceIndexVisitor;
42import cuchaz.enigma.analysis.Token;
42import cuchaz.enigma.mapping.ArgumentEntry; 43import cuchaz.enigma.mapping.ArgumentEntry;
43import cuchaz.enigma.mapping.ClassEntry; 44import cuchaz.enigma.mapping.ClassEntry;
44import cuchaz.enigma.mapping.ClassMapping; 45import cuchaz.enigma.mapping.ClassMapping;
@@ -115,7 +116,7 @@ public class Deobfuscator
115 val = new Mappings(); 116 val = new Mappings();
116 } 117 }
117 118
118 // look for any classes that got moved to inner classes 119 // pass 1: look for any classes that got moved to inner classes
119 Map<String,String> renames = Maps.newHashMap(); 120 Map<String,String> renames = Maps.newHashMap();
120 for( ClassMapping classMapping : val.classes() ) 121 for( ClassMapping classMapping : val.classes() )
121 { 122 {
@@ -136,6 +137,53 @@ public class Deobfuscator
136 val.renameObfClass( entry.getKey(), entry.getValue() ); 137 val.renameObfClass( entry.getKey(), entry.getValue() );
137 } 138 }
138 139
140 // pass 2: look for fields/methods that are actually declared in superclasses
141 MappingsRenamer renamer = new MappingsRenamer( m_jarIndex, val );
142 for( ClassMapping classMapping : val.classes() )
143 {
144 ClassEntry obfClassEntry = new ClassEntry( classMapping.getObfName() );
145
146 // fields
147 for( FieldMapping fieldMapping : Lists.newArrayList( classMapping.fields() ) )
148 {
149 FieldEntry fieldEntry = new FieldEntry( obfClassEntry, fieldMapping.getObfName() );
150 ClassEntry resolvedObfClassEntry = m_jarIndex.resolveEntryClass( fieldEntry );
151 if( resolvedObfClassEntry != null && !resolvedObfClassEntry.equals( fieldEntry.getClassEntry() ) )
152 {
153 boolean wasMoved = renamer.moveFieldToObfClass( classMapping, fieldMapping, resolvedObfClassEntry );
154 if( wasMoved )
155 {
156 System.out.println( String.format( "Moved field %s to class %s", fieldEntry, resolvedObfClassEntry ) );
157 }
158 else
159 {
160 System.err.println( String.format( "WARNING: Would move field %s to class %s but the field was already there. Dropping instead.", fieldEntry, resolvedObfClassEntry ) );
161 }
162 }
163 }
164
165 // methods
166 for( MethodMapping methodMapping : Lists.newArrayList( classMapping.methods() ) )
167 {
168 MethodEntry methodEntry = new MethodEntry( obfClassEntry, methodMapping.getObfName(), methodMapping.getObfSignature() );
169 ClassEntry resolvedObfClassEntry = m_jarIndex.resolveEntryClass( methodEntry );
170 if( resolvedObfClassEntry != null && !resolvedObfClassEntry.equals( methodEntry.getClassEntry() ) )
171 {
172 boolean wasMoved = renamer.moveMethodToObfClass( classMapping, methodMapping, resolvedObfClassEntry );
173 if( wasMoved )
174 {
175 System.out.println( String.format( "Moved method %s to class %s", methodEntry, resolvedObfClassEntry ) );
176 }
177 else
178 {
179 System.err.println( String.format( "WARNING: Would move method %s to class %s but the method was already there. Dropping instead.", methodEntry, resolvedObfClassEntry ) );
180 }
181 }
182 }
183
184 // TODO: recurse to inner classes?
185 }
186
139 // drop mappings that don't match the jar 187 // drop mappings that don't match the jar
140 List<ClassEntry> unknownClasses = Lists.newArrayList(); 188 List<ClassEntry> unknownClasses = Lists.newArrayList();
141 for( ClassMapping classMapping : val.classes() ) 189 for( ClassMapping classMapping : val.classes() )
@@ -148,7 +196,7 @@ public class Deobfuscator
148 } 196 }
149 197
150 m_mappings = val; 198 m_mappings = val;
151 m_renamer = new MappingsRenamer( m_jarIndex, m_mappings ); 199 m_renamer = renamer;
152 m_translatorCache.clear(); 200 m_translatorCache.clear();
153 } 201 }
154 202
@@ -170,7 +218,7 @@ public class Deobfuscator
170 for( FieldMapping fieldMapping : Lists.newArrayList( classMapping.fields() ) ) 218 for( FieldMapping fieldMapping : Lists.newArrayList( classMapping.fields() ) )
171 { 219 {
172 FieldEntry fieldEntry = new FieldEntry( classEntry, fieldMapping.getObfName() ); 220 FieldEntry fieldEntry = new FieldEntry( classEntry, fieldMapping.getObfName() );
173 if( m_jarIndex.getAccess( fieldEntry ) == null ) 221 if( !m_jarIndex.containsObfField( fieldEntry ) )
174 { 222 {
175 System.err.println( "WARNING: unable to find field " + fieldEntry + ". dropping mapping." ); 223 System.err.println( "WARNING: unable to find field " + fieldEntry + ". dropping mapping." );
176 classMapping.removeFieldMapping( fieldMapping ); 224 classMapping.removeFieldMapping( fieldMapping );
@@ -188,7 +236,7 @@ public class Deobfuscator
188 else if( methodMapping.getObfName().equals( "<init>" ) ) 236 else if( methodMapping.getObfName().equals( "<init>" ) )
189 { 237 {
190 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, methodMapping.getObfSignature() ); 238 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, methodMapping.getObfSignature() );
191 if( m_jarIndex.getAccess( constructorEntry ) == null ) 239 if( !m_jarIndex.containsObfBehavior( constructorEntry ) )
192 { 240 {
193 System.err.println( "WARNING: unable to find constructor " + constructorEntry + ". dropping mapping." ); 241 System.err.println( "WARNING: unable to find constructor " + constructorEntry + ". dropping mapping." );
194 classMapping.removeMethodMapping( methodMapping ); 242 classMapping.removeMethodMapping( methodMapping );
@@ -201,7 +249,7 @@ public class Deobfuscator
201 methodMapping.getObfName(), 249 methodMapping.getObfName(),
202 methodMapping.getObfSignature() 250 methodMapping.getObfSignature()
203 ); 251 );
204 if( m_jarIndex.getAccess( methodEntry ) == null ) 252 if( !m_jarIndex.containsObfBehavior( methodEntry ) )
205 { 253 {
206 System.err.println( "WARNING: unable to find method " + methodEntry + ". dropping mapping." ); 254 System.err.println( "WARNING: unable to find method " + methodEntry + ". dropping mapping." );
207 classMapping.removeMethodMapping( methodMapping ); 255 classMapping.removeMethodMapping( methodMapping );
@@ -257,19 +305,20 @@ public class Deobfuscator
257 } 305 }
258 } 306 }
259 307
260 public CompilationUnit getSourceTree( String className ) 308 public CompilationUnit getSourceTree( String obfClassName )
261 { 309 {
262 // is this class deobfuscated? 310 // is this class deobfuscated?
263 // we need to tell the decompiler the deobfuscated name so it doesn't get freaked out 311 // we need to tell the decompiler the deobfuscated name so it doesn't get freaked out
264 // the decompiler only sees the deobfuscated class, so we need to load it by the deobfuscated name 312 // the decompiler only sees the deobfuscated class, so we need to load it by the deobfuscated name
265 ClassMapping classMapping = m_mappings.getClassByObf( className ); 313 String lookupClassName = obfClassName;
314 ClassMapping classMapping = m_mappings.getClassByObf( obfClassName );
266 if( classMapping != null && classMapping.getDeobfName() != null ) 315 if( classMapping != null && classMapping.getDeobfName() != null )
267 { 316 {
268 className = classMapping.getDeobfName(); 317 lookupClassName = classMapping.getDeobfName();
269 } 318 }
270 319
271 // is this class even in the jar? 320 // is this class even in the jar?
272 if( !m_jarIndex.containsObfClass( new ClassEntry( className ) ) ) 321 if( !m_jarIndex.containsObfClass( new ClassEntry( obfClassName ) ) )
273 { 322 {
274 return null; 323 return null;
275 } 324 }
@@ -283,7 +332,7 @@ public class Deobfuscator
283 ) ); 332 ) );
284 333
285 // decompile it! 334 // decompile it!
286 TypeDefinition resolvedType = new MetadataSystem( m_settings.getTypeLoader() ).lookupType( className ).resolve(); 335 TypeDefinition resolvedType = new MetadataSystem( m_settings.getTypeLoader() ).lookupType( lookupClassName ).resolve();
287 DecompilerContext context = new DecompilerContext(); 336 DecompilerContext context = new DecompilerContext();
288 context.setCurrentType( resolvedType ); 337 context.setCurrentType( resolvedType );
289 context.setSettings( m_settings ); 338 context.setSettings( m_settings );
@@ -302,13 +351,29 @@ public class Deobfuscator
302 // DEBUG 351 // DEBUG
303 //sourceTree.acceptVisitor( new TreeDumpVisitor( new File( "tree.txt" ) ), null ); 352 //sourceTree.acceptVisitor( new TreeDumpVisitor( new File( "tree.txt" ) ), null );
304 353
305 /* DEBUG 354 // resolve all the classes in the source references
306 for( Token token : index.referenceTokens() ) 355 for( Token token : index.referenceTokens() )
307 { 356 {
308 EntryReference<Entry,Entry> reference = index.getDeobfReference( token ); 357 EntryReference<Entry,Entry> deobfReference = index.getDeobfReference( token );
309 System.out.println( token + " -> " + reference + " -> " + index.getReferenceToken( reference ) ); 358
359 // get the obfuscated entry
360 Entry obfEntry = obfuscateEntry( deobfReference.entry );
361
362 // try to resolve the class
363 ClassEntry resolvedObfClassEntry = m_jarIndex.resolveEntryClass( obfEntry );
364 if( resolvedObfClassEntry != null && !resolvedObfClassEntry.equals( obfEntry.getClassEntry() ) )
365 {
366 // change the class of the entry
367 obfEntry = obfEntry.cloneToNewClass( resolvedObfClassEntry );
368
369 // save the new deobfuscated reference
370 deobfReference.entry = deobfuscateEntry( obfEntry );
371 index.replaceDeobfReference( token, deobfReference );
372 }
373
374 // DEBUG
375 //System.out.println( token + " -> " + reference + " -> " + index.getReferenceToken( reference ) );
310 } 376 }
311 */
312 377
313 return index; 378 return index;
314 } 379 }
@@ -486,13 +551,6 @@ public class Deobfuscator
486 551
487 public boolean isObfuscatedIdentifier( Entry obfEntry ) 552 public boolean isObfuscatedIdentifier( Entry obfEntry )
488 { 553 {
489 if( obfEntry instanceof ClassEntry ) 554 return m_jarIndex.containsObfEntry( obfEntry );
490 {
491 return m_jarIndex.getObfClassEntries().contains( obfEntry );
492 }
493 else
494 {
495 return isObfuscatedIdentifier( obfEntry.getClassEntry() );
496 }
497 } 555 }
498} 556}