summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/Deobfuscator.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/cuchaz/enigma/Deobfuscator.java')
-rw-r--r--src/main/java/cuchaz/enigma/Deobfuscator.java120
1 files changed, 58 insertions, 62 deletions
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java
index f917deb..d22260f 100644
--- a/src/main/java/cuchaz/enigma/Deobfuscator.java
+++ b/src/main/java/cuchaz/enigma/Deobfuscator.java
@@ -47,50 +47,46 @@ public class Deobfuscator {
47 void onProgress(int numDone, String message); 47 void onProgress(int numDone, String message);
48 } 48 }
49 49
50 private JarFile m_jar; 50 private JarFile jar;
51 private DecompilerSettings m_settings; 51 private DecompilerSettings settings;
52 private JarIndex m_jarIndex; 52 private JarIndex jarIndex;
53 private Mappings m_mappings; 53 private Mappings mappings;
54 private MappingsRenamer m_renamer; 54 private MappingsRenamer renamer;
55 private Map<TranslationDirection, Translator> m_translatorCache; 55 private Map<TranslationDirection, Translator> translatorCache;
56 56
57 public Deobfuscator(JarFile jar) throws IOException { 57 public Deobfuscator(JarFile jar) {
58 m_jar = jar; 58 this.jar = jar;
59 59
60 // build the jar index 60 // build the jar index
61 m_jarIndex = new JarIndex(); 61 this.jarIndex = new JarIndex();
62 m_jarIndex.indexJar(m_jar, true); 62 this.jarIndex.indexJar(this.jar, true);
63 63
64 // config the decompiler 64 // config the decompiler
65 m_settings = DecompilerSettings.javaDefaults(); 65 this.settings = DecompilerSettings.javaDefaults();
66 m_settings.setMergeVariables(true); 66 this.settings.setMergeVariables(true);
67 m_settings.setForceExplicitImports(true); 67 this.settings.setForceExplicitImports(true);
68 m_settings.setForceExplicitTypeArguments(true); 68 this.settings.setForceExplicitTypeArguments(true);
69 m_settings.setShowDebugLineNumbers(true); 69 this.settings.setShowDebugLineNumbers(true);
70 // DEBUG 70 // DEBUG
71 //m_settings.setShowSyntheticMembers(true); 71 //this.settings.setShowSyntheticMembers(true);
72 72
73 // init defaults 73 // init defaults
74 m_translatorCache = Maps.newTreeMap(); 74 this.translatorCache = Maps.newTreeMap();
75 75
76 // init mappings 76 // init mappings
77 setMappings(new Mappings()); 77 setMappings(new Mappings());
78 } 78 }
79 79
80 public JarFile getJar() {
81 return m_jar;
82 }
83
84 public String getJarName() { 80 public String getJarName() {
85 return m_jar.getName(); 81 return this.jar.getName();
86 } 82 }
87 83
88 public JarIndex getJarIndex() { 84 public JarIndex getJarIndex() {
89 return m_jarIndex; 85 return this.jarIndex;
90 } 86 }
91 87
92 public Mappings getMappings() { 88 public Mappings getMappings() {
93 return m_mappings; 89 return this.mappings;
94 } 90 }
95 91
96 public void setMappings(Mappings val) { 92 public void setMappings(Mappings val) {
@@ -103,7 +99,7 @@ public class Deobfuscator {
103 } 99 }
104 100
105 // drop mappings that don't match the jar 101 // drop mappings that don't match the jar
106 MappingsChecker checker = new MappingsChecker(m_jarIndex); 102 MappingsChecker checker = new MappingsChecker(this.jarIndex);
107 checker.dropBrokenMappings(val); 103 checker.dropBrokenMappings(val);
108 if (warnAboutDrops) { 104 if (warnAboutDrops) {
109 for (java.util.Map.Entry<ClassEntry, ClassMapping> mapping : checker.getDroppedClassMappings().entrySet()) { 105 for (java.util.Map.Entry<ClassEntry, ClassMapping> mapping : checker.getDroppedClassMappings().entrySet()) {
@@ -120,22 +116,22 @@ public class Deobfuscator {
120 } 116 }
121 } 117 }
122 118
123 m_mappings = val; 119 this.mappings = val;
124 m_renamer = new MappingsRenamer(m_jarIndex, val); 120 this.renamer = new MappingsRenamer(this.jarIndex, val);
125 m_translatorCache.clear(); 121 this.translatorCache.clear();
126 } 122 }
127 123
128 public Translator getTranslator(TranslationDirection direction) { 124 public Translator getTranslator(TranslationDirection direction) {
129 Translator translator = m_translatorCache.get(direction); 125 Translator translator = this.translatorCache.get(direction);
130 if (translator == null) { 126 if (translator == null) {
131 translator = m_mappings.getTranslator(direction, m_jarIndex.getTranslationIndex()); 127 translator = this.mappings.getTranslator(direction, this.jarIndex.getTranslationIndex());
132 m_translatorCache.put(direction, translator); 128 this.translatorCache.put(direction, translator);
133 } 129 }
134 return translator; 130 return translator;
135 } 131 }
136 132
137 public void getSeparatedClasses(List<ClassEntry> obfClasses, List<ClassEntry> deobfClasses) { 133 public void getSeparatedClasses(List<ClassEntry> obfClasses, List<ClassEntry> deobfClasses) {
138 for (ClassEntry obfClassEntry : m_jarIndex.getObfClassEntries()) { 134 for (ClassEntry obfClassEntry : this.jarIndex.getObfClassEntries()) {
139 // skip inner classes 135 // skip inner classes
140 if (obfClassEntry.isInnerClass()) { 136 if (obfClassEntry.isInnerClass()) {
141 continue; 137 continue;
@@ -166,19 +162,19 @@ public class Deobfuscator {
166 String deobfClassName = className; 162 String deobfClassName = className;
167 163
168 // if it wasn't actually deobf, then we can find a mapping for it and get the deobf name 164 // if it wasn't actually deobf, then we can find a mapping for it and get the deobf name
169 ClassMapping classMapping = m_mappings.getClassByObf(className); 165 ClassMapping classMapping = this.mappings.getClassByObf(className);
170 if (classMapping != null && classMapping.getDeobfName() != null) { 166 if (classMapping != null && classMapping.getDeobfName() != null) {
171 deobfClassName = classMapping.getDeobfName(); 167 deobfClassName = classMapping.getDeobfName();
172 } 168 }
173 169
174 // set the type loader 170 // set the type loader
175 TranslatingTypeLoader loader = new TranslatingTypeLoader( 171 TranslatingTypeLoader loader = new TranslatingTypeLoader(
176 m_jar, 172 this.jar,
177 m_jarIndex, 173 this.jarIndex,
178 getTranslator(TranslationDirection.Obfuscating), 174 getTranslator(TranslationDirection.Obfuscating),
179 getTranslator(TranslationDirection.Deobfuscating) 175 getTranslator(TranslationDirection.Deobfuscating)
180 ); 176 );
181 m_settings.setTypeLoader(loader); 177 this.settings.setTypeLoader(loader);
182 178
183 // see if procyon can find the type 179 // see if procyon can find the type
184 TypeReference type = new MetadataSystem(loader).lookupType(deobfClassName); 180 TypeReference type = new MetadataSystem(loader).lookupType(deobfClassName);
@@ -192,7 +188,7 @@ public class Deobfuscator {
192 // decompile it! 188 // decompile it!
193 DecompilerContext context = new DecompilerContext(); 189 DecompilerContext context = new DecompilerContext();
194 context.setCurrentType(resolvedType); 190 context.setCurrentType(resolvedType);
195 context.setSettings(m_settings); 191 context.setSettings(this.settings);
196 AstBuilder builder = new AstBuilder(context); 192 AstBuilder builder = new AstBuilder(context);
197 builder.addType(resolvedType); 193 builder.addType(resolvedType);
198 builder.runTransformations(null); 194 builder.runTransformations(null);
@@ -225,7 +221,7 @@ public class Deobfuscator {
225 Entry obfEntry = obfuscateEntry(deobfReference.entry); 221 Entry obfEntry = obfuscateEntry(deobfReference.entry);
226 222
227 // try to resolve the class 223 // try to resolve the class
228 ClassEntry resolvedObfClassEntry = m_jarIndex.getTranslationIndex().resolveEntryClass(obfEntry); 224 ClassEntry resolvedObfClassEntry = this.jarIndex.getTranslationIndex().resolveEntryClass(obfEntry);
229 if (resolvedObfClassEntry != null && !resolvedObfClassEntry.equals(obfEntry.getClassEntry())) { 225 if (resolvedObfClassEntry != null && !resolvedObfClassEntry.equals(obfEntry.getClassEntry())) {
230 // change the class of the entry 226 // change the class of the entry
231 obfEntry = obfEntry.cloneToNewClass(resolvedObfClassEntry); 227 obfEntry = obfEntry.cloneToNewClass(resolvedObfClassEntry);
@@ -246,14 +242,14 @@ public class Deobfuscator {
246 // render the AST into source 242 // render the AST into source
247 StringWriter buf = new StringWriter(); 243 StringWriter buf = new StringWriter();
248 sourceTree.acceptVisitor(new InsertParenthesesVisitor(), null); 244 sourceTree.acceptVisitor(new InsertParenthesesVisitor(), null);
249 sourceTree.acceptVisitor(new JavaOutputVisitor(new PlainTextOutput(buf), m_settings), null); 245 sourceTree.acceptVisitor(new JavaOutputVisitor(new PlainTextOutput(buf), this.settings), null);
250 return buf.toString(); 246 return buf.toString();
251 } 247 }
252 248
253 public void writeSources(File dirOut, ProgressListener progress) throws IOException { 249 public void writeSources(File dirOut, ProgressListener progress) {
254 // get the classes to decompile 250 // get the classes to decompile
255 Set<ClassEntry> classEntries = Sets.newHashSet(); 251 Set<ClassEntry> classEntries = Sets.newHashSet();
256 for (ClassEntry obfClassEntry : m_jarIndex.getObfClassEntries()) { 252 for (ClassEntry obfClassEntry : this.jarIndex.getObfClassEntries()) {
257 // skip inner classes 253 // skip inner classes
258 if (obfClassEntry.isInnerClass()) { 254 if (obfClassEntry.isInnerClass()) {
259 continue; 255 continue;
@@ -298,8 +294,8 @@ public class Deobfuscator {
298 294
299 public void writeJar(File out, ProgressListener progress) { 295 public void writeJar(File out, ProgressListener progress) {
300 final TranslatingTypeLoader loader = new TranslatingTypeLoader( 296 final TranslatingTypeLoader loader = new TranslatingTypeLoader(
301 m_jar, 297 this.jar,
302 m_jarIndex, 298 this.jarIndex,
303 getTranslator(TranslationDirection.Obfuscating), 299 getTranslator(TranslationDirection.Obfuscating),
304 getTranslator(TranslationDirection.Deobfuscating) 300 getTranslator(TranslationDirection.Deobfuscating)
305 ); 301 );
@@ -321,11 +317,11 @@ public class Deobfuscator {
321 private void transformJar(File out, ProgressListener progress, ClassTransformer transformer) { 317 private void transformJar(File out, ProgressListener progress, ClassTransformer transformer) {
322 try (JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out))) { 318 try (JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out))) {
323 if (progress != null) { 319 if (progress != null) {
324 progress.init(JarClassIterator.getClassEntries(m_jar).size(), "Transforming classes..."); 320 progress.init(JarClassIterator.getClassEntries(this.jar).size(), "Transforming classes...");
325 } 321 }
326 322
327 int i = 0; 323 int i = 0;
328 for (CtClass c : JarClassIterator.classes(m_jar)) { 324 for (CtClass c : JarClassIterator.classes(this.jar)) {
329 if (progress != null) { 325 if (progress != null) {
330 progress.onProgress(i++, c.getName()); 326 progress.onProgress(i++, c.getName());
331 } 327 }
@@ -410,7 +406,7 @@ public class Deobfuscator {
410 } 406 }
411 } 407 }
412 408
413 return m_jarIndex.containsObfEntry(obfEntry); 409 return this.jarIndex.containsObfEntry(obfEntry);
414 } 410 }
415 411
416 public boolean isRenameable(EntryReference<Entry, Entry> obfReference) { 412 public boolean isRenameable(EntryReference<Entry, Entry> obfReference) {
@@ -423,7 +419,7 @@ public class Deobfuscator {
423 Translator translator = getTranslator(TranslationDirection.Deobfuscating); 419 Translator translator = getTranslator(TranslationDirection.Deobfuscating);
424 if (obfEntry instanceof ClassEntry) { 420 if (obfEntry instanceof ClassEntry) {
425 ClassEntry obfClass = (ClassEntry) obfEntry; 421 ClassEntry obfClass = (ClassEntry) obfEntry;
426 List<ClassMapping> mappingChain = m_mappings.getClassMappingChain(obfClass); 422 List<ClassMapping> mappingChain = this.mappings.getClassMappingChain(obfClass);
427 ClassMapping classMapping = mappingChain.get(mappingChain.size() - 1); 423 ClassMapping classMapping = mappingChain.get(mappingChain.size() - 1);
428 return classMapping != null && classMapping.getDeobfName() != null; 424 return classMapping != null && classMapping.getDeobfName() != null;
429 } else if (obfEntry instanceof FieldEntry) { 425 } else if (obfEntry instanceof FieldEntry) {
@@ -442,58 +438,58 @@ public class Deobfuscator {
442 438
443 public void rename(Entry obfEntry, String newName) { 439 public void rename(Entry obfEntry, String newName) {
444 if (obfEntry instanceof ClassEntry) { 440 if (obfEntry instanceof ClassEntry) {
445 m_renamer.setClassName((ClassEntry) obfEntry, Descriptor.toJvmName(newName)); 441 this.renamer.setClassName((ClassEntry) obfEntry, Descriptor.toJvmName(newName));
446 } else if (obfEntry instanceof FieldEntry) { 442 } else if (obfEntry instanceof FieldEntry) {
447 m_renamer.setFieldName((FieldEntry) obfEntry, newName); 443 this.renamer.setFieldName((FieldEntry) obfEntry, newName);
448 } else if (obfEntry instanceof MethodEntry) { 444 } else if (obfEntry instanceof MethodEntry) {
449 m_renamer.setMethodTreeName((MethodEntry) obfEntry, newName); 445 this.renamer.setMethodTreeName((MethodEntry) obfEntry, newName);
450 } else if (obfEntry instanceof ConstructorEntry) { 446 } else if (obfEntry instanceof ConstructorEntry) {
451 throw new IllegalArgumentException("Cannot rename constructors"); 447 throw new IllegalArgumentException("Cannot rename constructors");
452 } else if (obfEntry instanceof ArgumentEntry) { 448 } else if (obfEntry instanceof ArgumentEntry) {
453 m_renamer.setArgumentName((ArgumentEntry) obfEntry, newName); 449 this.renamer.setArgumentName((ArgumentEntry) obfEntry, newName);
454 } else { 450 } else {
455 throw new Error("Unknown entry type: " + obfEntry.getClass().getName()); 451 throw new Error("Unknown entry type: " + obfEntry.getClass().getName());
456 } 452 }
457 453
458 // clear caches 454 // clear caches
459 m_translatorCache.clear(); 455 this.translatorCache.clear();
460 } 456 }
461 457
462 public void removeMapping(Entry obfEntry) { 458 public void removeMapping(Entry obfEntry) {
463 if (obfEntry instanceof ClassEntry) { 459 if (obfEntry instanceof ClassEntry) {
464 m_renamer.removeClassMapping((ClassEntry) obfEntry); 460 this.renamer.removeClassMapping((ClassEntry) obfEntry);
465 } else if (obfEntry instanceof FieldEntry) { 461 } else if (obfEntry instanceof FieldEntry) {
466 m_renamer.removeFieldMapping((FieldEntry) obfEntry); 462 this.renamer.removeFieldMapping((FieldEntry) obfEntry);
467 } else if (obfEntry instanceof MethodEntry) { 463 } else if (obfEntry instanceof MethodEntry) {
468 m_renamer.removeMethodTreeMapping((MethodEntry) obfEntry); 464 this.renamer.removeMethodTreeMapping((MethodEntry) obfEntry);
469 } else if (obfEntry instanceof ConstructorEntry) { 465 } else if (obfEntry instanceof ConstructorEntry) {
470 throw new IllegalArgumentException("Cannot rename constructors"); 466 throw new IllegalArgumentException("Cannot rename constructors");
471 } else if (obfEntry instanceof ArgumentEntry) { 467 } else if (obfEntry instanceof ArgumentEntry) {
472 m_renamer.removeArgumentMapping((ArgumentEntry) obfEntry); 468 this.renamer.removeArgumentMapping((ArgumentEntry) obfEntry);
473 } else { 469 } else {
474 throw new Error("Unknown entry type: " + obfEntry); 470 throw new Error("Unknown entry type: " + obfEntry);
475 } 471 }
476 472
477 // clear caches 473 // clear caches
478 m_translatorCache.clear(); 474 this.translatorCache.clear();
479 } 475 }
480 476
481 public void markAsDeobfuscated(Entry obfEntry) { 477 public void markAsDeobfuscated(Entry obfEntry) {
482 if (obfEntry instanceof ClassEntry) { 478 if (obfEntry instanceof ClassEntry) {
483 m_renamer.markClassAsDeobfuscated((ClassEntry) obfEntry); 479 this.renamer.markClassAsDeobfuscated((ClassEntry) obfEntry);
484 } else if (obfEntry instanceof FieldEntry) { 480 } else if (obfEntry instanceof FieldEntry) {
485 m_renamer.markFieldAsDeobfuscated((FieldEntry) obfEntry); 481 this.renamer.markFieldAsDeobfuscated((FieldEntry) obfEntry);
486 } else if (obfEntry instanceof MethodEntry) { 482 } else if (obfEntry instanceof MethodEntry) {
487 m_renamer.markMethodTreeAsDeobfuscated((MethodEntry) obfEntry); 483 this.renamer.markMethodTreeAsDeobfuscated((MethodEntry) obfEntry);
488 } else if (obfEntry instanceof ConstructorEntry) { 484 } else if (obfEntry instanceof ConstructorEntry) {
489 throw new IllegalArgumentException("Cannot rename constructors"); 485 throw new IllegalArgumentException("Cannot rename constructors");
490 } else if (obfEntry instanceof ArgumentEntry) { 486 } else if (obfEntry instanceof ArgumentEntry) {
491 m_renamer.markArgumentAsDeobfuscated((ArgumentEntry) obfEntry); 487 this.renamer.markArgumentAsDeobfuscated((ArgumentEntry) obfEntry);
492 } else { 488 } else {
493 throw new Error("Unknown entry type: " + obfEntry); 489 throw new Error("Unknown entry type: " + obfEntry);
494 } 490 }
495 491
496 // clear caches 492 // clear caches
497 m_translatorCache.clear(); 493 this.translatorCache.clear();
498 } 494 }
499} 495}