diff options
| author | 2015-02-09 16:33:43 -0500 | |
|---|---|---|
| committer | 2015-02-09 16:33:43 -0500 | |
| commit | 250fe96550f9ab9179446a70cb15e8a8e23ae790 (patch) | |
| tree | 12eb720abdabde8314b11e2ff51f102e73cacc0c /src | |
| parent | add converter to update old mappings format (diff) | |
| download | enigma-fork-250fe96550f9ab9179446a70cb15e8a8e23ae790.tar.gz enigma-fork-250fe96550f9ab9179446a70cb15e8a8e23ae790.tar.xz enigma-fork-250fe96550f9ab9179446a70cb15e8a8e23ae790.zip | |
Don't automatically move mappings around. We're more interested in stability than backwards compatibility now. Just drop them instead.
Diffstat (limited to 'src')
| -rw-r--r-- | src/cuchaz/enigma/Deobfuscator.java | 87 |
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) { |