summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/Deobfuscator.java
diff options
context:
space:
mode:
authorGravatar asie2018-12-08 11:21:18 +0100
committerGravatar asie2018-12-08 11:21:18 +0100
commit4bc3afe4ff08b9f0c08952ec7f6e0ac930280cc5 (patch)
tree99e43aa385d7fa1248c7fe474c022db55c364592 /src/main/java/cuchaz/enigma/Deobfuscator.java
parentwork around Procyon weirdness (diff)
downloadenigma-fork-4bc3afe4ff08b9f0c08952ec7f6e0ac930280cc5.tar.gz
enigma-fork-4bc3afe4ff08b9f0c08952ec7f6e0ac930280cc5.tar.xz
enigma-fork-4bc3afe4ff08b9f0c08952ec7f6e0ac930280cc5.zip
add barebones plugin framework, cleanup
Diffstat (limited to 'src/main/java/cuchaz/enigma/Deobfuscator.java')
-rw-r--r--src/main/java/cuchaz/enigma/Deobfuscator.java63
1 files changed, 27 insertions, 36 deletions
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java
index 465c1ec..c199225 100644
--- a/src/main/java/cuchaz/enigma/Deobfuscator.java
+++ b/src/main/java/cuchaz/enigma/Deobfuscator.java
@@ -28,8 +28,7 @@ import com.strobel.decompiler.languages.java.ast.CompilationUnit;
28import com.strobel.decompiler.languages.java.ast.InsertParenthesesVisitor; 28import com.strobel.decompiler.languages.java.ast.InsertParenthesesVisitor;
29import com.strobel.decompiler.languages.java.ast.transforms.IAstTransform; 29import com.strobel.decompiler.languages.java.ast.transforms.IAstTransform;
30import cuchaz.enigma.analysis.*; 30import cuchaz.enigma.analysis.*;
31import cuchaz.enigma.bytecode.ClassProtectifier; 31import cuchaz.enigma.api.EnigmaPlugin;
32import cuchaz.enigma.bytecode.ClassPublifier;
33import cuchaz.enigma.mapping.*; 32import cuchaz.enigma.mapping.*;
34import cuchaz.enigma.mapping.entry.*; 33import cuchaz.enigma.mapping.entry.*;
35import cuchaz.enigma.throwables.IllegalNameException; 34import cuchaz.enigma.throwables.IllegalNameException;
@@ -40,19 +39,20 @@ import oml.ast.transformers.ObfuscatedEnumSwitchRewriterTransform;
40import oml.ast.transformers.RemoveObjectCasts; 39import oml.ast.transformers.RemoveObjectCasts;
41import oml.ast.transformers.VarargsFixer; 40import oml.ast.transformers.VarargsFixer;
42import org.objectweb.asm.ClassWriter; 41import org.objectweb.asm.ClassWriter;
43import org.objectweb.asm.Opcodes;
44import org.objectweb.asm.tree.ClassNode; 42import org.objectweb.asm.tree.ClassNode;
45 43
46import java.io.*; 44import java.io.*;
47import java.util.*; 45import java.util.*;
48import java.util.concurrent.ConcurrentHashMap; 46import java.util.concurrent.ConcurrentHashMap;
49import java.util.concurrent.atomic.AtomicInteger; 47import java.util.concurrent.atomic.AtomicInteger;
48import java.util.function.Consumer;
50import java.util.jar.JarEntry; 49import java.util.jar.JarEntry;
51import java.util.jar.JarFile; 50import java.util.jar.JarFile;
52import java.util.jar.JarOutputStream; 51import java.util.jar.JarOutputStream;
53 52
54public class Deobfuscator { 53public class Deobfuscator {
55 54
55 private final ServiceLoader<EnigmaPlugin> plugins = ServiceLoader.load(EnigmaPlugin.class);
56 private final ReferencedEntryPool entryPool = new ReferencedEntryPool(); 56 private final ReferencedEntryPool entryPool = new ReferencedEntryPool();
57 private final ParsedJar parsedJar; 57 private final ParsedJar parsedJar;
58 private final DecompilerSettings settings; 58 private final DecompilerSettings settings;
@@ -61,13 +61,20 @@ public class Deobfuscator {
61 private final Map<TranslationDirection, Translator> translatorCache; 61 private final Map<TranslationDirection, Translator> translatorCache;
62 private Mappings mappings; 62 private Mappings mappings;
63 63
64 public Deobfuscator(ParsedJar jar) { 64 public Deobfuscator(ParsedJar jar, Consumer<String> listener) {
65 this.parsedJar = jar; 65 this.parsedJar = jar;
66 66
67 // build the jar index 67 // build the jar index
68 listener.accept("Indexing JAR...");
68 this.jarIndex = new JarIndex(entryPool); 69 this.jarIndex = new JarIndex(entryPool);
69 this.jarIndex.indexJar(this.parsedJar, true); 70 this.jarIndex.indexJar(this.parsedJar, true);
70 71
72 listener.accept("Initializing plugins...");
73 for (EnigmaPlugin plugin : getPlugins()) {
74 plugin.onClassesLoaded(parsedJar.getClassDataMap(), parsedJar::getClassNode);
75 }
76
77 listener.accept("Preparing...");
71 // config the decompiler 78 // config the decompiler
72 this.settings = DecompilerSettings.javaDefaults(); 79 this.settings = DecompilerSettings.javaDefaults();
73 this.settings.setMergeVariables(Utils.getSystemPropertyAsBoolean("enigma.mergeVariables", true)); 80 this.settings.setMergeVariables(Utils.getSystemPropertyAsBoolean("enigma.mergeVariables", true));
@@ -85,8 +92,20 @@ public class Deobfuscator {
85 setMappings(new Mappings()); 92 setMappings(new Mappings());
86 } 93 }
87 94
88 public Deobfuscator(JarFile jar) throws IOException { 95 public Deobfuscator(JarFile jar, Consumer<String> listener) throws IOException {
89 this(new ParsedJar(jar)); 96 this(new ParsedJar(jar), listener);
97 }
98
99 public Deobfuscator(ParsedJar jar) throws IOException {
100 this(jar, (msg) -> {});
101 }
102
103 public Deobfuscator(JarFile jar) throws IOException {
104 this(jar, (msg) -> {});
105 }
106
107 public ServiceLoader<EnigmaPlugin> getPlugins() {
108 return plugins;
90 } 109 }
91 110
92 public ParsedJar getJar() { 111 public ParsedJar getJar() {
@@ -442,20 +461,6 @@ public class Deobfuscator {
442 transformJar(out, progress, createTypeLoader()::transformInto); 461 transformJar(out, progress, createTypeLoader()::transformInto);
443 } 462 }
444 463
445 public void protectifyJar(File out, ProgressListener progress) {
446 transformJar(out, progress, (node, writer) -> {
447 node.accept(new ClassProtectifier(Opcodes.ASM5, writer));
448 return node.name;
449 });
450 }
451
452 public void publifyJar(File out, ProgressListener progress) {
453 transformJar(out, progress, (node, writer) -> {
454 node.accept(new ClassPublifier(Opcodes.ASM5, writer));
455 return node.name;
456 });
457 }
458
459 public void transformJar(File out, ProgressListener progress, ClassTransformer transformer) { 464 public void transformJar(File out, ProgressListener progress, ClassTransformer transformer) {
460 try (JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out))) { 465 try (JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out))) {
461 if (progress != null) { 466 if (progress != null) {
@@ -463,7 +468,7 @@ public class Deobfuscator {
463 } 468 }
464 469
465 AtomicInteger i = new AtomicInteger(); 470 AtomicInteger i = new AtomicInteger();
466 parsedJar.visit(node -> { 471 parsedJar.visitNode(node -> {
467 if (progress != null) { 472 if (progress != null) {
468 progress.onProgress(i.getAndIncrement(), node.name); 473 progress.onProgress(i.getAndIncrement(), node.name);
469 } 474 }
@@ -524,13 +529,7 @@ public class Deobfuscator {
524 } 529 }
525 530
526 public boolean isObfuscatedIdentifier(Entry obfEntry) { 531 public boolean isObfuscatedIdentifier(Entry obfEntry) {
527 return isObfuscatedIdentifier(obfEntry, false);
528 }
529
530 public boolean isObfuscatedIdentifier(Entry obfEntry, boolean hack) {
531
532 if (obfEntry instanceof MethodEntry) { 532 if (obfEntry instanceof MethodEntry) {
533
534 // HACKHACK: Object methods are not obfuscated identifiers 533 // HACKHACK: Object methods are not obfuscated identifiers
535 MethodEntry obfMethodEntry = (MethodEntry) obfEntry; 534 MethodEntry obfMethodEntry = (MethodEntry) obfEntry;
536 String name = obfMethodEntry.getName(); 535 String name = obfMethodEntry.getName();
@@ -558,21 +557,13 @@ public class Deobfuscator {
558 } else if (name.equals("wait") && sig.equals("(JI)V")) { 557 } else if (name.equals("wait") && sig.equals("(JI)V")) {
559 return false; 558 return false;
560 } 559 }
561
562 // FIXME: HACK EVEN MORE HACK!
563 if (hack && this.jarIndex.containsObfEntry(obfEntry.getOwnerClassEntry()))
564 return true;
565 } 560 }
566 561
567 return this.jarIndex.containsObfEntry(obfEntry); 562 return this.jarIndex.containsObfEntry(obfEntry);
568 } 563 }
569 564
570 public boolean isRenameable(EntryReference<Entry, Entry> obfReference, boolean activeHack) {
571 return obfReference.isNamed() && isObfuscatedIdentifier(obfReference.getNameableEntry(), activeHack);
572 }
573
574 public boolean isRenameable(EntryReference<Entry, Entry> obfReference) { 565 public boolean isRenameable(EntryReference<Entry, Entry> obfReference) {
575 return isRenameable(obfReference, false); 566 return obfReference.isNamed() && isObfuscatedIdentifier(obfReference.getNameableEntry());
576 } 567 }
577 568
578 public boolean hasDeobfuscatedName(Entry obfEntry) { 569 public boolean hasDeobfuscatedName(Entry obfEntry) {