summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java87
1 files changed, 13 insertions, 74 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index 818bfd4..b4ac501 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -114,86 +114,20 @@ public class Deobfuscator {
114 val = new Mappings(); 114 val = new Mappings();
115 } 115 }
116 116
117 // pass 1: look for any classes that got moved to inner classes 117 // drop mappings that don't match the jar
118 Map<String,String> renames = Maps.newHashMap();
119 for (ClassMapping classMapping : val.classes()) {
120 // make sure we strip the packages off of obfuscated inner classes
121 String innerClassName = new ClassEntry(classMapping.getObfName()).getSimpleName();
122 String outerClassName = m_jarIndex.getOuterClass(innerClassName);
123 if (outerClassName != null) {
124 // build the composite class name
125 String newName = outerClassName + "$" + innerClassName;
126
127 // add a rename
128 renames.put(classMapping.getObfName(), newName);
129
130 System.out.println(String.format("Converted class mapping %s to %s", classMapping.getObfName(), newName));
131 }
132 }
133 for (Map.Entry<String,String> entry : renames.entrySet()) {
134 val.renameObfClass(entry.getKey(), entry.getValue());
135 }
136
137 // pass 2: look for fields/methods that are actually declared in superclasses
138 MappingsRenamer renamer = new MappingsRenamer(m_jarIndex, val);
139 for (ClassMapping classMapping : Lists.newArrayList(val.classes())) { 118 for (ClassMapping classMapping : Lists.newArrayList(val.classes())) {
140 ClassEntry obfClassEntry = new ClassEntry(classMapping.getObfName()); 119 if (!checkClassMapping(classMapping)) {
141 120 val.removeClassMapping(classMapping);
142 // fields
143 for (FieldMapping fieldMapping : Lists.newArrayList(classMapping.fields())) {
144 FieldEntry fieldEntry = new FieldEntry(obfClassEntry, fieldMapping.getObfName(), fieldMapping.getObfType());
145 ClassEntry resolvedObfClassEntry = m_jarIndex.getTranslationIndex().resolveEntryClass(fieldEntry);
146 if (resolvedObfClassEntry != null && !resolvedObfClassEntry.equals(fieldEntry.getClassEntry())) {
147 boolean wasMoved = renamer.moveFieldToObfClass(classMapping, fieldMapping, resolvedObfClassEntry);
148 if (wasMoved) {
149 System.out.println(String.format("Moved field %s to class %s", fieldEntry, resolvedObfClassEntry));
150 } else {
151 System.err.println(String.format("WARNING: Would move field %s to class %s but the field was already there. Dropping instead.", fieldEntry, resolvedObfClassEntry));
152 }
153 }
154 } 121 }
155
156 // methods
157 for (MethodMapping methodMapping : Lists.newArrayList(classMapping.methods())) {
158 // skip constructors
159 if (methodMapping.isConstructor()) {
160 continue;
161 }
162
163 MethodEntry methodEntry = new MethodEntry(
164 obfClassEntry,
165 methodMapping.getObfName(),
166 methodMapping.getObfSignature()
167 );
168 ClassEntry resolvedObfClassEntry = m_jarIndex.getTranslationIndex().resolveEntryClass(methodEntry);
169 if (resolvedObfClassEntry != null && !resolvedObfClassEntry.equals(methodEntry.getClassEntry())) {
170 boolean wasMoved = renamer.moveMethodToObfClass(classMapping, methodMapping, resolvedObfClassEntry);
171 if (wasMoved) {
172 System.out.println(String.format("Moved method %s to class %s", methodEntry, resolvedObfClassEntry));
173 } else {
174 System.err.println(String.format("WARNING: Would move method %s to class %s but the method was already there. Dropping instead.", methodEntry, resolvedObfClassEntry));
175 }
176 }
177 }
178
179 // TODO: recurse to inner classes?
180 }
181
182 // drop mappings that don't match the jar
183 List<ClassEntry> unknownClasses = Lists.newArrayList();
184 for (ClassMapping classMapping : val.classes()) {
185 checkClassMapping(unknownClasses, classMapping);
186 }
187 if (!unknownClasses.isEmpty()) {
188 throw new Error("Unable to find classes in jar: " + unknownClasses);
189 } 122 }
190 123
191 m_mappings = val; 124 m_mappings = val;
192 m_renamer = renamer; 125 m_renamer = new MappingsRenamer(m_jarIndex, val);
193 m_translatorCache.clear(); 126 m_translatorCache.clear();
194 } 127 }
195 128
196 private void checkClassMapping(List<ClassEntry> unknownClasses, ClassMapping classMapping) { 129 private boolean checkClassMapping(ClassMapping classMapping) {
130
197 // check the class 131 // check the class
198 ClassEntry classEntry = new ClassEntry(classMapping.getObfName()); 132 ClassEntry classEntry = new ClassEntry(classMapping.getObfName());
199 String outerClassName = m_jarIndex.getOuterClass(classEntry.getSimpleName()); 133 String outerClassName = m_jarIndex.getOuterClass(classEntry.getSimpleName());
@@ -201,7 +135,7 @@ public class Deobfuscator {
201 classEntry = new ClassEntry(outerClassName + "$" + classMapping.getObfName()); 135 classEntry = new ClassEntry(outerClassName + "$" + classMapping.getObfName());
202 } 136 }
203 if (!m_jarIndex.getObfClassEntries().contains(classEntry)) { 137 if (!m_jarIndex.getObfClassEntries().contains(classEntry)) {
204 unknownClasses.add(classEntry); 138 return false;
205 } 139 }
206 140
207 // check the fields 141 // check the fields
@@ -224,8 +158,13 @@ public class Deobfuscator {
224 158
225 // check inner classes 159 // check inner classes
226 for (ClassMapping innerClassMapping : classMapping.innerClasses()) { 160 for (ClassMapping innerClassMapping : classMapping.innerClasses()) {
227 checkClassMapping(unknownClasses, innerClassMapping); 161 if (!checkClassMapping(innerClassMapping)) {
162 System.err.println("WARNING: unable to find inner class " + innerClassMapping + ". dropping mapping.");
163 classMapping.removeInnerClassMapping(innerClassMapping);
164 }
228 } 165 }
166
167 return true;
229 } 168 }
230 169
231 public Translator getTranslator(TranslationDirection direction) { 170 public Translator getTranslator(TranslationDirection direction) {