From e27d5967029f4f3da8889dd673ba516dcd9f3ac8 Mon Sep 17 00:00:00 2001
From: gegy1000
Date: Sun, 16 Jun 2019 23:49:25 +0200
Subject: Plugin rework along with API rework: Enigma split from EnigmaProject;
plugins now provide services configurable via a profile
---
src/main/java/cuchaz/enigma/Deobfuscator.java | 435 --------------------------
1 file changed, 435 deletions(-)
delete mode 100644 src/main/java/cuchaz/enigma/Deobfuscator.java
(limited to 'src/main/java/cuchaz/enigma/Deobfuscator.java')
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java
deleted file mode 100644
index 32f7aa7..0000000
--- a/src/main/java/cuchaz/enigma/Deobfuscator.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015 Jeff Martin.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Lesser General Public
- * License v3.0 which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/lgpl.html
- *
- * Contributors:
- * Jeff Martin - initial API and implementation
- ******************************************************************************/
-
-package cuchaz.enigma;
-
-import com.google.common.base.Functions;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.Streams;
-import com.strobel.assembler.metadata.ITypeLoader;
-import com.strobel.assembler.metadata.MetadataSystem;
-import com.strobel.assembler.metadata.TypeDefinition;
-import com.strobel.assembler.metadata.TypeReference;
-import com.strobel.decompiler.DecompilerSettings;
-import com.strobel.decompiler.languages.java.ast.CompilationUnit;
-import cuchaz.enigma.analysis.EntryReference;
-import cuchaz.enigma.analysis.IndexTreeBuilder;
-import cuchaz.enigma.analysis.ParsedJar;
-import cuchaz.enigma.analysis.index.JarIndex;
-import cuchaz.enigma.api.EntryNameProposer;
-import cuchaz.enigma.api.JarProcessor;
-import cuchaz.enigma.bytecode.translators.SourceFixVisitor;
-import cuchaz.enigma.bytecode.translators.TranslationClassVisitor;
-import cuchaz.enigma.translation.Translatable;
-import cuchaz.enigma.translation.Translator;
-import cuchaz.enigma.translation.mapping.*;
-import cuchaz.enigma.translation.mapping.tree.DeltaTrackingTree;
-import cuchaz.enigma.translation.mapping.tree.EntryTree;
-import cuchaz.enigma.translation.representation.entry.ClassEntry;
-import cuchaz.enigma.translation.representation.entry.Entry;
-import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
-import cuchaz.enigma.translation.representation.entry.MethodEntry;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.tree.ClassNode;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.Writer;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.JarOutputStream;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-public class Deobfuscator {
-
- private final ServiceLoader jarProcessors = ServiceLoader.load(JarProcessor.class);
- private final ServiceLoader nameProposers = ServiceLoader.load(EntryNameProposer.class);
-
- private final ParsedJar parsedJar;
- private final JarIndex jarIndex;
- private final IndexTreeBuilder indexTreeBuilder;
-
- private final SourceProvider obfSourceProvider;
-
- private EntryRemapper mapper;
-
- public Deobfuscator(ParsedJar jar, Consumer listener) {
- this.parsedJar = jar;
-
- // build the jar index
- this.jarIndex = JarIndex.empty();
- this.jarIndex.indexJar(this.parsedJar, listener);
-
- listener.accept("Processing jar");
- this.jarProcessors.forEach(processor -> processor.accept(parsedJar, jarIndex));
-
- this.indexTreeBuilder = new IndexTreeBuilder(jarIndex);
-
- listener.accept("Preparing...");
-
- CompiledSourceTypeLoader typeLoader = new CompiledSourceTypeLoader(parsedJar);
- typeLoader.addVisitor(visitor -> new SourceFixVisitor(Opcodes.ASM5, visitor, jarIndex));
-
- this.obfSourceProvider = new SourceProvider(SourceProvider.createSettings(), typeLoader);
-
- // init mappings
- mapper = new EntryRemapper(jarIndex);
- }
-
- public Deobfuscator(JarFile jar, Consumer listener) throws IOException {
- this(new ParsedJar(jar), listener);
- }
-
- public Deobfuscator(ParsedJar jar) {
- this(jar, (msg) -> {
- });
- }
-
- public Deobfuscator(JarFile jar) throws IOException {
- this(jar, (msg) -> {
- });
- }
-
- public Stream getNameProposers() {
- return Streams.stream(nameProposers);
- }
-
- public ParsedJar getJar() {
- return this.parsedJar;
- }
-
- public JarIndex getJarIndex() {
- return this.jarIndex;
- }
-
- public IndexTreeBuilder getIndexTreeBuilder() {
- return indexTreeBuilder;
- }
-
- public EntryRemapper getMapper() {
- return this.mapper;
- }
-
- public void setMappings(EntryTree mappings) {
- setMappings(mappings, ProgressListener.VOID);
- }
-
- public void setMappings(EntryTree mappings, ProgressListener progress) {
- if (mappings != null) {
- Collection> dropped = dropMappings(mappings, progress);
- mapper = new EntryRemapper(jarIndex, mappings);
-
- DeltaTrackingTree obfToDeobf = mapper.getObfToDeobf();
- for (Entry> entry : dropped) {
- obfToDeobf.trackChange(entry);
- }
- } else {
- mapper = new EntryRemapper(jarIndex);
- }
- }
-
- private Collection> dropMappings(EntryTree mappings, ProgressListener progress) {
- // drop mappings that don't match the jar
- MappingsChecker checker = new MappingsChecker(jarIndex, mappings);
- MappingsChecker.Dropped dropped = checker.dropBrokenMappings(progress);
-
- Map, String> droppedMappings = dropped.getDroppedMappings();
- for (Map.Entry, String> mapping : droppedMappings.entrySet()) {
- System.out.println("WARNING: Couldn't find " + mapping.getKey() + " (" + mapping.getValue() + ") in jar. Mapping was dropped.");
- }
-
- return droppedMappings.keySet();
- }
-
- public void getSeparatedClasses(List obfClasses, List deobfClasses) {
- for (ClassEntry obfClassEntry : this.jarIndex.getEntryIndex().getClasses()) {
- // skip inner classes
- if (obfClassEntry.isInnerClass()) {
- continue;
- }
-
- // separate the classes
- ClassEntry deobfClassEntry = mapper.deobfuscate(obfClassEntry);
- if (!deobfClassEntry.equals(obfClassEntry)) {
- // if the class has a mapping, clearly it's deobfuscated
- deobfClasses.add(obfClassEntry);
- } else if (obfClassEntry.getPackageName() != null) {
- // also call it deobufscated if it's not in the none package
- deobfClasses.add(obfClassEntry);
- } else {
- // otherwise, assume it's still obfuscated
- obfClasses.add(obfClassEntry);
- }
- }
- }
-
- public SourceProvider getObfSourceProvider() {
- return obfSourceProvider;
- }
-
- public void writeSources(Path outputDirectory, ProgressListener progress) {
- // get the classes to decompile
- Collection classEntries = jarIndex.getEntryIndex().getClasses();
-
- Stopwatch stopwatch = Stopwatch.createStarted();
-
- try {
- Translator deobfuscator = mapper.getDeobfuscator();
-
- // deobfuscate everything first
- Map translatedNodes = deobfuscateClasses(progress, classEntries, deobfuscator);
-
- decompileClasses(outputDirectory, progress, translatedNodes);
- } finally {
- stopwatch.stop();
-
- System.out.println("writeSources Done in : " + stopwatch.toString());
- }
- }
-
- private Map deobfuscateClasses(ProgressListener progress, Collection classEntries, Translator translator) {
- AtomicInteger count = new AtomicInteger();
- if (progress != null) {
- progress.init(classEntries.size(), "Deobfuscating classes...");
- }
-
- return classEntries.parallelStream()
- .map(entry -> {
- ClassEntry translatedEntry = translator.translate(entry);
- if (progress != null) {
- progress.step(count.getAndIncrement(), translatedEntry.toString());
- }
-
- ClassNode node = parsedJar.getClassNode(entry.getFullName());
- if (node != null) {
- ClassNode translatedNode = new ClassNode();
- node.accept(new TranslationClassVisitor(translator, Opcodes.ASM5, translatedNode));
- return translatedNode;
- }
-
- return null;
- })
- .filter(Objects::nonNull)
- .collect(Collectors.toMap(n -> n.name, Functions.identity()));
- }
-
- private void decompileClasses(Path outputDirectory, ProgressListener progress, Map translatedClasses) {
- Collection decompileClasses = translatedClasses.values().stream()
- .filter(classNode -> classNode.name.indexOf('$') == -1)
- .collect(Collectors.toList());
-
- if (progress != null) {
- progress.init(decompileClasses.size(), "Decompiling classes...");
- }
-
- //create a common instance outside the loop as mappings shouldn't be changing while this is happening
- CompiledSourceTypeLoader typeLoader = new CompiledSourceTypeLoader(translatedClasses::get);
- typeLoader.addVisitor(visitor -> new SourceFixVisitor(Opcodes.ASM5, visitor, jarIndex));
-
- //synchronized to make sure the parallelStream doesn't CME with the cache
- ITypeLoader synchronizedTypeLoader = new SynchronizedTypeLoader(typeLoader);
-
- MetadataSystem metadataSystem = new Deobfuscator.NoRetryMetadataSystem(synchronizedTypeLoader);
-
- //ensures methods are loaded on classload and prevents race conditions
- metadataSystem.setEagerMethodLoadingEnabled(true);
-
- DecompilerSettings settings = SourceProvider.createSettings();
- SourceProvider sourceProvider = new SourceProvider(settings, synchronizedTypeLoader, metadataSystem);
-
- AtomicInteger count = new AtomicInteger();
-
- decompileClasses.parallelStream().forEach(translatedNode -> {
- if (progress != null) {
- progress.step(count.getAndIncrement(), translatedNode.name);
- }
-
- decompileClass(outputDirectory, translatedNode, sourceProvider);
- });
- }
-
- private void decompileClass(Path outputDirectory, ClassNode translatedNode, SourceProvider sourceProvider) {
- try {
- // get the source
- CompilationUnit sourceTree = sourceProvider.getSources(translatedNode.name);
-
- Path path = outputDirectory.resolve(translatedNode.name.replace('.', '/') + ".java");
- Files.createDirectories(path.getParent());
-
- try (Writer writer = Files.newBufferedWriter(path)) {
- sourceProvider.writeSource(writer, sourceTree);
- }
- } catch (Throwable t) {
- // don't crash the whole world here, just log the error and keep going
- // TODO: set up logback via log4j
- System.err.println("Unable to decompile class " + translatedNode.name);
- t.printStackTrace(System.err);
- }
- }
-
- public void writeTransformedJar(File out, ProgressListener progress) {
- Translator deobfuscator = mapper.getDeobfuscator();
- writeTransformedJar(out, progress, (node, visitor) -> {
- ClassEntry entry = new ClassEntry(node.name);
- node.accept(new TranslationClassVisitor(deobfuscator, Opcodes.ASM5, visitor));
- return deobfuscator.translate(entry).getFullName();
- });
- }
-
- public void writeTransformedJar(File out, ProgressListener progress, ClassTransformer transformer) {
- try (JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out))) {
- if (progress != null) {
- progress.init(parsedJar.getClassCount(), "Transforming classes...");
- }
-
- AtomicInteger count = new AtomicInteger();
- parsedJar.visitNode(node -> {
- if (progress != null) {
- progress.step(count.getAndIncrement(), node.name);
- }
-
- try {
- ClassWriter writer = new ClassWriter(0);
- String transformedName = transformer.transform(node, writer);
- outJar.putNextEntry(new JarEntry(transformedName.replace('.', '/') + ".class"));
- outJar.write(writer.toByteArray());
- outJar.closeEntry();
- } catch (Throwable t) {
- throw new Error("Unable to transform class " + node.name, t);
- }
- });
- } catch (IOException ex) {
- throw new Error("Unable to write to Jar file!");
- }
- }
-
- public AccessModifier getModifier(Entry> entry) {
- EntryMapping mapping = mapper.getDeobfMapping(entry);
- if (mapping == null) {
- return AccessModifier.UNCHANGED;
- }
- return mapping.getAccessModifier();
- }
-
- public void changeModifier(Entry> entry, AccessModifier modifier) {
- EntryMapping mapping = mapper.getDeobfMapping(entry);
- if (mapping != null) {
- mapper.mapFromObf(entry, new EntryMapping(mapping.getTargetName(), modifier));
- } else {
- mapper.mapFromObf(entry, new EntryMapping(entry.getName(), modifier));
- }
- }
-
- public boolean isRenamable(Entry> obfEntry) {
- if (obfEntry instanceof MethodEntry) {
- // HACKHACK: Object methods are not obfuscated identifiers
- MethodEntry obfMethodEntry = (MethodEntry) obfEntry;
- String name = obfMethodEntry.getName();
- String sig = obfMethodEntry.getDesc().toString();
- if (name.equals("clone") && sig.equals("()Ljava/lang/Object;")) {
- return false;
- } else if (name.equals("equals") && sig.equals("(Ljava/lang/Object;)Z")) {
- return false;
- } else if (name.equals("finalize") && sig.equals("()V")) {
- return false;
- } else if (name.equals("getClass") && sig.equals("()Ljava/lang/Class;")) {
- return false;
- } else if (name.equals("hashCode") && sig.equals("()I")) {
- return false;
- } else if (name.equals("notify") && sig.equals("()V")) {
- return false;
- } else if (name.equals("notifyAll") && sig.equals("()V")) {
- return false;
- } else if (name.equals("toString") && sig.equals("()Ljava/lang/String;")) {
- return false;
- } else if (name.equals("wait") && sig.equals("()V")) {
- return false;
- } else if (name.equals("wait") && sig.equals("(J)V")) {
- return false;
- } else if (name.equals("wait") && sig.equals("(JI)V")) {
- return false;
- }
- } else if (obfEntry instanceof LocalVariableEntry && !((LocalVariableEntry) obfEntry).isArgument()) {
- return false;
- }
-
- return this.jarIndex.getEntryIndex().hasEntry(obfEntry);
- }
-
- public boolean isRenamable(EntryReference, Entry>> obfReference) {
- return obfReference.isNamed() && isRenamable(obfReference.getNameableEntry());
- }
-
- public boolean isRemapped(Entry> entry) {
- EntryResolver resolver = mapper.getObfResolver();
- DeltaTrackingTree mappings = mapper.getObfToDeobf();
- return resolver.resolveEntry(entry, ResolutionStrategy.RESOLVE_ROOT).stream()
- .anyMatch(mappings::contains);
- }
-
- public void rename(Entry> obfEntry, String newName) {
- mapper.mapFromObf(obfEntry, new EntryMapping(newName));
- }
-
- public void removeMapping(Entry> obfEntry) {
- mapper.removeByObf(obfEntry);
- }
-
- public void markAsDeobfuscated(Entry> obfEntry) {
- mapper.mapFromObf(obfEntry, new EntryMapping(mapper.deobfuscate(obfEntry).getName()));
- }
-
- public T deobfuscate(T translatable) {
- return mapper.deobfuscate(translatable);
- }
-
- public interface ClassTransformer {
- String transform(ClassNode node, ClassVisitor visitor);
- }
-
- public static class NoRetryMetadataSystem extends MetadataSystem {
- private final Set _failedTypes = Collections.newSetFromMap(new ConcurrentHashMap<>());
-
- public NoRetryMetadataSystem(final ITypeLoader typeLoader) {
- super(typeLoader);
- }
-
- @Override
- protected synchronized TypeDefinition resolveType(final String descriptor, final boolean mightBePrimitive) {
- if (_failedTypes.contains(descriptor)) {
- return null;
- }
-
- final TypeDefinition result = super.resolveType(descriptor, mightBePrimitive);
-
- if (result == null) {
- _failedTypes.add(descriptor);
- }
-
- return result;
- }
-
- @Override
- public synchronized TypeDefinition resolve(final TypeReference type) {
- return super.resolve(type);
- }
- }
-}
--
cgit v1.2.3