diff options
| author | 2018-10-25 00:01:49 +0200 | |
|---|---|---|
| committer | 2018-10-25 00:01:49 +0200 | |
| commit | 9274c5c862e6a38b37ff2d11f468a6a98cc47daf (patch) | |
| tree | 0d4cb774e77848112368a12bba42c7be0ed1f8fb /src | |
| parent | Merge pull request #62 from OpenModLoader/asm (diff) | |
| parent | recursively check ClassMapping dirty state (diff) | |
| download | enigma-9274c5c862e6a38b37ff2d11f468a6a98cc47daf.tar.gz enigma-9274c5c862e6a38b37ff2d11f468a6a98cc47daf.tar.xz enigma-9274c5c862e6a38b37ff2d11f468a6a98cc47daf.zip | |
make rebuild method names discard child-only names. imperfect, but eh
Diffstat (limited to 'src')
4 files changed, 105 insertions, 17 deletions
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java index 6ea1c40b..5980f1fc 100644 --- a/src/main/java/cuchaz/enigma/Deobfuscator.java +++ b/src/main/java/cuchaz/enigma/Deobfuscator.java | |||
| @@ -34,6 +34,7 @@ import cuchaz.enigma.mapping.entry.*; | |||
| 34 | import cuchaz.enigma.throwables.IllegalNameException; | 34 | import cuchaz.enigma.throwables.IllegalNameException; |
| 35 | import cuchaz.enigma.utils.Utils; | 35 | import cuchaz.enigma.utils.Utils; |
| 36 | import oml.ast.transformers.ObfuscatedEnumSwitchRewriterTransform; | 36 | import oml.ast.transformers.ObfuscatedEnumSwitchRewriterTransform; |
| 37 | import oml.ast.transformers.RemoveObjectCasts; | ||
| 37 | import org.objectweb.asm.ClassWriter; | 38 | import org.objectweb.asm.ClassWriter; |
| 38 | import org.objectweb.asm.Opcodes; | 39 | import org.objectweb.asm.Opcodes; |
| 39 | import org.objectweb.asm.tree.ClassNode; | 40 | import org.objectweb.asm.tree.ClassNode; |
| @@ -324,6 +325,21 @@ public class Deobfuscator { | |||
| 324 | } | 325 | } |
| 325 | } | 326 | } |
| 326 | 327 | ||
| 328 | public boolean isMethodProvider(MethodEntry methodEntry) { | ||
| 329 | Set<ClassEntry> classEntries = new HashSet<>(); | ||
| 330 | addAllPotentialAncestors(classEntries, methodEntry.getOwnerClassEntry()); | ||
| 331 | |||
| 332 | for (ClassEntry parentEntry : classEntries) { | ||
| 333 | MethodEntry ancestorMethodEntry = entryPool.getMethod(parentEntry, methodEntry.getName(), methodEntry.getDesc()); | ||
| 334 | if (jarIndex.containsObfMethod(ancestorMethodEntry)) { | ||
| 335 | return false; | ||
| 336 | } | ||
| 337 | } | ||
| 338 | |||
| 339 | return true; | ||
| 340 | } | ||
| 341 | |||
| 342 | @Deprecated | ||
| 327 | public boolean isMethodProvider(ClassEntry classObfEntry, MethodEntry methodEntry) { | 343 | public boolean isMethodProvider(ClassEntry classObfEntry, MethodEntry methodEntry) { |
| 328 | Set<ClassEntry> classEntries = new HashSet<>(); | 344 | Set<ClassEntry> classEntries = new HashSet<>(); |
| 329 | addAllPotentialAncestors(classEntries, classObfEntry); | 345 | addAllPotentialAncestors(classEntries, classObfEntry); |
| @@ -366,10 +382,12 @@ public class Deobfuscator { | |||
| 366 | Entry obfEntry = entry.getKey(); | 382 | Entry obfEntry = entry.getKey(); |
| 367 | String name = entry.getValue(); | 383 | String name = entry.getValue(); |
| 368 | 384 | ||
| 369 | try { | 385 | if (name != null) { |
| 370 | rename(obfEntry, name); | 386 | try { |
| 371 | } catch (IllegalNameException exception) { | 387 | rename(obfEntry, name); |
| 372 | System.out.println("WARNING: " + exception.getMessage()); | 388 | } catch (IllegalNameException exception) { |
| 389 | System.out.println("WARNING: " + exception.getMessage()); | ||
| 390 | } | ||
| 373 | } | 391 | } |
| 374 | } | 392 | } |
| 375 | } | 393 | } |
| @@ -381,15 +399,15 @@ public class Deobfuscator { | |||
| 381 | for (MethodMapping methodMapping : Lists.newArrayList(classMapping.methods())) { | 399 | for (MethodMapping methodMapping : Lists.newArrayList(classMapping.methods())) { |
| 382 | ClassEntry classObfEntry = classMapping.getObfEntry(); | 400 | ClassEntry classObfEntry = classMapping.getObfEntry(); |
| 383 | MethodEntry obfEntry = methodMapping.getObfEntry(classObfEntry); | 401 | MethodEntry obfEntry = methodMapping.getObfEntry(classObfEntry); |
| 402 | boolean isProvider = isMethodProvider(obfEntry); | ||
| 384 | 403 | ||
| 385 | if (isMethodProvider(classObfEntry, obfEntry)) { | 404 | if (hasDeobfuscatedName(obfEntry) |
| 386 | if (hasDeobfuscatedName(obfEntry) | 405 | && !(methodMapping.getDeobfName().equals(methodMapping.getObfName()))) { |
| 387 | && !(methodMapping.getDeobfName().equals(methodMapping.getObfName()))) { | 406 | renameEntries.put(obfEntry, isProvider ? methodMapping.getDeobfName() : null); |
| 388 | renameEntries.put(obfEntry, methodMapping.getDeobfName()); | 407 | } |
| 389 | } | ||
| 390 | 408 | ||
| 391 | ArrayList<LocalVariableMapping> arguments = Lists.newArrayList(methodMapping.arguments()); | 409 | if (isProvider) { |
| 392 | for (LocalVariableMapping localVariableMapping : arguments) { | 410 | for (LocalVariableMapping localVariableMapping : methodMapping.arguments()) { |
| 393 | Entry argObfEntry = localVariableMapping.getObfEntry(obfEntry); | 411 | Entry argObfEntry = localVariableMapping.getObfEntry(obfEntry); |
| 394 | if (hasDeobfuscatedName(argObfEntry)) { | 412 | if (hasDeobfuscatedName(argObfEntry)) { |
| 395 | renameEntries.put(argObfEntry, deobfuscateEntry(argObfEntry).getName()); | 413 | renameEntries.put(argObfEntry, deobfuscateEntry(argObfEntry).getName()); |
| @@ -661,7 +679,8 @@ public class Deobfuscator { | |||
| 661 | 679 | ||
| 662 | public static void runCustomTransforms(AstBuilder builder, DecompilerContext context){ | 680 | public static void runCustomTransforms(AstBuilder builder, DecompilerContext context){ |
| 663 | List<IAstTransform> transformers = Arrays.asList( | 681 | List<IAstTransform> transformers = Arrays.asList( |
| 664 | new ObfuscatedEnumSwitchRewriterTransform(context) | 682 | new ObfuscatedEnumSwitchRewriterTransform(context), |
| 683 | new RemoveObjectCasts(context) | ||
| 665 | ); | 684 | ); |
| 666 | for (IAstTransform transform : transformers){ | 685 | for (IAstTransform transform : transformers){ |
| 667 | transform.run(builder.getCompilationUnit()); | 686 | transform.run(builder.getCompilationUnit()); |
diff --git a/src/main/java/cuchaz/enigma/analysis/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/JarIndex.java index 5917a32f..64ea7950 100644 --- a/src/main/java/cuchaz/enigma/analysis/JarIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/JarIndex.java | |||
| @@ -268,13 +268,34 @@ public class JarIndex { | |||
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | public MethodInheritanceTreeNode getMethodInheritance(Translator deobfuscatingTranslator, MethodEntry obfMethodEntry) { | 270 | public MethodInheritanceTreeNode getMethodInheritance(Translator deobfuscatingTranslator, MethodEntry obfMethodEntry) { |
| 271 | |||
| 272 | // travel to the ancestor implementation | 271 | // travel to the ancestor implementation |
| 272 | LinkedList<ClassEntry> entries = new LinkedList<>(); | ||
| 273 | entries.add(obfMethodEntry.getOwnerClassEntry()); | ||
| 274 | |||
| 275 | // TODO: This could be optimized to not go through interfaces repeatedly... | ||
| 276 | |||
| 273 | ClassEntry baseImplementationClassEntry = obfMethodEntry.getOwnerClassEntry(); | 277 | ClassEntry baseImplementationClassEntry = obfMethodEntry.getOwnerClassEntry(); |
| 274 | for (ClassEntry ancestorClassEntry : this.translationIndex.getAncestry(obfMethodEntry.getOwnerClassEntry())) { | 278 | |
| 279 | for (ClassEntry itf : getInterfaces(obfMethodEntry.getOwnerClassEntry().getClassName())) { | ||
| 280 | MethodEntry itfMethodEntry = entryPool.getMethod(itf, obfMethodEntry.getName(), obfMethodEntry.getDesc().toString()); | ||
| 281 | if (itfMethodEntry != null && containsObfMethod(itfMethodEntry)) { | ||
| 282 | baseImplementationClassEntry = itf; | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 286 | for (ClassEntry ancestorClassEntry : this.translationIndex.getAncestry(entries.remove())) { | ||
| 275 | MethodEntry ancestorMethodEntry = entryPool.getMethod(ancestorClassEntry, obfMethodEntry.getName(), obfMethodEntry.getDesc().toString()); | 287 | MethodEntry ancestorMethodEntry = entryPool.getMethod(ancestorClassEntry, obfMethodEntry.getName(), obfMethodEntry.getDesc().toString()); |
| 276 | if (ancestorMethodEntry != null && containsObfMethod(ancestorMethodEntry)) { | 288 | if (ancestorMethodEntry != null) { |
| 277 | baseImplementationClassEntry = ancestorClassEntry; | 289 | if (containsObfMethod(ancestorMethodEntry)) { |
| 290 | baseImplementationClassEntry = ancestorClassEntry; | ||
| 291 | } | ||
| 292 | |||
| 293 | for (ClassEntry itf : getInterfaces(ancestorClassEntry.getClassName())) { | ||
| 294 | MethodEntry itfMethodEntry = entryPool.getMethod(itf, obfMethodEntry.getName(), obfMethodEntry.getDesc().toString()); | ||
| 295 | if (itfMethodEntry != null && containsObfMethod(itfMethodEntry)) { | ||
| 296 | baseImplementationClassEntry = itf; | ||
| 297 | } | ||
| 298 | } | ||
| 278 | } | 299 | } |
| 279 | } | 300 | } |
| 280 | 301 | ||
diff --git a/src/main/java/cuchaz/enigma/mapping/ClassMapping.java b/src/main/java/cuchaz/enigma/mapping/ClassMapping.java index 8f3f2b2b..369ba8c6 100644 --- a/src/main/java/cuchaz/enigma/mapping/ClassMapping.java +++ b/src/main/java/cuchaz/enigma/mapping/ClassMapping.java | |||
| @@ -526,7 +526,16 @@ public class ClassMapping implements Comparable<ClassMapping> { | |||
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | public boolean isDirty() { | 528 | public boolean isDirty() { |
| 529 | return isDirty; | 529 | return isDirty || areInnersDirty(); |
| 530 | } | ||
| 531 | |||
| 532 | private boolean areInnersDirty(){ | ||
| 533 | for (ClassMapping c : this.innerClasses()){ | ||
| 534 | if (c.isDirty()){ | ||
| 535 | return true; | ||
| 536 | } | ||
| 537 | } | ||
| 538 | return false; | ||
| 530 | } | 539 | } |
| 531 | 540 | ||
| 532 | public void resetDirty() { | 541 | public void resetDirty() { |
diff --git a/src/main/java/oml/ast/transformers/RemoveObjectCasts.java b/src/main/java/oml/ast/transformers/RemoveObjectCasts.java new file mode 100644 index 00000000..d7c3c4a6 --- /dev/null +++ b/src/main/java/oml/ast/transformers/RemoveObjectCasts.java | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | package oml.ast.transformers; | ||
| 2 | |||
| 3 | import com.strobel.assembler.metadata.BuiltinTypes; | ||
| 4 | import com.strobel.decompiler.DecompilerContext; | ||
| 5 | import com.strobel.decompiler.languages.java.ast.AstNode; | ||
| 6 | import com.strobel.decompiler.languages.java.ast.CastExpression; | ||
| 7 | import com.strobel.decompiler.languages.java.ast.ContextTrackingVisitor; | ||
| 8 | import com.strobel.decompiler.languages.java.ast.transforms.IAstTransform; | ||
| 9 | |||
| 10 | /** | ||
| 11 | * Created by Thiakil on 11/07/2018. | ||
| 12 | */ | ||
| 13 | public class RemoveObjectCasts implements IAstTransform { | ||
| 14 | private final DecompilerContext _context; | ||
| 15 | |||
| 16 | public RemoveObjectCasts(DecompilerContext context) { | ||
| 17 | _context = context; | ||
| 18 | } | ||
| 19 | |||
| 20 | @Override | ||
| 21 | public void run(AstNode compilationUnit) { | ||
| 22 | compilationUnit.acceptVisitor(new Visitor(_context), null); | ||
| 23 | } | ||
| 24 | |||
| 25 | private final static class Visitor extends ContextTrackingVisitor<Void>{ | ||
| 26 | |||
| 27 | protected Visitor(DecompilerContext context) { | ||
| 28 | super(context); | ||
| 29 | } | ||
| 30 | |||
| 31 | @Override | ||
| 32 | public Void visitCastExpression(CastExpression node, Void data) { | ||
| 33 | if (node.getType().toTypeReference().equals(BuiltinTypes.Object)){ | ||
| 34 | node.replaceWith(node.getExpression()); | ||
| 35 | } | ||
| 36 | return super.visitCastExpression(node, data); | ||
| 37 | } | ||
| 38 | } | ||
| 39 | } | ||