From 2dc7428e37bdd7a119f53d02ce157675509b0d63 Mon Sep 17 00:00:00 2001 From: jeff Date: Mon, 23 Feb 2015 23:29:22 -0500 Subject: lots of work in better handling of inner classes also working on recognizing unobfuscated and deobfuscated jars (needed for M3L) --- src/cuchaz/enigma/mapping/Translator.java | 154 ++++++++++++++++++++++-------- 1 file changed, 115 insertions(+), 39 deletions(-) (limited to 'src/cuchaz/enigma/mapping/Translator.java') diff --git a/src/cuchaz/enigma/mapping/Translator.java b/src/cuchaz/enigma/mapping/Translator.java index 759dddf..d985032 100644 --- a/src/cuchaz/enigma/mapping/Translator.java +++ b/src/cuchaz/enigma/mapping/Translator.java @@ -10,8 +10,10 @@ ******************************************************************************/ package cuchaz.enigma.mapping; +import java.util.List; import java.util.Map; +import com.beust.jcommander.internal.Lists; import com.google.common.collect.Maps; import cuchaz.enigma.analysis.TranslationIndex; @@ -50,54 +52,106 @@ public class Translator { } } + public String translate(T entry) { + if (entry instanceof ClassEntry) { + return translate((ClassEntry)entry); + } else if (entry instanceof FieldEntry) { + return translate((FieldEntry)entry); + } else if (entry instanceof MethodEntry) { + return translate((MethodEntry)entry); + } else if (entry instanceof ConstructorEntry) { + return translate((ConstructorEntry)entry); + } else if (entry instanceof ArgumentEntry) { + return translate((ArgumentEntry)entry); + } else { + throw new Error("Unknown entry type: " + entry.getClass().getName()); + } + } + public String translateClass(String className) { return translate(new ClassEntry(className)); } public String translate(ClassEntry in) { - ClassMapping classMapping = m_classes.get(in.getOuterClassName()); - if (classMapping != null) { - if (in.isInnerClass()) { - // translate the inner class - String translatedInnerClassName = m_direction.choose( - classMapping.getDeobfInnerClassName(in.getInnerClassName()), - classMapping.getObfInnerClassName(in.getInnerClassName()) + + if (in.isInnerClass()) { + + // translate everything in the class chain, or return null + List mappingsChain = getClassMappingChain(in); + StringBuilder buf = new StringBuilder(); + for (ClassMapping classMapping : mappingsChain) { + if (classMapping == null) { + return null; + } + boolean isFirstClass = buf.length() == 0; + String name = m_direction.choose( + classMapping.getDeobfName(), + isFirstClass ? classMapping.getObfFullName() : classMapping.getObfSimpleName() ); - if (translatedInnerClassName != null) { - // try to translate the outer name - String translatedOuterClassName = m_direction.choose(classMapping.getDeobfName(), classMapping.getObfName()); - if (translatedOuterClassName != null) { - return translatedOuterClassName + "$" + translatedInnerClassName; - } else { - return in.getOuterClassName() + "$" + translatedInnerClassName; - } + if (name == null) { + return null; + } + if (!isFirstClass) { + buf.append("$"); } - } else { - // just return outer - return m_direction.choose(classMapping.getDeobfName(), classMapping.getObfName()); + buf.append(name); } + return buf.toString(); + + } else { + + // normal classes are easier + ClassMapping classMapping = m_classes.get(in.getName()); + if (classMapping == null) { + return null; + } + return m_direction.choose( + classMapping.getDeobfName(), + classMapping.getObfFullName() + ); } - return null; } public ClassEntry translateEntry(ClassEntry in) { - // can we translate the inner class? - String name = translate(in); - if (name != null) { - return new ClassEntry(name); - } - if (in.isInnerClass()) { - // guess not. just translate the outer class name then - String outerClassName = translate(in.getOuterClassEntry()); - if (outerClassName != null) { - return new ClassEntry(outerClassName + "$" + in.getInnerClassName()); + // translate as much of the class chain as we can + List mappingsChain = getClassMappingChain(in); + String[] obfClassNames = in.getName().split("\\$"); + StringBuilder buf = new StringBuilder(); + for (int i=0; i mappingChain = getClassMappingChain(in); + return mappingChain.get(mappingChain.size() - 1); + } + + private List getClassMappingChain(ClassEntry in) { + + // get a list of all the classes in the hierarchy + String[] parts = in.getName().split("\\$"); + List mappingsChain = Lists.newArrayList(); + + // get mappings for the outer class + ClassMapping outerClassMapping = m_classes.get(parts[0]); + mappingsChain.add(outerClassMapping); + + for (int i=1; i