diff options
| author | 2014-09-24 01:00:54 -0400 | |
|---|---|---|
| committer | 2014-09-24 01:00:54 -0400 | |
| commit | 8776a8ba38123c822530e5f659c626c8db616217 (patch) | |
| tree | 8138a4e4447552e598bb99cfd8fb23a5f27f840b /src/cuchaz/enigma/Deobfuscator.java | |
| parent | trying to figure out why some mappings to correspond to anything in the jar f... (diff) | |
| download | enigma-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.java | 102 |
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; | |||
| 39 | import cuchaz.enigma.analysis.JarIndex; | 39 | import cuchaz.enigma.analysis.JarIndex; |
| 40 | import cuchaz.enigma.analysis.SourceIndex; | 40 | import cuchaz.enigma.analysis.SourceIndex; |
| 41 | import cuchaz.enigma.analysis.SourceIndexVisitor; | 41 | import cuchaz.enigma.analysis.SourceIndexVisitor; |
| 42 | import cuchaz.enigma.analysis.Token; | ||
| 42 | import cuchaz.enigma.mapping.ArgumentEntry; | 43 | import cuchaz.enigma.mapping.ArgumentEntry; |
| 43 | import cuchaz.enigma.mapping.ClassEntry; | 44 | import cuchaz.enigma.mapping.ClassEntry; |
| 44 | import cuchaz.enigma.mapping.ClassMapping; | 45 | import 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 | } |