summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/mapping
diff options
context:
space:
mode:
authorGravatar jeff2015-01-19 22:22:57 -0500
committerGravatar jeff2015-01-19 22:22:57 -0500
commit2fbcf8e5c4eec0aa4a4fc59c7cc8abac33b1429c (patch)
tree0e9c23d6838d3e0299831dbc24b6d736c268cd8b /src/cuchaz/enigma/mapping
parentadded inverse operation for moving classes out of the default package (diff)
downloadenigma-fork-2fbcf8e5c4eec0aa4a4fc59c7cc8abac33b1429c.tar.gz
enigma-fork-2fbcf8e5c4eec0aa4a4fc59c7cc8abac33b1429c.tar.xz
enigma-fork-2fbcf8e5c4eec0aa4a4fc59c7cc8abac33b1429c.zip
solved tricky issue with incorrect translation of fields/methods referenced by a subclass instead of the declaring class
Diffstat (limited to 'src/cuchaz/enigma/mapping')
-rw-r--r--src/cuchaz/enigma/mapping/JavassistUtil.java55
-rw-r--r--src/cuchaz/enigma/mapping/Mappings.java11
-rw-r--r--src/cuchaz/enigma/mapping/MappingsRenamer.java6
-rw-r--r--src/cuchaz/enigma/mapping/Translator.java57
4 files changed, 102 insertions, 27 deletions
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 @@
1package cuchaz.enigma.mapping;
2
3import javassist.CtBehavior;
4import javassist.CtClass;
5import javassist.CtConstructor;
6import javassist.CtField;
7import javassist.CtMethod;
8import javassist.bytecode.Descriptor;
9import cuchaz.enigma.mapping.BehaviorEntry;
10import cuchaz.enigma.mapping.ClassEntry;
11import cuchaz.enigma.mapping.ConstructorEntry;
12import cuchaz.enigma.mapping.FieldEntry;
13import cuchaz.enigma.mapping.MethodEntry;
14
15public class JavassistUtil {
16
17 public static ClassEntry getClassEntry(CtClass c) {
18 return new ClassEntry(Descriptor.toJvmName(c.getName()));
19 }
20
21 public static ClassEntry getSuperclassEntry(CtClass c) {
22 return new ClassEntry(Descriptor.toJvmName(c.getClassFile().getSuperclass()));
23 }
24
25 public static MethodEntry getMethodEntry(CtMethod method) {
26 return new MethodEntry(
27 getClassEntry(method.getDeclaringClass()),
28 method.getName(),
29 method.getMethodInfo().getDescriptor()
30 );
31 }
32
33 public static ConstructorEntry getConstructorEntry(CtConstructor constructor) {
34 return new ConstructorEntry(
35 getClassEntry(constructor.getDeclaringClass()),
36 constructor.getMethodInfo().getDescriptor()
37 );
38 }
39
40 public static BehaviorEntry getBehaviorEntry(CtBehavior behavior) {
41 if (behavior instanceof CtMethod) {
42 return getMethodEntry((CtMethod)behavior);
43 } else if (behavior instanceof CtConstructor) {
44 return getConstructorEntry((CtConstructor)behavior);
45 }
46 throw new Error("behavior is neither Method nor Constructor!");
47 }
48
49 public static FieldEntry getFieldEntry(CtField field) {
50 return new FieldEntry(
51 getClassEntry(field.getDeclaringClass()),
52 field.getName()
53 );
54 }
55}
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;
24import com.google.common.collect.Sets; 24import com.google.common.collect.Sets;
25 25
26import cuchaz.enigma.Util; 26import cuchaz.enigma.Util;
27import cuchaz.enigma.analysis.TranslationIndex;
27import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater; 28import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater;
28 29
29public class Mappings implements Serializable { 30public class Mappings implements Serializable {
@@ -104,11 +105,11 @@ public class Mappings implements Serializable {
104 return m_classesByDeobf.get(deobfName); 105 return m_classesByDeobf.get(deobfName);
105 } 106 }
106 107
107 public Translator getTranslator(TranslationDirection direction) { 108 public Translator getTranslator(TranslationDirection direction, TranslationIndex index) {
108 switch (direction) { 109 switch (direction) {
109 case Deobfuscating: 110 case Deobfuscating:
110 111
111 return new Translator(direction, m_classesByObf); 112 return new Translator(direction, m_classesByObf, index);
112 113
113 case Obfuscating: 114 case Obfuscating:
114 115
@@ -122,7 +123,11 @@ public class Mappings implements Serializable {
122 } 123 }
123 } 124 }
124 125
125 return new Translator(direction, classes); 126 // translate the translation index
127 // NOTE: this isn't actually recursive
128 TranslationIndex deobfIndex = new TranslationIndex(index, getTranslator(TranslationDirection.Deobfuscating, index));
129
130 return new Translator(direction, classes, deobfIndex);
126 131
127 default: 132 default:
128 throw new Error("Invalid translation direction!"); 133 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 {
100 100
101 deobfName = NameValidator.validateMethodName(deobfName); 101 deobfName = NameValidator.validateMethodName(deobfName);
102 for (MethodEntry entry : implementations) { 102 for (MethodEntry entry : implementations) {
103 String deobfSignature = m_mappings.getTranslator(TranslationDirection.Deobfuscating).translateSignature(obf.getSignature()); 103 String deobfSignature = m_mappings.getTranslator(TranslationDirection.Deobfuscating, m_index.getTranslationIndex()).translateSignature(obf.getSignature());
104 MethodEntry targetEntry = new MethodEntry(entry.getClassEntry(), deobfName, deobfSignature); 104 MethodEntry targetEntry = new MethodEntry(entry.getClassEntry(), deobfName, deobfSignature);
105 if (m_mappings.containsDeobfMethod(entry.getClassEntry(), deobfName, entry.getSignature()) || m_index.containsObfBehavior(targetEntry)) { 105 if (m_mappings.containsDeobfMethod(entry.getClassEntry(), deobfName, entry.getSignature()) || m_index.containsObfBehavior(targetEntry)) {
106 String deobfClassName = m_mappings.getTranslator(TranslationDirection.Deobfuscating).translateClass(entry.getClassName()); 106 String deobfClassName = m_mappings.getTranslator(TranslationDirection.Deobfuscating, m_index.getTranslationIndex()).translateClass(entry.getClassName());
107 throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); 107 throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName);
108 } 108 }
109 } 109 }
@@ -117,7 +117,7 @@ public class MappingsRenamer {
117 deobfName = NameValidator.validateMethodName(deobfName); 117 deobfName = NameValidator.validateMethodName(deobfName);
118 MethodEntry targetEntry = new MethodEntry(obf.getClassEntry(), deobfName, obf.getSignature()); 118 MethodEntry targetEntry = new MethodEntry(obf.getClassEntry(), deobfName, obf.getSignature());
119 if (m_mappings.containsDeobfMethod(obf.getClassEntry(), deobfName, obf.getSignature()) || m_index.containsObfBehavior(targetEntry)) { 119 if (m_mappings.containsDeobfMethod(obf.getClassEntry(), deobfName, obf.getSignature()) || m_index.containsObfBehavior(targetEntry)) {
120 String deobfClassName = m_mappings.getTranslator(TranslationDirection.Deobfuscating).translateClass(obf.getClassName()); 120 String deobfClassName = m_mappings.getTranslator(TranslationDirection.Deobfuscating, m_index.getTranslationIndex()).translateClass(obf.getClassName());
121 throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); 121 throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName);
122 } 122 }
123 123
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;
14 14
15import com.google.common.collect.Maps; 15import com.google.common.collect.Maps;
16 16
17import cuchaz.enigma.analysis.TranslationIndex;
17import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater; 18import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater;
18 19
19public class Translator { 20public class Translator {
20 21
21 private TranslationDirection m_direction; 22 private TranslationDirection m_direction;
22 private Map<String,ClassMapping> m_classes; 23 private Map<String,ClassMapping> m_classes;
24 private TranslationIndex m_index;
23 25
24 public Translator() { 26 public Translator() {
25 m_direction = null; 27 m_direction = null;
26 m_classes = Maps.newHashMap(); 28 m_classes = Maps.newHashMap();
27 } 29 }
28 30
29 public Translator(TranslationDirection direction, Map<String,ClassMapping> classes) { 31 public Translator(TranslationDirection direction, Map<String,ClassMapping> classes, TranslationIndex index) {
30 m_direction = direction; 32 m_direction = direction;
31 m_classes = classes; 33 m_classes = classes;
34 m_index = index;
32 } 35 }
33 36
34 @SuppressWarnings("unchecked") 37 @SuppressWarnings("unchecked")
@@ -100,17 +103,22 @@ public class Translator {
100 103
101 public String translate(FieldEntry in) { 104 public String translate(FieldEntry in) {
102 105
103 // look for the class 106 // resolve the class entry
104 ClassMapping classMapping = findClassMapping(in.getClassEntry()); 107 ClassEntry resolvedClassEntry = m_index.resolveEntryClass(in);
105 if (classMapping != null) { 108 if (resolvedClassEntry != null) {
106 109
107 // look for the field 110 // look for the class
108 String translatedName = m_direction.choose( 111 ClassMapping classMapping = findClassMapping(resolvedClassEntry);
109 classMapping.getDeobfFieldName(in.getName()), 112 if (classMapping != null) {
110 classMapping.getObfFieldName(in.getName()) 113
111 ); 114 // look for the field
112 if (translatedName != null) { 115 String translatedName = m_direction.choose(
113 return translatedName; 116 classMapping.getDeobfFieldName(in.getName()),
117 classMapping.getObfFieldName(in.getName())
118 );
119 if (translatedName != null) {
120 return translatedName;
121 }
114 } 122 }
115 } 123 }
116 return null; 124 return null;
@@ -126,15 +134,22 @@ public class Translator {
126 134
127 public String translate(MethodEntry in) { 135 public String translate(MethodEntry in) {
128 136
129 // look for class 137 // resolve the class entry
130 ClassMapping classMapping = findClassMapping(in.getClassEntry()); 138 ClassEntry resolvedClassEntry = m_index.resolveEntryClass(in);
131 if (classMapping != null) { 139 if (resolvedClassEntry != null) {
132 140
133 // look for the method 141 // look for class
134 MethodMapping methodMapping = m_direction.choose(classMapping.getMethodByObf(in.getName(), in.getSignature()), 142 ClassMapping classMapping = findClassMapping(resolvedClassEntry);
135 classMapping.getMethodByDeobf(in.getName(), translateSignature(in.getSignature()))); 143 if (classMapping != null) {
136 if (methodMapping != null) { 144
137 return m_direction.choose(methodMapping.getDeobfName(), methodMapping.getObfName()); 145 // look for the method
146 MethodMapping methodMapping = m_direction.choose(
147 classMapping.getMethodByObf(in.getName(), in.getSignature()),
148 classMapping.getMethodByDeobf(in.getName(), translateSignature(in.getSignature()))
149 );
150 if (methodMapping != null) {
151 return m_direction.choose(methodMapping.getDeobfName(), methodMapping.getObfName());
152 }
138 } 153 }
139 } 154 }
140 return null; 155 return null;