diff options
| author | 2015-03-13 16:46:02 -0400 | |
|---|---|---|
| committer | 2015-03-13 16:46:02 -0400 | |
| commit | 65f551cd25739f1ccfa15d819c6a23060ebf2629 (patch) | |
| tree | fd0cb0da21787fe77ea502560e023a03600e58dc | |
| parent | working on writing mappings based on all the matches (diff) | |
| download | enigma-65f551cd25739f1ccfa15d819c6a23060ebf2629.tar.gz enigma-65f551cd25739f1ccfa15d819c6a23060ebf2629.tar.xz enigma-65f551cd25739f1ccfa15d819c6a23060ebf2629.zip | |
complete mappings converion code. Still need to debug though
| -rw-r--r-- | src/cuchaz/enigma/ConvertMain.java | 29 | ||||
| -rw-r--r-- | src/cuchaz/enigma/convert/MappingsConverter.java | 45 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/MemberMatchingGui.java | 4 |
3 files changed, 69 insertions, 9 deletions
diff --git a/src/cuchaz/enigma/ConvertMain.java b/src/cuchaz/enigma/ConvertMain.java index 15658d90..c5c92bcb 100644 --- a/src/cuchaz/enigma/ConvertMain.java +++ b/src/cuchaz/enigma/ConvertMain.java | |||
| @@ -46,13 +46,12 @@ public class ConvertMain { | |||
| 46 | // match fields | 46 | // match fields |
| 47 | //computeFieldMatches(fieldMatchesFile, destJar, outMappingsFile, classMatchesFile); | 47 | //computeFieldMatches(fieldMatchesFile, destJar, outMappingsFile, classMatchesFile); |
| 48 | //editFieldMatches(sourceJar, destJar, outMappingsFile, mappings, classMatchesFile, fieldMatchesFile); | 48 | //editFieldMatches(sourceJar, destJar, outMappingsFile, mappings, classMatchesFile, fieldMatchesFile); |
| 49 | //convertMappings(outMappingsFile, sourceJar, destJar, mappings, classMatchesFile, fieldMatchesFile); | ||
| 49 | 50 | ||
| 50 | // match methods/constructors | 51 | // match methods/constructors |
| 51 | //computeMethodMatches(methodMatchesFile, destJar, outMappingsFile, classMatchesFile); | 52 | //computeMethodMatches(methodMatchesFile, destJar, outMappingsFile, classMatchesFile); |
| 52 | //editMethodMatches(sourceJar, destJar, outMappingsFile, mappings, classMatchesFile, methodMatchesFile); | 53 | //editMethodMatches(sourceJar, destJar, outMappingsFile, mappings, classMatchesFile, methodMatchesFile); |
| 53 | 54 | convertMappings(outMappingsFile, sourceJar, destJar, mappings, classMatchesFile, fieldMatchesFile, methodMatchesFile); | |
| 54 | // write final converted mappings | ||
| 55 | writeFinalMappings(outMappingsFile, sourceJar, destJar, mappings, classMatchesFile, fieldMatchesFile, methodMatchesFile); | ||
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | private static void computeClassMatches(File classMatchesFile, JarFile sourceJar, JarFile destJar, Mappings mappings) | 57 | private static void computeClassMatches(File classMatchesFile, JarFile sourceJar, JarFile destJar, Mappings mappings) |
| @@ -146,6 +145,28 @@ public class ConvertMain { | |||
| 146 | } | 145 | } |
| 147 | }); | 146 | }); |
| 148 | } | 147 | } |
| 148 | |||
| 149 | private static void convertMappings(File outMappingsFile, JarFile sourceJar, JarFile destJar, Mappings mappings, File classMatchesFile, File fieldMatchesFile) | ||
| 150 | throws IOException { | ||
| 151 | |||
| 152 | System.out.println("Reading matches..."); | ||
| 153 | ClassMatches classMatches = MatchesReader.readClasses(classMatchesFile); | ||
| 154 | MemberMatches<FieldEntry> fieldMatches = MatchesReader.readMembers(fieldMatchesFile); | ||
| 155 | |||
| 156 | Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar); | ||
| 157 | deobfuscators.source.setMappings(mappings); | ||
| 158 | |||
| 159 | // apply matches | ||
| 160 | Mappings newMappings = MappingsConverter.newMappings(classMatches, mappings, deobfuscators.source, deobfuscators.dest); | ||
| 161 | MappingsConverter.applyMemberMatches(newMappings, fieldMatches, MappingsConverter.getFieldDoer()); | ||
| 162 | |||
| 163 | // write out the converted mappings | ||
| 164 | try (FileWriter out = new FileWriter(outMappingsFile)) { | ||
| 165 | new MappingsWriter().write(out, newMappings); | ||
| 166 | } | ||
| 167 | System.out.println("Wrote converted mappings to:\n\t" + outMappingsFile.getAbsolutePath()); | ||
| 168 | } | ||
| 169 | |||
| 149 | 170 | ||
| 150 | private static void computeMethodMatches(File methodMatchesFile, JarFile destJar, File destMappingsFile, File classMatchesFile) | 171 | private static void computeMethodMatches(File methodMatchesFile, JarFile destJar, File destMappingsFile, File classMatchesFile) |
| 151 | throws IOException, MappingParseException { | 172 | throws IOException, MappingParseException { |
| @@ -198,7 +219,7 @@ public class ConvertMain { | |||
| 198 | }); | 219 | }); |
| 199 | } | 220 | } |
| 200 | 221 | ||
| 201 | private static void writeFinalMappings(File outMappingsFile, JarFile sourceJar, JarFile destJar, Mappings mappings, File classMatchesFile, File fieldMatchesFile, File methodMatchesFile) | 222 | private static void convertMappings(File outMappingsFile, JarFile sourceJar, JarFile destJar, Mappings mappings, File classMatchesFile, File fieldMatchesFile, File methodMatchesFile) |
| 202 | throws IOException { | 223 | throws IOException { |
| 203 | 224 | ||
| 204 | System.out.println("Reading matches..."); | 225 | System.out.println("Reading matches..."); |
diff --git a/src/cuchaz/enigma/convert/MappingsConverter.java b/src/cuchaz/enigma/convert/MappingsConverter.java index 44bc8b87..59f3b5ba 100644 --- a/src/cuchaz/enigma/convert/MappingsConverter.java +++ b/src/cuchaz/enigma/convert/MappingsConverter.java | |||
| @@ -263,6 +263,7 @@ public class MappingsConverter { | |||
| 263 | Collection<? extends MemberMapping<T>> getMappings(ClassMapping destClassMapping); | 263 | Collection<? extends MemberMapping<T>> getMappings(ClassMapping destClassMapping); |
| 264 | Set<T> filterEntries(Collection<T> obfEntries, T obfSourceEntry, ClassMatches classMatches); | 264 | Set<T> filterEntries(Collection<T> obfEntries, T obfSourceEntry, ClassMatches classMatches); |
| 265 | void setMemberObfName(ClassMapping classMapping, MemberMapping<T> memberMapping, String newObfName); | 265 | void setMemberObfName(ClassMapping classMapping, MemberMapping<T> memberMapping, String newObfName); |
| 266 | boolean hasObfMember(ClassMapping classMapping, T obfEntry); | ||
| 266 | } | 267 | } |
| 267 | 268 | ||
| 268 | public static Doer<FieldEntry> getFieldDoer() { | 269 | public static Doer<FieldEntry> getFieldDoer() { |
| @@ -300,6 +301,11 @@ public class MappingsConverter { | |||
| 300 | FieldMapping fieldMapping = (FieldMapping)memberMapping; | 301 | FieldMapping fieldMapping = (FieldMapping)memberMapping; |
| 301 | classMapping.setFieldObfName(fieldMapping.getObfName(), fieldMapping.getObfType(), newObfName); | 302 | classMapping.setFieldObfName(fieldMapping.getObfName(), fieldMapping.getObfType(), newObfName); |
| 302 | } | 303 | } |
| 304 | |||
| 305 | @Override | ||
| 306 | public boolean hasObfMember(ClassMapping classMapping, FieldEntry obfField) { | ||
| 307 | return classMapping.getFieldByObf(obfField.getName(), obfField.getType()) != null; | ||
| 308 | } | ||
| 303 | }; | 309 | }; |
| 304 | } | 310 | } |
| 305 | 311 | ||
| @@ -342,6 +348,11 @@ public class MappingsConverter { | |||
| 342 | MethodMapping methodMapping = (MethodMapping)memberMapping; | 348 | MethodMapping methodMapping = (MethodMapping)memberMapping; |
| 343 | classMapping.setMethodObfName(methodMapping.getObfName(), methodMapping.getObfSignature(), newObfName); | 349 | classMapping.setMethodObfName(methodMapping.getObfName(), methodMapping.getObfSignature(), newObfName); |
| 344 | } | 350 | } |
| 351 | |||
| 352 | @Override | ||
| 353 | public boolean hasObfMember(ClassMapping classMapping, BehaviorEntry obfBehavior) { | ||
| 354 | return classMapping.getMethodByObf(obfBehavior.getName(), obfBehavior.getSignature()) != null; | ||
| 355 | } | ||
| 345 | }; | 356 | }; |
| 346 | } | 357 | } |
| 347 | 358 | ||
| @@ -475,13 +486,41 @@ public class MappingsConverter { | |||
| 475 | private static <T extends Entry> void applyMemberMatches(ClassMapping classMapping, MemberMatches<T> memberMatches, Doer<T> doer) { | 486 | private static <T extends Entry> void applyMemberMatches(ClassMapping classMapping, MemberMatches<T> memberMatches, Doer<T> doer) { |
| 476 | ClassEntry classEntry = classMapping.getObfEntry(); | 487 | ClassEntry classEntry = classMapping.getObfEntry(); |
| 477 | 488 | ||
| 478 | // apply to this class | 489 | // make a map of all the renames we need to make |
| 479 | // TODO: need to sort renames so they happen in the right order!! | 490 | Map<T,T> renames = Maps.newHashMap(); |
| 480 | for (MemberMapping<T> memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) { | 491 | for (MemberMapping<T> memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) { |
| 481 | T obfSourceEntry = memberMapping.getObfEntry(classEntry); | 492 | T obfSourceEntry = memberMapping.getObfEntry(classEntry); |
| 482 | T obfDestEntry = memberMatches.matches().get(obfSourceEntry); | 493 | T obfDestEntry = memberMatches.matches().get(obfSourceEntry); |
| 483 | if (obfDestEntry != null) { | 494 | if (obfDestEntry != null) { |
| 484 | doer.setMemberObfName(classMapping, memberMapping, obfDestEntry.getName()); | 495 | if (obfDestEntry.getName().equals(obfSourceEntry.getName())) { |
| 496 | // same name, don't need to change anything | ||
| 497 | continue; | ||
| 498 | } | ||
| 499 | renames.put(obfSourceEntry, obfDestEntry); | ||
| 500 | } | ||
| 501 | } | ||
| 502 | |||
| 503 | // apply to this class (should never need more than n passes) | ||
| 504 | int numRenames = renames.size(); | ||
| 505 | for (int i=0; i<numRenames && !renames.isEmpty(); i++) { | ||
| 506 | for (MemberMapping<T> memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) { | ||
| 507 | T obfSourceEntry = memberMapping.getObfEntry(classEntry); | ||
| 508 | T obfDestEntry = renames.get(obfSourceEntry); | ||
| 509 | if (obfDestEntry != null) { | ||
| 510 | // make sure this rename won't cause a collision | ||
| 511 | if (!doer.hasObfMember(classMapping, obfDestEntry)) { | ||
| 512 | doer.setMemberObfName(classMapping, memberMapping, obfDestEntry.getName()); | ||
| 513 | renames.remove(obfSourceEntry); | ||
| 514 | } | ||
| 515 | } | ||
| 516 | } | ||
| 517 | } | ||
| 518 | if (!renames.isEmpty()) { | ||
| 519 | System.err.println(String.format("WARNING: Couldn't apply all the renames for class %s. %d/%d renames left.", | ||
| 520 | classMapping.getObfFullName(), renames.size(), numRenames | ||
| 521 | )); | ||
| 522 | for (Map.Entry<T,T> entry : renames.entrySet()) { | ||
| 523 | System.err.println(String.format("\t%s -> %s", entry.getKey(), entry.getValue())); | ||
| 485 | } | 524 | } |
| 486 | } | 525 | } |
| 487 | 526 | ||
diff --git a/src/cuchaz/enigma/gui/MemberMatchingGui.java b/src/cuchaz/enigma/gui/MemberMatchingGui.java index 52545b33..181fb548 100644 --- a/src/cuchaz/enigma/gui/MemberMatchingGui.java +++ b/src/cuchaz/enigma/gui/MemberMatchingGui.java | |||
| @@ -403,9 +403,9 @@ public class MemberMatchingGui<T extends Entry> { | |||
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | private String getEntryLabel(T obfEntry, Deobfuscator deobfuscator) { | 405 | private String getEntryLabel(T obfEntry, Deobfuscator deobfuscator) { |
| 406 | // deobfuscate, then take off the class name | 406 | // show obfuscated and deobfuscated names, but no types/signatures |
| 407 | T deobfEntry = deobfuscator.deobfuscateEntry(obfEntry); | 407 | T deobfEntry = deobfuscator.deobfuscateEntry(obfEntry); |
| 408 | return deobfEntry.toString().substring(deobfEntry.getClassName().length() + 1); | 408 | return String.format("%s (%s)", deobfEntry.getName(), obfEntry.getName()); |
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | private void updateButtons() { | 411 | private void updateButtons() { |