summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/convert
diff options
context:
space:
mode:
authorGravatar jeff2015-03-08 20:48:30 -0400
committerGravatar jeff2015-03-08 20:48:30 -0400
commit4ceb8d490058e48df666bf7227ce020e60928be5 (patch)
treebdfb432cd1d61dc4914b8591468193dcd7e7421c /src/cuchaz/enigma/convert
parentlots of small tweaks and improvements (diff)
downloadenigma-fork-4ceb8d490058e48df666bf7227ce020e60928be5.tar.gz
enigma-fork-4ceb8d490058e48df666bf7227ce020e60928be5.tar.xz
enigma-fork-4ceb8d490058e48df666bf7227ce020e60928be5.zip
more tweaks, improvements, and bug fixes
Diffstat (limited to 'src/cuchaz/enigma/convert')
-rw-r--r--src/cuchaz/enigma/convert/ClassIdentity.java25
-rw-r--r--src/cuchaz/enigma/convert/MappingsConverter.java60
2 files changed, 77 insertions, 8 deletions
diff --git a/src/cuchaz/enigma/convert/ClassIdentity.java b/src/cuchaz/enigma/convert/ClassIdentity.java
index d07e0a4..35667b0 100644
--- a/src/cuchaz/enigma/convert/ClassIdentity.java
+++ b/src/cuchaz/enigma/convert/ClassIdentity.java
@@ -16,6 +16,7 @@ import java.security.NoSuchAlgorithmException;
16import java.util.Enumeration; 16import java.util.Enumeration;
17import java.util.List; 17import java.util.List;
18import java.util.Map; 18import java.util.Map;
19import java.util.Set;
19 20
20import javassist.CannotCompileException; 21import javassist.CannotCompileException;
21import javassist.CtBehavior; 22import javassist.CtBehavior;
@@ -38,6 +39,7 @@ import com.google.common.collect.HashMultiset;
38import com.google.common.collect.Lists; 39import com.google.common.collect.Lists;
39import com.google.common.collect.Maps; 40import com.google.common.collect.Maps;
40import com.google.common.collect.Multiset; 41import com.google.common.collect.Multiset;
42import com.google.common.collect.Sets;
41 43
42import cuchaz.enigma.Constants; 44import cuchaz.enigma.Constants;
43import cuchaz.enigma.Util; 45import cuchaz.enigma.Util;
@@ -67,6 +69,7 @@ public class ClassIdentity {
67 private String m_staticInitializer; 69 private String m_staticInitializer;
68 private String m_extends; 70 private String m_extends;
69 private Multiset<String> m_implements; 71 private Multiset<String> m_implements;
72 private Set<String> m_stringLiterals;
70 private Multiset<String> m_implementations; 73 private Multiset<String> m_implementations;
71 private Multiset<String> m_references; 74 private Multiset<String> m_references;
72 private String m_outer; 75 private String m_outer;
@@ -140,6 +143,14 @@ public class ClassIdentity {
140 m_implements.add(scrubClassName(Descriptor.toJvmName(interfaceName))); 143 m_implements.add(scrubClassName(Descriptor.toJvmName(interfaceName)));
141 } 144 }
142 145
146 m_stringLiterals = Sets.newHashSet();
147 ConstPool constants = c.getClassFile().getConstPool();
148 for (int i=1; i<constants.getSize(); i++) {
149 if (constants.getTag(i) == ConstPool.CONST_String) {
150 m_stringLiterals.add(constants.getStringInfo(i));
151 }
152 }
153
143 // stuff from the jar index 154 // stuff from the jar index
144 155
145 m_implementations = HashMultiset.create(); 156 m_implementations = HashMultiset.create();
@@ -410,13 +421,15 @@ public class ClassIdentity {
410 public int getMatchScore(ClassIdentity other) { 421 public int getMatchScore(ClassIdentity other) {
411 return 2*getNumMatches(m_extends, other.m_extends) 422 return 2*getNumMatches(m_extends, other.m_extends)
412 + 2*getNumMatches(m_outer, other.m_outer) 423 + 2*getNumMatches(m_outer, other.m_outer)
424 + 2*getNumMatches(m_implements, other.m_implements)
425 + getNumMatches(m_stringLiterals, other.m_stringLiterals)
413 + getNumMatches(m_fields, other.m_fields) 426 + getNumMatches(m_fields, other.m_fields)
414 + getNumMatches(m_methods, other.m_methods) 427 + getNumMatches(m_methods, other.m_methods)
415 + getNumMatches(m_constructors, other.m_constructors); 428 + getNumMatches(m_constructors, other.m_constructors);
416 } 429 }
417 430
418 public int getMaxMatchScore() { 431 public int getMaxMatchScore() {
419 return 2 + 2 + m_fields.size() + m_methods.size() + m_constructors.size(); 432 return 2 + 2 + 2*m_implements.size() + m_stringLiterals.size() + m_fields.size() + m_methods.size() + m_constructors.size();
420 } 433 }
421 434
422 public boolean matches(CtClass c) { 435 public boolean matches(CtClass c) {
@@ -426,6 +439,16 @@ public class ClassIdentity {
426 && m_constructors.size() == c.getDeclaredConstructors().length; 439 && m_constructors.size() == c.getDeclaredConstructors().length;
427 } 440 }
428 441
442 private int getNumMatches(Set<String> a, Set<String> b) {
443 int numMatches = 0;
444 for (String val : a) {
445 if (b.contains(val)) {
446 numMatches++;
447 }
448 }
449 return numMatches;
450 }
451
429 private int getNumMatches(Multiset<String> a, Multiset<String> b) { 452 private int getNumMatches(Multiset<String> a, Multiset<String> b) {
430 int numMatches = 0; 453 int numMatches = 0;
431 for (String val : a) { 454 for (String val : a) {
diff --git a/src/cuchaz/enigma/convert/MappingsConverter.java b/src/cuchaz/enigma/convert/MappingsConverter.java
index f38723f..5883878 100644
--- a/src/cuchaz/enigma/convert/MappingsConverter.java
+++ b/src/cuchaz/enigma/convert/MappingsConverter.java
@@ -30,7 +30,10 @@ import cuchaz.enigma.analysis.JarIndex;
30import cuchaz.enigma.convert.ClassNamer.SidedClassNamer; 30import cuchaz.enigma.convert.ClassNamer.SidedClassNamer;
31import cuchaz.enigma.mapping.ClassEntry; 31import cuchaz.enigma.mapping.ClassEntry;
32import cuchaz.enigma.mapping.ClassMapping; 32import cuchaz.enigma.mapping.ClassMapping;
33import cuchaz.enigma.mapping.ClassNameReplacer;
34import cuchaz.enigma.mapping.FieldMapping;
33import cuchaz.enigma.mapping.Mappings; 35import cuchaz.enigma.mapping.Mappings;
36import cuchaz.enigma.mapping.MethodMapping;
34 37
35public class MappingsConverter { 38public class MappingsConverter {
36 39
@@ -129,15 +132,20 @@ public class MappingsConverter {
129 for (Entry<ClassEntry,ClassEntry> match : matchesByDestChainSize.get(chainSize)) { 132 for (Entry<ClassEntry,ClassEntry> match : matchesByDestChainSize.get(chainSize)) {
130 133
131 // get class info 134 // get class info
132 ClassEntry sourceClassEntry = match.getKey(); 135 ClassEntry obfSourceClassEntry = match.getKey();
133 ClassEntry deobfClassEntry = sourceDeobfuscator.deobfuscateEntry(sourceClassEntry); 136 ClassEntry obfDestClassEntry = match.getValue();
134 ClassEntry destClassEntry = match.getValue(); 137 List<ClassEntry> destClassChain = destDeobfuscator.getJarIndex().getObfClassChain(obfDestClassEntry);
135 List<ClassEntry> destClassChain = destDeobfuscator.getJarIndex().getObfClassChain(destClassEntry); 138
139 ClassMapping sourceMapping = sourceDeobfuscator.getMappings().getClassByObf(obfSourceClassEntry);
140 if (sourceMapping == null) {
141 // if this class was never deobfuscated, don't try to match it
142 continue;
143 }
136 144
137 // find out where to make the dest class mapping 145 // find out where to make the dest class mapping
138 if (destClassChain.size() == 1) { 146 if (destClassChain.size() == 1) {
139 // not an inner class, add directly to mappings 147 // not an inner class, add directly to mappings
140 newMappings.addClassMapping(new ClassMapping(destClassEntry.getName(), deobfClassEntry.getName())); 148 newMappings.addClassMapping(migrateClassMapping(obfDestClassEntry, sourceMapping, matches, false));
141 } else { 149 } else {
142 // inner class, find the outer class mapping 150 // inner class, find the outer class mapping
143 ClassMapping destMapping = null; 151 ClassMapping destMapping = null;
@@ -157,14 +165,52 @@ public class MappingsConverter {
157 } 165 }
158 } 166 }
159 } 167 }
160 String deobfName = deobfClassEntry.isInnerClass() ? deobfClassEntry.getInnerClassName() : deobfClassEntry.getSimpleName(); 168 destMapping.addInnerClassMapping(migrateClassMapping(obfDestClassEntry, sourceMapping, matches, true));
161 destMapping.addInnerClassMapping(new ClassMapping(destClassEntry.getName(), deobfName));
162 } 169 }
163 } 170 }
164 } 171 }
165 return newMappings; 172 return newMappings;
166 } 173 }
167 174
175 private static ClassMapping migrateClassMapping(ClassEntry newObfClass, ClassMapping mapping, final Matches matches, boolean useSimpleName) {
176
177 ClassNameReplacer replacer = new ClassNameReplacer() {
178 @Override
179 public String replace(String className) {
180 ClassEntry newClassEntry = matches.getUniqueMatches().get(new ClassEntry(className));
181 if (newClassEntry != null) {
182 return newClassEntry.getName();
183 }
184 return null;
185 }
186 };
187
188 ClassMapping newMapping;
189 String deobfName = mapping.getDeobfName();
190 if (deobfName != null) {
191 if (useSimpleName) {
192 deobfName = new ClassEntry(deobfName).getSimpleName();
193 }
194 newMapping = new ClassMapping(newObfClass.getName(), deobfName);
195 } else {
196 newMapping = new ClassMapping(newObfClass.getName());
197 }
198
199 // copy fields
200 for (FieldMapping fieldMapping : mapping.fields()) {
201 // TODO: map field obf names too...
202 newMapping.addFieldMapping(new FieldMapping(fieldMapping, replacer));
203 }
204
205 // copy methods
206 for (MethodMapping methodMapping : mapping.methods()) {
207 // TODO: map method obf names too...
208 newMapping.addMethodMapping(new MethodMapping(methodMapping, replacer));
209 }
210
211 return newMapping;
212 }
213
168 public static void convertMappings(Mappings mappings, BiMap<ClassEntry,ClassEntry> changes) { 214 public static void convertMappings(Mappings mappings, BiMap<ClassEntry,ClassEntry> changes) {
169 215
170 // sort the changes so classes are renamed in the correct order 216 // sort the changes so classes are renamed in the correct order