diff options
| author | 2014-08-04 00:26:48 -0400 | |
|---|---|---|
| committer | 2014-08-04 00:26:48 -0400 | |
| commit | 57f45b0409d5363782052183bb090175c469f89a (patch) | |
| tree | 672b32876b420445630e58e16b67d671e45c07b6 /src/cuchaz/enigma/Deobfuscator.java | |
| parent | fixed bugs with saving mappings (diff) | |
| download | enigma-fork-57f45b0409d5363782052183bb090175c469f89a.tar.gz enigma-fork-57f45b0409d5363782052183bb090175c469f89a.tar.xz enigma-fork-57f45b0409d5363782052183bb090175c469f89a.zip | |
added stable save order for mappings to hopefully help with merging
added color-coding for source identifiers
redesigned rename GUI
customized editor pane, added popup menu
finished name validation
added last-chance save on window close
Diffstat (limited to 'src/cuchaz/enigma/Deobfuscator.java')
| -rw-r--r-- | src/cuchaz/enigma/Deobfuscator.java | 119 |
1 files changed, 80 insertions, 39 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java index edc29e1..a3937b4 100644 --- a/src/cuchaz/enigma/Deobfuscator.java +++ b/src/cuchaz/enigma/Deobfuscator.java | |||
| @@ -17,6 +17,7 @@ import java.io.InputStream; | |||
| 17 | import java.io.StringWriter; | 17 | import java.io.StringWriter; |
| 18 | import java.util.Enumeration; | 18 | import java.util.Enumeration; |
| 19 | import java.util.List; | 19 | import java.util.List; |
| 20 | import java.util.Map; | ||
| 20 | import java.util.jar.JarEntry; | 21 | import java.util.jar.JarEntry; |
| 21 | import java.util.jar.JarFile; | 22 | import java.util.jar.JarFile; |
| 22 | 23 | ||
| @@ -32,7 +33,6 @@ import cuchaz.enigma.mapping.Entry; | |||
| 32 | import cuchaz.enigma.mapping.FieldEntry; | 33 | import cuchaz.enigma.mapping.FieldEntry; |
| 33 | import cuchaz.enigma.mapping.Mappings; | 34 | import cuchaz.enigma.mapping.Mappings; |
| 34 | import cuchaz.enigma.mapping.MethodEntry; | 35 | import cuchaz.enigma.mapping.MethodEntry; |
| 35 | import cuchaz.enigma.mapping.NameValidator; | ||
| 36 | import cuchaz.enigma.mapping.Renamer; | 36 | import cuchaz.enigma.mapping.Renamer; |
| 37 | import cuchaz.enigma.mapping.TranslationDirection; | 37 | import cuchaz.enigma.mapping.TranslationDirection; |
| 38 | import cuchaz.enigma.mapping.Translator; | 38 | import cuchaz.enigma.mapping.Translator; |
| @@ -100,26 +100,28 @@ public class Deobfuscator | |||
| 100 | ) ); | 100 | ) ); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | public void getSortedClasses( List<ClassFile> obfClasses, List<ClassFile> deobfClasses ) | 103 | public void getSeparatedClasses( List<ClassFile> obfClasses, Map<ClassFile,String> deobfClasses ) |
| 104 | { | 104 | { |
| 105 | Enumeration<JarEntry> entries = m_jar.entries(); | 105 | Enumeration<JarEntry> entries = m_jar.entries(); |
| 106 | while( entries.hasMoreElements() ) | 106 | while( entries.hasMoreElements() ) |
| 107 | { | 107 | { |
| 108 | JarEntry entry = entries.nextElement(); | 108 | JarEntry entry = entries.nextElement(); |
| 109 | 109 | ||
| 110 | // get the class name | 110 | // skip everything but class files |
| 111 | String obfName = NameValidator.fileNameToClassName( entry.getName() ); | 111 | if( !entry.getName().endsWith( ".class" ) ) |
| 112 | if( obfName == null ) | ||
| 113 | { | 112 | { |
| 114 | continue; | 113 | continue; |
| 115 | } | 114 | } |
| 116 | 115 | ||
| 117 | ClassFile classFile = new ClassFile( obfName ); | 116 | // get the class name from the file |
| 117 | String className = entry.getName().substring( 0, entry.getName().length() - 6 ); | ||
| 118 | ClassFile classFile = new ClassFile( className ); | ||
| 119 | |||
| 120 | // separate the classes | ||
| 118 | ClassMapping classMapping = m_mappings.getClassByObf( classFile.getName() ); | 121 | ClassMapping classMapping = m_mappings.getClassByObf( classFile.getName() ); |
| 119 | if( classMapping != null ) | 122 | if( classMapping != null ) |
| 120 | { | 123 | { |
| 121 | classFile.setDeobfName( classMapping.getDeobfName() ); | 124 | deobfClasses.put( classFile, classMapping.getDeobfName() ); |
| 122 | deobfClasses.add( classFile ); | ||
| 123 | } | 125 | } |
| 124 | else | 126 | else |
| 125 | { | 127 | { |
| @@ -130,84 +132,123 @@ public class Deobfuscator | |||
| 130 | 132 | ||
| 131 | public String getSource( final ClassFile classFile ) | 133 | public String getSource( final ClassFile classFile ) |
| 132 | { | 134 | { |
| 135 | // is this class deobfuscated? | ||
| 136 | // we need to tell the decompiler the deobfuscated name so it doesn't get freaked out | ||
| 137 | // the decompiler only sees the deobfuscated class, so we need to load it by the deobfuscated name | ||
| 138 | String deobfName = classFile.getName(); | ||
| 139 | ClassMapping classMapping = m_mappings.getClassByObf( classFile.getName() ); | ||
| 140 | if( classMapping != null ) | ||
| 141 | { | ||
| 142 | deobfName = classMapping.getDeobfName(); | ||
| 143 | } | ||
| 144 | |||
| 145 | // decompile it! | ||
| 133 | StringWriter buf = new StringWriter(); | 146 | StringWriter buf = new StringWriter(); |
| 134 | Decompiler.decompile( classFile.getObfName(), new PlainTextOutput( buf ), m_settings ); | 147 | Decompiler.decompile( deobfName, new PlainTextOutput( buf ), m_settings ); |
| 135 | return buf.toString(); | 148 | return buf.toString(); |
| 136 | } | 149 | } |
| 137 | 150 | ||
| 138 | // NOTE: these methods are a bit messy... oh well | 151 | // NOTE: these methods are a bit messy... oh well |
| 139 | 152 | ||
| 140 | public void rename( Entry entry, String newName ) | 153 | public void rename( Entry obfEntry, String newName ) |
| 141 | { | 154 | { |
| 142 | if( entry instanceof ClassEntry ) | 155 | if( obfEntry instanceof ClassEntry ) |
| 143 | { | 156 | { |
| 144 | m_renamer.setClassName( (ClassEntry)entry, newName ); | 157 | m_renamer.setClassName( (ClassEntry)obfEntry, newName ); |
| 145 | } | 158 | } |
| 146 | else if( entry instanceof FieldEntry ) | 159 | else if( obfEntry instanceof FieldEntry ) |
| 147 | { | 160 | { |
| 148 | m_renamer.setFieldName( (FieldEntry)entry, newName ); | 161 | m_renamer.setFieldName( (FieldEntry)obfEntry, newName ); |
| 149 | } | 162 | } |
| 150 | else if( entry instanceof MethodEntry ) | 163 | else if( obfEntry instanceof MethodEntry ) |
| 151 | { | 164 | { |
| 152 | m_renamer.setMethodName( (MethodEntry)entry, newName ); | 165 | m_renamer.setMethodName( (MethodEntry)obfEntry, newName ); |
| 153 | } | 166 | } |
| 154 | else if( entry instanceof ArgumentEntry ) | 167 | else if( obfEntry instanceof ArgumentEntry ) |
| 155 | { | 168 | { |
| 156 | m_renamer.setArgumentName( (ArgumentEntry)entry, newName ); | 169 | m_renamer.setArgumentName( (ArgumentEntry)obfEntry, newName ); |
| 157 | } | 170 | } |
| 158 | else | 171 | else |
| 159 | { | 172 | { |
| 160 | throw new Error( "Unknown entry type: " + entry.getClass().getName() ); | 173 | throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() ); |
| 161 | } | 174 | } |
| 162 | } | 175 | } |
| 163 | 176 | ||
| 164 | public Entry obfuscate( Entry in ) | 177 | public Entry obfuscateEntry( Entry deobfEntry ) |
| 165 | { | 178 | { |
| 166 | Translator translator = m_mappings.getTranslator( m_ancestries, TranslationDirection.Obfuscating ); | 179 | Translator translator = m_mappings.getTranslator( m_ancestries, TranslationDirection.Obfuscating ); |
| 167 | if( in instanceof ClassEntry ) | 180 | if( deobfEntry instanceof ClassEntry ) |
| 181 | { | ||
| 182 | return translator.translateEntry( (ClassEntry)deobfEntry ); | ||
| 183 | } | ||
| 184 | else if( deobfEntry instanceof FieldEntry ) | ||
| 185 | { | ||
| 186 | return translator.translateEntry( (FieldEntry)deobfEntry ); | ||
| 187 | } | ||
| 188 | else if( deobfEntry instanceof MethodEntry ) | ||
| 189 | { | ||
| 190 | return translator.translateEntry( (MethodEntry)deobfEntry ); | ||
| 191 | } | ||
| 192 | else if( deobfEntry instanceof ArgumentEntry ) | ||
| 193 | { | ||
| 194 | return translator.translateEntry( (ArgumentEntry)deobfEntry ); | ||
| 195 | } | ||
| 196 | else | ||
| 197 | { | ||
| 198 | throw new Error( "Unknown entry type: " + deobfEntry.getClass().getName() ); | ||
| 199 | } | ||
| 200 | } | ||
| 201 | |||
| 202 | public Entry deobfuscateEntry( Entry obfEntry ) | ||
| 203 | { | ||
| 204 | Translator translator = m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating ); | ||
| 205 | if( obfEntry instanceof ClassEntry ) | ||
| 168 | { | 206 | { |
| 169 | return translator.translateEntry( (ClassEntry)in ); | 207 | return translator.translateEntry( (ClassEntry)obfEntry ); |
| 170 | } | 208 | } |
| 171 | else if( in instanceof FieldEntry ) | 209 | else if( obfEntry instanceof FieldEntry ) |
| 172 | { | 210 | { |
| 173 | return translator.translateEntry( (FieldEntry)in ); | 211 | return translator.translateEntry( (FieldEntry)obfEntry ); |
| 174 | } | 212 | } |
| 175 | else if( in instanceof MethodEntry ) | 213 | else if( obfEntry instanceof MethodEntry ) |
| 176 | { | 214 | { |
| 177 | return translator.translateEntry( (MethodEntry)in ); | 215 | return translator.translateEntry( (MethodEntry)obfEntry ); |
| 178 | } | 216 | } |
| 179 | else if( in instanceof ArgumentEntry ) | 217 | else if( obfEntry instanceof ArgumentEntry ) |
| 180 | { | 218 | { |
| 181 | return translator.translateEntry( (ArgumentEntry)in ); | 219 | return translator.translateEntry( (ArgumentEntry)obfEntry ); |
| 182 | } | 220 | } |
| 183 | else | 221 | else |
| 184 | { | 222 | { |
| 185 | throw new Error( "Unknown entry type: " + in.getClass().getName() ); | 223 | throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() ); |
| 186 | } | 224 | } |
| 187 | } | 225 | } |
| 188 | 226 | ||
| 189 | public Entry deobfuscate( Entry in ) | 227 | public boolean hasMapping( Entry obfEntry ) |
| 190 | { | 228 | { |
| 191 | Translator translator = m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating ); | 229 | Translator translator = m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating ); |
| 192 | if( in instanceof ClassEntry ) | 230 | if( obfEntry instanceof ClassEntry ) |
| 193 | { | 231 | { |
| 194 | return translator.translateEntry( (ClassEntry)in ); | 232 | String deobfName = translator.translate( (ClassEntry)obfEntry ); |
| 233 | return deobfName != null && !deobfName.equals( obfEntry.getName() ); | ||
| 195 | } | 234 | } |
| 196 | else if( in instanceof FieldEntry ) | 235 | else if( obfEntry instanceof FieldEntry ) |
| 197 | { | 236 | { |
| 198 | return translator.translateEntry( (FieldEntry)in ); | 237 | String deobfName = translator.translate( (FieldEntry)obfEntry ); |
| 238 | return deobfName != null && !deobfName.equals( obfEntry.getName() ); | ||
| 199 | } | 239 | } |
| 200 | else if( in instanceof MethodEntry ) | 240 | else if( obfEntry instanceof MethodEntry ) |
| 201 | { | 241 | { |
| 202 | return translator.translateEntry( (MethodEntry)in ); | 242 | String deobfName = translator.translate( (MethodEntry)obfEntry ); |
| 243 | return deobfName != null && !deobfName.equals( obfEntry.getName() ); | ||
| 203 | } | 244 | } |
| 204 | else if( in instanceof ArgumentEntry ) | 245 | else if( obfEntry instanceof ArgumentEntry ) |
| 205 | { | 246 | { |
| 206 | return translator.translateEntry( (ArgumentEntry)in ); | 247 | return translator.translate( (ArgumentEntry)obfEntry ) != null; |
| 207 | } | 248 | } |
| 208 | else | 249 | else |
| 209 | { | 250 | { |
| 210 | throw new Error( "Unknown entry type: " + in.getClass().getName() ); | 251 | throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() ); |
| 211 | } | 252 | } |
| 212 | } | 253 | } |
| 213 | } | 254 | } |