diff options
Diffstat (limited to 'src/main/java/cuchaz/enigma/Deobfuscator.java')
| -rw-r--r-- | src/main/java/cuchaz/enigma/Deobfuscator.java | 91 |
1 files changed, 88 insertions, 3 deletions
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java index b3fb315..2207999 100644 --- a/src/main/java/cuchaz/enigma/Deobfuscator.java +++ b/src/main/java/cuchaz/enigma/Deobfuscator.java | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | package cuchaz.enigma; | 11 | package cuchaz.enigma; |
| 12 | 12 | ||
| 13 | import com.google.common.base.Charsets; | 13 | import com.google.common.base.Charsets; |
| 14 | import com.google.common.collect.Lists; | ||
| 14 | import com.google.common.collect.Maps; | 15 | import com.google.common.collect.Maps; |
| 15 | import com.google.common.collect.Sets; | 16 | import com.google.common.collect.Sets; |
| 16 | import com.strobel.assembler.metadata.MetadataSystem; | 17 | import com.strobel.assembler.metadata.MetadataSystem; |
| @@ -32,9 +33,7 @@ import javassist.CtClass; | |||
| 32 | import javassist.bytecode.Descriptor; | 33 | import javassist.bytecode.Descriptor; |
| 33 | 34 | ||
| 34 | import java.io.*; | 35 | import java.io.*; |
| 35 | import java.util.List; | 36 | import java.util.*; |
| 36 | import java.util.Map; | ||
| 37 | import java.util.Set; | ||
| 38 | import java.util.jar.JarEntry; | 37 | import java.util.jar.JarEntry; |
| 39 | import java.util.jar.JarFile; | 38 | import java.util.jar.JarFile; |
| 40 | import java.util.jar.JarOutputStream; | 39 | import java.util.jar.JarOutputStream; |
| @@ -297,6 +296,92 @@ public class Deobfuscator { | |||
| 297 | } | 296 | } |
| 298 | } | 297 | } |
| 299 | 298 | ||
| 299 | private void addAllPotentialAncestors(Set<ClassEntry> classEntries, ClassEntry classObfEntry) { | ||
| 300 | for (ClassEntry interfaceEntry : jarIndex.getTranslationIndex().getInterfaces(classObfEntry)) { | ||
| 301 | if (classEntries.add(interfaceEntry)) { | ||
| 302 | addAllPotentialAncestors(classEntries, interfaceEntry); | ||
| 303 | } | ||
| 304 | } | ||
| 305 | |||
| 306 | ClassEntry superClassEntry = jarIndex.getTranslationIndex().getSuperclass(classObfEntry); | ||
| 307 | if (superClassEntry != null && classEntries.add(superClassEntry)) { | ||
| 308 | addAllPotentialAncestors(classEntries, superClassEntry); | ||
| 309 | } | ||
| 310 | } | ||
| 311 | |||
| 312 | private boolean isBehaviorProvider(ClassEntry classObfEntry, BehaviorEntry behaviorEntry) { | ||
| 313 | if (behaviorEntry instanceof MethodEntry) { | ||
| 314 | MethodEntry methodEntry = (MethodEntry) behaviorEntry; | ||
| 315 | |||
| 316 | Set<ClassEntry> classEntries = new HashSet<>(); | ||
| 317 | addAllPotentialAncestors(classEntries, classObfEntry); | ||
| 318 | |||
| 319 | for (ClassEntry parentEntry : classEntries) { | ||
| 320 | MethodEntry ancestorMethodEntry = new MethodEntry(parentEntry, methodEntry.getName(), methodEntry.getSignature()); | ||
| 321 | if (jarIndex.containsObfBehavior(ancestorMethodEntry)) { | ||
| 322 | return false; | ||
| 323 | } | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | return true; | ||
| 328 | } | ||
| 329 | |||
| 330 | public void rebuildMethodNames(ProgressListener progress) { | ||
| 331 | int i = 0; | ||
| 332 | Map<ClassMapping, Map<Entry, String>> renameClassMap = new HashMap<>(); | ||
| 333 | |||
| 334 | progress.init(getMappings().classes().size() * 3, "Rebuilding method names"); | ||
| 335 | |||
| 336 | for (ClassMapping classMapping : Lists.newArrayList(getMappings().classes())) { | ||
| 337 | Map<Entry, String> renameEntries = new HashMap<>(); | ||
| 338 | |||
| 339 | progress.onProgress(i++, classMapping.getDeobfName()); | ||
| 340 | |||
| 341 | for (MethodMapping methodMapping : Lists.newArrayList(classMapping.methods())) { | ||
| 342 | ClassEntry classObfEntry = classMapping.getObfEntry(); | ||
| 343 | BehaviorEntry obfEntry = methodMapping.getObfEntry(classObfEntry); | ||
| 344 | |||
| 345 | if (isBehaviorProvider(classObfEntry, obfEntry)) { | ||
| 346 | if (hasDeobfuscatedName(obfEntry) && !(obfEntry instanceof ConstructorEntry) | ||
| 347 | && !(methodMapping.getDeobfName().equals(methodMapping.getObfName()))) { | ||
| 348 | renameEntries.put(obfEntry, methodMapping.getDeobfName()); | ||
| 349 | } | ||
| 350 | |||
| 351 | for (ArgumentMapping argumentMapping : Lists.newArrayList(methodMapping.arguments())) { | ||
| 352 | Entry argObfEntry = argumentMapping.getObfEntry(obfEntry); | ||
| 353 | if (hasDeobfuscatedName(argObfEntry)) { | ||
| 354 | renameEntries.put(argObfEntry, deobfuscateEntry(argObfEntry).getName()); | ||
| 355 | } | ||
| 356 | } | ||
| 357 | } | ||
| 358 | } | ||
| 359 | |||
| 360 | renameClassMap.put(classMapping, renameEntries); | ||
| 361 | } | ||
| 362 | |||
| 363 | for (Map.Entry<ClassMapping, Map<Entry, String>> renameClassMapEntry : renameClassMap.entrySet()) { | ||
| 364 | progress.onProgress(i++, renameClassMapEntry.getKey().getDeobfName()); | ||
| 365 | |||
| 366 | for (Map.Entry<Entry, String> entry : renameClassMapEntry.getValue().entrySet()) { | ||
| 367 | Entry obfEntry = entry.getKey(); | ||
| 368 | |||
| 369 | removeMapping(obfEntry); | ||
| 370 | } | ||
| 371 | } | ||
| 372 | |||
| 373 | for (Map.Entry<ClassMapping, Map<Entry, String>> renameClassMapEntry : renameClassMap.entrySet()) { | ||
| 374 | progress.onProgress(i++, renameClassMapEntry.getKey().getDeobfName()); | ||
| 375 | |||
| 376 | for (Map.Entry<Entry, String> entry : renameClassMapEntry.getValue().entrySet()) { | ||
| 377 | Entry obfEntry = entry.getKey(); | ||
| 378 | String name = entry.getValue(); | ||
| 379 | |||
| 380 | rename(obfEntry, name); | ||
| 381 | } | ||
| 382 | } | ||
| 383 | } | ||
| 384 | |||
| 300 | public void writeJar(File out, ProgressListener progress) { | 385 | public void writeJar(File out, ProgressListener progress) { |
| 301 | final TranslatingTypeLoader loader = new TranslatingTypeLoader( | 386 | final TranslatingTypeLoader loader = new TranslatingTypeLoader( |
| 302 | this.jar, | 387 | this.jar, |