From 2fbcf8e5c4eec0aa4a4fc59c7cc8abac33b1429c Mon Sep 17 00:00:00 2001 From: jeff Date: Mon, 19 Jan 2015 22:22:57 -0500 Subject: solved tricky issue with incorrect translation of fields/methods referenced by a subclass instead of the declaring class --- src/cuchaz/enigma/mapping/JavassistUtil.java | 55 +++++++++++++++++++++++++ src/cuchaz/enigma/mapping/Mappings.java | 11 +++-- src/cuchaz/enigma/mapping/MappingsRenamer.java | 6 +-- src/cuchaz/enigma/mapping/Translator.java | 57 ++++++++++++++++---------- 4 files changed, 102 insertions(+), 27 deletions(-) create mode 100644 src/cuchaz/enigma/mapping/JavassistUtil.java (limited to 'src/cuchaz/enigma/mapping') diff --git a/src/cuchaz/enigma/mapping/JavassistUtil.java b/src/cuchaz/enigma/mapping/JavassistUtil.java new file mode 100644 index 0000000..b011e0b --- /dev/null +++ b/src/cuchaz/enigma/mapping/JavassistUtil.java @@ -0,0 +1,55 @@ +package cuchaz.enigma.mapping; + +import javassist.CtBehavior; +import javassist.CtClass; +import javassist.CtConstructor; +import javassist.CtField; +import javassist.CtMethod; +import javassist.bytecode.Descriptor; +import cuchaz.enigma.mapping.BehaviorEntry; +import cuchaz.enigma.mapping.ClassEntry; +import cuchaz.enigma.mapping.ConstructorEntry; +import cuchaz.enigma.mapping.FieldEntry; +import cuchaz.enigma.mapping.MethodEntry; + +public class JavassistUtil { + + public static ClassEntry getClassEntry(CtClass c) { + return new ClassEntry(Descriptor.toJvmName(c.getName())); + } + + public static ClassEntry getSuperclassEntry(CtClass c) { + return new ClassEntry(Descriptor.toJvmName(c.getClassFile().getSuperclass())); + } + + public static MethodEntry getMethodEntry(CtMethod method) { + return new MethodEntry( + getClassEntry(method.getDeclaringClass()), + method.getName(), + method.getMethodInfo().getDescriptor() + ); + } + + public static ConstructorEntry getConstructorEntry(CtConstructor constructor) { + return new ConstructorEntry( + getClassEntry(constructor.getDeclaringClass()), + constructor.getMethodInfo().getDescriptor() + ); + } + + public static BehaviorEntry getBehaviorEntry(CtBehavior behavior) { + if (behavior instanceof CtMethod) { + return getMethodEntry((CtMethod)behavior); + } else if (behavior instanceof CtConstructor) { + return getConstructorEntry((CtConstructor)behavior); + } + throw new Error("behavior is neither Method nor Constructor!"); + } + + public static FieldEntry getFieldEntry(CtField field) { + return new FieldEntry( + getClassEntry(field.getDeclaringClass()), + field.getName() + ); + } +} diff --git a/src/cuchaz/enigma/mapping/Mappings.java b/src/cuchaz/enigma/mapping/Mappings.java index c5e38f4..cc560a8 100644 --- a/src/cuchaz/enigma/mapping/Mappings.java +++ b/src/cuchaz/enigma/mapping/Mappings.java @@ -24,6 +24,7 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import cuchaz.enigma.Util; +import cuchaz.enigma.analysis.TranslationIndex; import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater; public class Mappings implements Serializable { @@ -104,11 +105,11 @@ public class Mappings implements Serializable { return m_classesByDeobf.get(deobfName); } - public Translator getTranslator(TranslationDirection direction) { + public Translator getTranslator(TranslationDirection direction, TranslationIndex index) { switch (direction) { case Deobfuscating: - return new Translator(direction, m_classesByObf); + return new Translator(direction, m_classesByObf, index); case Obfuscating: @@ -122,7 +123,11 @@ public class Mappings implements Serializable { } } - return new Translator(direction, classes); + // translate the translation index + // NOTE: this isn't actually recursive + TranslationIndex deobfIndex = new TranslationIndex(index, getTranslator(TranslationDirection.Deobfuscating, index)); + + return new Translator(direction, classes, deobfIndex); default: throw new Error("Invalid translation direction!"); diff --git a/src/cuchaz/enigma/mapping/MappingsRenamer.java b/src/cuchaz/enigma/mapping/MappingsRenamer.java index cb95f42..3aac65a 100644 --- a/src/cuchaz/enigma/mapping/MappingsRenamer.java +++ b/src/cuchaz/enigma/mapping/MappingsRenamer.java @@ -100,10 +100,10 @@ public class MappingsRenamer { deobfName = NameValidator.validateMethodName(deobfName); for (MethodEntry entry : implementations) { - String deobfSignature = m_mappings.getTranslator(TranslationDirection.Deobfuscating).translateSignature(obf.getSignature()); + String deobfSignature = m_mappings.getTranslator(TranslationDirection.Deobfuscating, m_index.getTranslationIndex()).translateSignature(obf.getSignature()); MethodEntry targetEntry = new MethodEntry(entry.getClassEntry(), deobfName, deobfSignature); if (m_mappings.containsDeobfMethod(entry.getClassEntry(), deobfName, entry.getSignature()) || m_index.containsObfBehavior(targetEntry)) { - String deobfClassName = m_mappings.getTranslator(TranslationDirection.Deobfuscating).translateClass(entry.getClassName()); + String deobfClassName = m_mappings.getTranslator(TranslationDirection.Deobfuscating, m_index.getTranslationIndex()).translateClass(entry.getClassName()); throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); } } @@ -117,7 +117,7 @@ public class MappingsRenamer { deobfName = NameValidator.validateMethodName(deobfName); MethodEntry targetEntry = new MethodEntry(obf.getClassEntry(), deobfName, obf.getSignature()); if (m_mappings.containsDeobfMethod(obf.getClassEntry(), deobfName, obf.getSignature()) || m_index.containsObfBehavior(targetEntry)) { - String deobfClassName = m_mappings.getTranslator(TranslationDirection.Deobfuscating).translateClass(obf.getClassName()); + String deobfClassName = m_mappings.getTranslator(TranslationDirection.Deobfuscating, m_index.getTranslationIndex()).translateClass(obf.getClassName()); throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); } diff --git a/src/cuchaz/enigma/mapping/Translator.java b/src/cuchaz/enigma/mapping/Translator.java index d8d9f48..a5a3e2f 100644 --- a/src/cuchaz/enigma/mapping/Translator.java +++ b/src/cuchaz/enigma/mapping/Translator.java @@ -14,21 +14,24 @@ import java.util.Map; import com.google.common.collect.Maps; +import cuchaz.enigma.analysis.TranslationIndex; import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater; public class Translator { private TranslationDirection m_direction; private Map m_classes; + private TranslationIndex m_index; public Translator() { m_direction = null; m_classes = Maps.newHashMap(); } - public Translator(TranslationDirection direction, Map classes) { + public Translator(TranslationDirection direction, Map classes, TranslationIndex index) { m_direction = direction; m_classes = classes; + m_index = index; } @SuppressWarnings("unchecked") @@ -100,17 +103,22 @@ public class Translator { public String translate(FieldEntry in) { - // look for the class - ClassMapping classMapping = findClassMapping(in.getClassEntry()); - if (classMapping != null) { - - // look for the field - String translatedName = m_direction.choose( - classMapping.getDeobfFieldName(in.getName()), - classMapping.getObfFieldName(in.getName()) - ); - if (translatedName != null) { - return translatedName; + // resolve the class entry + ClassEntry resolvedClassEntry = m_index.resolveEntryClass(in); + if (resolvedClassEntry != null) { + + // look for the class + ClassMapping classMapping = findClassMapping(resolvedClassEntry); + if (classMapping != null) { + + // look for the field + String translatedName = m_direction.choose( + classMapping.getDeobfFieldName(in.getName()), + classMapping.getObfFieldName(in.getName()) + ); + if (translatedName != null) { + return translatedName; + } } } return null; @@ -126,15 +134,22 @@ public class Translator { public String translate(MethodEntry in) { - // look for class - ClassMapping classMapping = findClassMapping(in.getClassEntry()); - if (classMapping != null) { - - // look for the method - MethodMapping methodMapping = m_direction.choose(classMapping.getMethodByObf(in.getName(), in.getSignature()), - classMapping.getMethodByDeobf(in.getName(), translateSignature(in.getSignature()))); - if (methodMapping != null) { - return m_direction.choose(methodMapping.getDeobfName(), methodMapping.getObfName()); + // resolve the class entry + ClassEntry resolvedClassEntry = m_index.resolveEntryClass(in); + if (resolvedClassEntry != null) { + + // look for class + ClassMapping classMapping = findClassMapping(resolvedClassEntry); + if (classMapping != null) { + + // look for the method + MethodMapping methodMapping = m_direction.choose( + classMapping.getMethodByObf(in.getName(), in.getSignature()), + classMapping.getMethodByDeobf(in.getName(), translateSignature(in.getSignature())) + ); + if (methodMapping != null) { + return m_direction.choose(methodMapping.getDeobfName(), methodMapping.getObfName()); + } } } return null; -- cgit v1.2.3