From 65f551cd25739f1ccfa15d819c6a23060ebf2629 Mon Sep 17 00:00:00 2001 From: jeff Date: Fri, 13 Mar 2015 16:46:02 -0400 Subject: complete mappings converion code. Still need to debug though --- src/cuchaz/enigma/ConvertMain.java | 29 ++++++++++++--- src/cuchaz/enigma/convert/MappingsConverter.java | 45 ++++++++++++++++++++++-- src/cuchaz/enigma/gui/MemberMatchingGui.java | 4 +-- 3 files changed, 69 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/cuchaz/enigma/ConvertMain.java b/src/cuchaz/enigma/ConvertMain.java index 15658d9..c5c92bc 100644 --- a/src/cuchaz/enigma/ConvertMain.java +++ b/src/cuchaz/enigma/ConvertMain.java @@ -46,13 +46,12 @@ public class ConvertMain { // match fields //computeFieldMatches(fieldMatchesFile, destJar, outMappingsFile, classMatchesFile); //editFieldMatches(sourceJar, destJar, outMappingsFile, mappings, classMatchesFile, fieldMatchesFile); + //convertMappings(outMappingsFile, sourceJar, destJar, mappings, classMatchesFile, fieldMatchesFile); // match methods/constructors //computeMethodMatches(methodMatchesFile, destJar, outMappingsFile, classMatchesFile); //editMethodMatches(sourceJar, destJar, outMappingsFile, mappings, classMatchesFile, methodMatchesFile); - - // write final converted mappings - writeFinalMappings(outMappingsFile, sourceJar, destJar, mappings, classMatchesFile, fieldMatchesFile, methodMatchesFile); + convertMappings(outMappingsFile, sourceJar, destJar, mappings, classMatchesFile, fieldMatchesFile, methodMatchesFile); } private static void computeClassMatches(File classMatchesFile, JarFile sourceJar, JarFile destJar, Mappings mappings) @@ -146,6 +145,28 @@ public class ConvertMain { } }); } + + private static void convertMappings(File outMappingsFile, JarFile sourceJar, JarFile destJar, Mappings mappings, File classMatchesFile, File fieldMatchesFile) + throws IOException { + + System.out.println("Reading matches..."); + ClassMatches classMatches = MatchesReader.readClasses(classMatchesFile); + MemberMatches fieldMatches = MatchesReader.readMembers(fieldMatchesFile); + + Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar); + deobfuscators.source.setMappings(mappings); + + // apply matches + Mappings newMappings = MappingsConverter.newMappings(classMatches, mappings, deobfuscators.source, deobfuscators.dest); + MappingsConverter.applyMemberMatches(newMappings, fieldMatches, MappingsConverter.getFieldDoer()); + + // write out the converted mappings + try (FileWriter out = new FileWriter(outMappingsFile)) { + new MappingsWriter().write(out, newMappings); + } + System.out.println("Wrote converted mappings to:\n\t" + outMappingsFile.getAbsolutePath()); + } + private static void computeMethodMatches(File methodMatchesFile, JarFile destJar, File destMappingsFile, File classMatchesFile) throws IOException, MappingParseException { @@ -198,7 +219,7 @@ public class ConvertMain { }); } - private static void writeFinalMappings(File outMappingsFile, JarFile sourceJar, JarFile destJar, Mappings mappings, File classMatchesFile, File fieldMatchesFile, File methodMatchesFile) + private static void convertMappings(File outMappingsFile, JarFile sourceJar, JarFile destJar, Mappings mappings, File classMatchesFile, File fieldMatchesFile, File methodMatchesFile) throws IOException { System.out.println("Reading matches..."); diff --git a/src/cuchaz/enigma/convert/MappingsConverter.java b/src/cuchaz/enigma/convert/MappingsConverter.java index 44bc8b8..59f3b5b 100644 --- a/src/cuchaz/enigma/convert/MappingsConverter.java +++ b/src/cuchaz/enigma/convert/MappingsConverter.java @@ -263,6 +263,7 @@ public class MappingsConverter { Collection> getMappings(ClassMapping destClassMapping); Set filterEntries(Collection obfEntries, T obfSourceEntry, ClassMatches classMatches); void setMemberObfName(ClassMapping classMapping, MemberMapping memberMapping, String newObfName); + boolean hasObfMember(ClassMapping classMapping, T obfEntry); } public static Doer getFieldDoer() { @@ -300,6 +301,11 @@ public class MappingsConverter { FieldMapping fieldMapping = (FieldMapping)memberMapping; classMapping.setFieldObfName(fieldMapping.getObfName(), fieldMapping.getObfType(), newObfName); } + + @Override + public boolean hasObfMember(ClassMapping classMapping, FieldEntry obfField) { + return classMapping.getFieldByObf(obfField.getName(), obfField.getType()) != null; + } }; } @@ -342,6 +348,11 @@ public class MappingsConverter { MethodMapping methodMapping = (MethodMapping)memberMapping; classMapping.setMethodObfName(methodMapping.getObfName(), methodMapping.getObfSignature(), newObfName); } + + @Override + public boolean hasObfMember(ClassMapping classMapping, BehaviorEntry obfBehavior) { + return classMapping.getMethodByObf(obfBehavior.getName(), obfBehavior.getSignature()) != null; + } }; } @@ -475,13 +486,41 @@ public class MappingsConverter { private static void applyMemberMatches(ClassMapping classMapping, MemberMatches memberMatches, Doer doer) { ClassEntry classEntry = classMapping.getObfEntry(); - // apply to this class - // TODO: need to sort renames so they happen in the right order!! + // make a map of all the renames we need to make + Map renames = Maps.newHashMap(); for (MemberMapping memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) { T obfSourceEntry = memberMapping.getObfEntry(classEntry); T obfDestEntry = memberMatches.matches().get(obfSourceEntry); if (obfDestEntry != null) { - doer.setMemberObfName(classMapping, memberMapping, obfDestEntry.getName()); + if (obfDestEntry.getName().equals(obfSourceEntry.getName())) { + // same name, don't need to change anything + continue; + } + renames.put(obfSourceEntry, obfDestEntry); + } + } + + // apply to this class (should never need more than n passes) + int numRenames = renames.size(); + for (int i=0; i memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) { + T obfSourceEntry = memberMapping.getObfEntry(classEntry); + T obfDestEntry = renames.get(obfSourceEntry); + if (obfDestEntry != null) { + // make sure this rename won't cause a collision + if (!doer.hasObfMember(classMapping, obfDestEntry)) { + doer.setMemberObfName(classMapping, memberMapping, obfDestEntry.getName()); + renames.remove(obfSourceEntry); + } + } + } + } + if (!renames.isEmpty()) { + System.err.println(String.format("WARNING: Couldn't apply all the renames for class %s. %d/%d renames left.", + classMapping.getObfFullName(), renames.size(), numRenames + )); + for (Map.Entry entry : renames.entrySet()) { + System.err.println(String.format("\t%s -> %s", entry.getKey(), entry.getValue())); } } diff --git a/src/cuchaz/enigma/gui/MemberMatchingGui.java b/src/cuchaz/enigma/gui/MemberMatchingGui.java index 52545b3..181fb54 100644 --- a/src/cuchaz/enigma/gui/MemberMatchingGui.java +++ b/src/cuchaz/enigma/gui/MemberMatchingGui.java @@ -403,9 +403,9 @@ public class MemberMatchingGui { } private String getEntryLabel(T obfEntry, Deobfuscator deobfuscator) { - // deobfuscate, then take off the class name + // show obfuscated and deobfuscated names, but no types/signatures T deobfEntry = deobfuscator.deobfuscateEntry(obfEntry); - return deobfEntry.toString().substring(deobfEntry.getClassName().length() + 1); + return String.format("%s (%s)", deobfEntry.getName(), obfEntry.getName()); } private void updateButtons() { -- cgit v1.2.3