summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar jeff2015-03-09 11:03:35 -0400
committerGravatar jeff2015-03-09 11:03:35 -0400
commit93c053803404382163d728e044d6dd49e76a5007 (patch)
treea5e8c610185f83550d6ae5df158fe6b619ca096c /src
parentmore tweaks, improvements, and bug fixes (diff)
downloadenigma-93c053803404382163d728e044d6dd49e76a5007.tar.gz
enigma-93c053803404382163d728e044d6dd49e76a5007.tar.xz
enigma-93c053803404382163d728e044d6dd49e76a5007.zip
add tracking for mismatched fields/methods
Diffstat (limited to 'src')
-rw-r--r--src/cuchaz/enigma/ConvertMain.java8
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java74
-rw-r--r--src/cuchaz/enigma/gui/ClassMatchingGui.java (renamed from src/cuchaz/enigma/gui/MatchingGui.java)27
-rw-r--r--src/cuchaz/enigma/mapping/MappingsChecker.java97
4 files changed, 141 insertions, 65 deletions
diff --git a/src/cuchaz/enigma/ConvertMain.java b/src/cuchaz/enigma/ConvertMain.java
index 975cdcc8..2afd9ca9 100644
--- a/src/cuchaz/enigma/ConvertMain.java
+++ b/src/cuchaz/enigma/ConvertMain.java
@@ -10,8 +10,8 @@ import cuchaz.enigma.convert.MappingsConverter;
10import cuchaz.enigma.convert.Matches; 10import cuchaz.enigma.convert.Matches;
11import cuchaz.enigma.convert.MatchesReader; 11import cuchaz.enigma.convert.MatchesReader;
12import cuchaz.enigma.convert.MatchesWriter; 12import cuchaz.enigma.convert.MatchesWriter;
13import cuchaz.enigma.gui.MatchingGui; 13import cuchaz.enigma.gui.ClassMatchingGui;
14import cuchaz.enigma.gui.MatchingGui.SaveListener; 14import cuchaz.enigma.gui.ClassMatchingGui.SaveListener;
15import cuchaz.enigma.mapping.MappingParseException; 15import cuchaz.enigma.mapping.MappingParseException;
16import cuchaz.enigma.mapping.Mappings; 16import cuchaz.enigma.mapping.Mappings;
17import cuchaz.enigma.mapping.MappingsReader; 17import cuchaz.enigma.mapping.MappingsReader;
@@ -58,11 +58,11 @@ public class ConvertMain {
58 Matches matches = MatchesReader.read(matchingFile); 58 Matches matches = MatchesReader.read(matchingFile);
59 System.out.println("Indexing source jar..."); 59 System.out.println("Indexing source jar...");
60 Deobfuscator sourceDeobfuscator = new Deobfuscator(sourceJar); 60 Deobfuscator sourceDeobfuscator = new Deobfuscator(sourceJar);
61 sourceDeobfuscator.setMappings(mappings, false); 61 sourceDeobfuscator.setMappings(mappings);
62 System.out.println("Indexing dest jar..."); 62 System.out.println("Indexing dest jar...");
63 Deobfuscator destDeobfuscator = new Deobfuscator(destJar); 63 Deobfuscator destDeobfuscator = new Deobfuscator(destJar);
64 System.out.println("Starting GUI..."); 64 System.out.println("Starting GUI...");
65 new MatchingGui(matches, sourceDeobfuscator, destDeobfuscator).setSaveListener(new SaveListener() { 65 new ClassMatchingGui(matches, sourceDeobfuscator, destDeobfuscator).setSaveListener(new SaveListener() {
66 @Override 66 @Override
67 public void save(Matches matches) { 67 public void save(Matches matches) {
68 try { 68 try {
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index 9b0d3db4..35cfd0b6 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -26,7 +26,6 @@ import java.util.jar.JarOutputStream;
26import javassist.CtClass; 26import javassist.CtClass;
27import javassist.bytecode.Descriptor; 27import javassist.bytecode.Descriptor;
28 28
29import com.google.common.collect.Lists;
30import com.google.common.collect.Maps; 29import com.google.common.collect.Maps;
31import com.google.common.collect.Sets; 30import com.google.common.collect.Sets;
32import com.strobel.assembler.metadata.MetadataSystem; 31import com.strobel.assembler.metadata.MetadataSystem;
@@ -43,7 +42,6 @@ import com.strobel.decompiler.languages.java.ast.InsertParenthesesVisitor;
43import cuchaz.enigma.analysis.EntryReference; 42import cuchaz.enigma.analysis.EntryReference;
44import cuchaz.enigma.analysis.JarClassIterator; 43import cuchaz.enigma.analysis.JarClassIterator;
45import cuchaz.enigma.analysis.JarIndex; 44import cuchaz.enigma.analysis.JarIndex;
46import cuchaz.enigma.analysis.RelatedMethodChecker;
47import cuchaz.enigma.analysis.SourceIndex; 45import cuchaz.enigma.analysis.SourceIndex;
48import cuchaz.enigma.analysis.SourceIndexVisitor; 46import cuchaz.enigma.analysis.SourceIndexVisitor;
49import cuchaz.enigma.analysis.Token; 47import cuchaz.enigma.analysis.Token;
@@ -53,10 +51,10 @@ import cuchaz.enigma.mapping.ClassEntry;
53import cuchaz.enigma.mapping.ClassMapping; 51import cuchaz.enigma.mapping.ClassMapping;
54import cuchaz.enigma.mapping.ConstructorEntry; 52import cuchaz.enigma.mapping.ConstructorEntry;
55import cuchaz.enigma.mapping.Entry; 53import cuchaz.enigma.mapping.Entry;
56import cuchaz.enigma.mapping.EntryFactory;
57import cuchaz.enigma.mapping.FieldEntry; 54import cuchaz.enigma.mapping.FieldEntry;
58import cuchaz.enigma.mapping.FieldMapping; 55import cuchaz.enigma.mapping.FieldMapping;
59import cuchaz.enigma.mapping.Mappings; 56import cuchaz.enigma.mapping.Mappings;
57import cuchaz.enigma.mapping.MappingsChecker;
60import cuchaz.enigma.mapping.MappingsRenamer; 58import cuchaz.enigma.mapping.MappingsRenamer;
61import cuchaz.enigma.mapping.MethodEntry; 59import cuchaz.enigma.mapping.MethodEntry;
62import cuchaz.enigma.mapping.MethodMapping; 60import cuchaz.enigma.mapping.MethodMapping;
@@ -125,19 +123,26 @@ public class Deobfuscator {
125 } 123 }
126 124
127 // drop mappings that don't match the jar 125 // drop mappings that don't match the jar
128 RelatedMethodChecker relatedMethodChecker = new RelatedMethodChecker(m_jarIndex); 126 MappingsChecker checker = new MappingsChecker(m_jarIndex);
129 for (ClassMapping classMapping : Lists.newArrayList(val.classes())) { 127 checker.dropBrokenMappings(val);
130 if (!checkClassMapping(relatedMethodChecker, classMapping, warnAboutDrops)) { 128 if (warnAboutDrops) {
131 if (warnAboutDrops) { 129 for (java.util.Map.Entry<ClassEntry,ClassMapping> mapping : checker.getDroppedClassMappings().entrySet()) {
132 System.err.println("WARNING: unable to find class " + classMapping.getObfFullName() + ". dropping mapping"); 130 System.out.println("WARNING: Couldn't find class entry " + mapping.getKey() + " (" + mapping.getValue().getDeobfName() + ") in jar. Mapping was dropped.");
133 } 131 }
134 val.removeClassMapping(classMapping); 132 for (java.util.Map.Entry<ClassEntry,ClassMapping> mapping : checker.getDroppedInnerClassMappings().entrySet()) {
133 System.out.println("WARNING: Couldn't find inner class entry " + mapping.getKey() + " (" + mapping.getValue().getDeobfName() + ") in jar. Mapping was dropped.");
134 }
135 for (java.util.Map.Entry<FieldEntry,FieldMapping> mapping : checker.getDroppedFieldMappings().entrySet()) {
136 System.out.println("WARNING: Couldn't find field entry " + mapping.getKey() + " (" + mapping.getValue().getDeobfName() + ") in jar. Mapping was dropped.");
137 }
138 for (java.util.Map.Entry<BehaviorEntry,MethodMapping> mapping : checker.getDroppedMethodMappings().entrySet()) {
139 System.out.println("WARNING: Couldn't find behavior entry " + mapping.getKey() + " (" + mapping.getValue().getDeobfName() + ") in jar. Mapping was dropped.");
135 } 140 }
136 } 141 }
137 142
138 // check for related method inconsistencies 143 // check for related method inconsistencies
139 if (relatedMethodChecker.hasProblems()) { 144 if (checker.getRelatedMethodChecker().hasProblems()) {
140 throw new Error("Related methods are inconsistent! Need to fix the mappings manually.\n" + relatedMethodChecker.getReport()); 145 throw new Error("Related methods are inconsistent! Need to fix the mappings manually.\n" + checker.getRelatedMethodChecker().getReport());
141 } 146 }
142 147
143 m_mappings = val; 148 m_mappings = val;
@@ -145,51 +150,6 @@ public class Deobfuscator {
145 m_translatorCache.clear(); 150 m_translatorCache.clear();
146 } 151 }
147 152
148 private boolean checkClassMapping(RelatedMethodChecker relatedMethodChecker, ClassMapping classMapping, boolean warnAboutDrops) {
149
150 // check the class
151 ClassEntry classEntry = EntryFactory.getObfClassEntry(m_jarIndex, classMapping);
152 if (!m_jarIndex.getObfClassEntries().contains(classEntry)) {
153 return false;
154 }
155
156 // check the fields
157 for (FieldMapping fieldMapping : Lists.newArrayList(classMapping.fields())) {
158 FieldEntry fieldEntry = new FieldEntry(classEntry, fieldMapping.getObfName(), fieldMapping.getObfType());
159 if (!m_jarIndex.containsObfField(fieldEntry)) {
160 if (warnAboutDrops) {
161 System.err.println("WARNING: unable to find field " + fieldEntry + ". dropping mapping.");
162 }
163 classMapping.removeFieldMapping(fieldMapping);
164 }
165 }
166
167 // check methods
168 for (MethodMapping methodMapping : Lists.newArrayList(classMapping.methods())) {
169 BehaviorEntry obfBehaviorEntry = EntryFactory.getObfBehaviorEntry(classEntry, methodMapping);
170 if (!m_jarIndex.containsObfBehavior(obfBehaviorEntry)) {
171 if (warnAboutDrops) {
172 System.err.println("WARNING: unable to find behavior " + obfBehaviorEntry + ". dropping mapping.");
173 }
174 classMapping.removeMethodMapping(methodMapping);
175 }
176
177 relatedMethodChecker.checkMethod(classEntry, methodMapping);
178 }
179
180 // check inner classes
181 for (ClassMapping innerClassMapping : Lists.newArrayList(classMapping.innerClasses())) {
182 if (!checkClassMapping(relatedMethodChecker, innerClassMapping, warnAboutDrops)) {
183 if (warnAboutDrops) {
184 System.err.println("WARNING: unable to find inner class " + EntryFactory.getObfClassEntry(m_jarIndex, classMapping) + ". dropping mapping.");
185 }
186 classMapping.removeInnerClassMapping(innerClassMapping);
187 }
188 }
189
190 return true;
191 }
192
193 public Translator getTranslator(TranslationDirection direction) { 153 public Translator getTranslator(TranslationDirection direction) {
194 Translator translator = m_translatorCache.get(direction); 154 Translator translator = m_translatorCache.get(direction);
195 if (translator == null) { 155 if (translator == null) {
diff --git a/src/cuchaz/enigma/gui/MatchingGui.java b/src/cuchaz/enigma/gui/ClassMatchingGui.java
index 85842c12..ff7cda99 100644
--- a/src/cuchaz/enigma/gui/MatchingGui.java
+++ b/src/cuchaz/enigma/gui/ClassMatchingGui.java
@@ -44,10 +44,12 @@ import cuchaz.enigma.convert.Matches;
44import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener; 44import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener;
45import cuchaz.enigma.mapping.ClassEntry; 45import cuchaz.enigma.mapping.ClassEntry;
46import cuchaz.enigma.mapping.Entry; 46import cuchaz.enigma.mapping.Entry;
47import cuchaz.enigma.mapping.Mappings;
48import cuchaz.enigma.mapping.MappingsChecker;
47import de.sciss.syntaxpane.DefaultSyntaxKit; 49import de.sciss.syntaxpane.DefaultSyntaxKit;
48 50
49 51
50public class MatchingGui { 52public class ClassMatchingGui {
51 53
52 private static enum SourceType { 54 private static enum SourceType {
53 Matched { 55 Matched {
@@ -112,7 +114,7 @@ public class MatchingGui {
112 private SourceType m_sourceType; 114 private SourceType m_sourceType;
113 private SaveListener m_saveListener; 115 private SaveListener m_saveListener;
114 116
115 public MatchingGui(Matches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { 117 public ClassMatchingGui(Matches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) {
116 118
117 m_matches = matches; 119 m_matches = matches;
118 m_sourceDeobfuscator = sourceDeobfuscator; 120 m_sourceDeobfuscator = sourceDeobfuscator;
@@ -263,12 +265,29 @@ public class MatchingGui {
263 } 265 }
264 266
265 private void updateDestMappings() { 267 private void updateDestMappings() {
266 m_destDeobfuscator.setMappings(MappingsConverter.newMappings( 268
269 Mappings newMappings = MappingsConverter.newMappings(
267 m_matches, 270 m_matches,
268 m_sourceDeobfuscator.getMappings(), 271 m_sourceDeobfuscator.getMappings(),
269 m_sourceDeobfuscator, 272 m_sourceDeobfuscator,
270 m_destDeobfuscator 273 m_destDeobfuscator
271 ), false); 274 );
275
276 // look for dropped mappings
277 MappingsChecker checker = new MappingsChecker(m_destDeobfuscator.getJarIndex());
278 checker.dropBrokenMappings(newMappings);
279
280 // count them
281 int numDroppedFields = checker.getDroppedFieldMappings().size();
282 int numDroppedMethods = checker.getDroppedMethodMappings().size();
283 System.out.println(String.format(
284 "%d mappings from matched classes don't match the dest jar:\n\t%5d fields\n\t%5d methods",
285 numDroppedFields + numDroppedMethods,
286 numDroppedFields,
287 numDroppedMethods
288 ));
289
290 m_destDeobfuscator.setMappings(newMappings);
272 } 291 }
273 292
274 protected void setSourceType(SourceType val) { 293 protected void setSourceType(SourceType val) {
diff --git a/src/cuchaz/enigma/mapping/MappingsChecker.java b/src/cuchaz/enigma/mapping/MappingsChecker.java
new file mode 100644
index 00000000..c5ff7a7e
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/MappingsChecker.java
@@ -0,0 +1,97 @@
1package cuchaz.enigma.mapping;
2
3import java.util.Map;
4
5import com.beust.jcommander.internal.Maps;
6import com.google.common.collect.Lists;
7
8import cuchaz.enigma.analysis.JarIndex;
9import cuchaz.enigma.analysis.RelatedMethodChecker;
10
11
12public class MappingsChecker {
13
14 private JarIndex m_index;
15 private RelatedMethodChecker m_relatedMethodChecker;
16 private Map<ClassEntry,ClassMapping> m_droppedClassMappings;
17 private Map<ClassEntry,ClassMapping> m_droppedInnerClassMappings;
18 private Map<FieldEntry,FieldMapping> m_droppedFieldMappings;
19 private Map<BehaviorEntry,MethodMapping> m_droppedMethodMappings;
20
21 public MappingsChecker(JarIndex index) {
22 m_index = index;
23 m_relatedMethodChecker = new RelatedMethodChecker(m_index);
24 m_droppedClassMappings = Maps.newHashMap();
25 m_droppedInnerClassMappings = Maps.newHashMap();
26 m_droppedFieldMappings = Maps.newHashMap();
27 m_droppedMethodMappings = Maps.newHashMap();
28 }
29
30 public RelatedMethodChecker getRelatedMethodChecker() {
31 return m_relatedMethodChecker;
32 }
33
34 public Map<ClassEntry,ClassMapping> getDroppedClassMappings() {
35 return m_droppedClassMappings;
36 }
37
38 public Map<ClassEntry,ClassMapping> getDroppedInnerClassMappings() {
39 return m_droppedInnerClassMappings;
40 }
41
42 public Map<FieldEntry,FieldMapping> getDroppedFieldMappings() {
43 return m_droppedFieldMappings;
44 }
45
46 public Map<BehaviorEntry,MethodMapping> getDroppedMethodMappings() {
47 return m_droppedMethodMappings;
48 }
49
50 public void dropBrokenMappings(Mappings mappings) {
51 for (ClassMapping classMapping : Lists.newArrayList(mappings.classes())) {
52 if (!checkClassMapping(classMapping)) {
53 mappings.removeClassMapping(classMapping);
54 m_droppedClassMappings.put(EntryFactory.getObfClassEntry(m_index, classMapping), classMapping);
55 }
56 }
57 }
58
59 private boolean checkClassMapping(ClassMapping classMapping) {
60
61 // check the class
62 ClassEntry classEntry = EntryFactory.getObfClassEntry(m_index, classMapping);
63 if (!m_index.getObfClassEntries().contains(classEntry)) {
64 return false;
65 }
66
67 // check the fields
68 for (FieldMapping fieldMapping : Lists.newArrayList(classMapping.fields())) {
69 FieldEntry obfFieldEntry = new FieldEntry(classEntry, fieldMapping.getObfName(), fieldMapping.getObfType());
70 if (!m_index.containsObfField(obfFieldEntry)) {
71 classMapping.removeFieldMapping(fieldMapping);
72 m_droppedFieldMappings.put(obfFieldEntry, fieldMapping);
73 }
74 }
75
76 // check methods
77 for (MethodMapping methodMapping : Lists.newArrayList(classMapping.methods())) {
78 BehaviorEntry obfBehaviorEntry = EntryFactory.getObfBehaviorEntry(classEntry, methodMapping);
79 if (!m_index.containsObfBehavior(obfBehaviorEntry)) {
80 classMapping.removeMethodMapping(methodMapping);
81 m_droppedMethodMappings.put(obfBehaviorEntry, methodMapping);
82 }
83
84 m_relatedMethodChecker.checkMethod(classEntry, methodMapping);
85 }
86
87 // check inner classes
88 for (ClassMapping innerClassMapping : Lists.newArrayList(classMapping.innerClasses())) {
89 if (!checkClassMapping(innerClassMapping)) {
90 classMapping.removeInnerClassMapping(innerClassMapping);
91 m_droppedInnerClassMappings.put(EntryFactory.getObfClassEntry(m_index, innerClassMapping), innerClassMapping);
92 }
93 }
94
95 return true;
96 }
97}