diff options
Diffstat (limited to 'src/cuchaz/enigma/Deobfuscator.java')
| -rw-r--r-- | src/cuchaz/enigma/Deobfuscator.java | 87 |
1 files changed, 73 insertions, 14 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java index e067183..e6e647e 100644 --- a/src/cuchaz/enigma/Deobfuscator.java +++ b/src/cuchaz/enigma/Deobfuscator.java | |||
| @@ -10,10 +10,12 @@ | |||
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | package cuchaz.enigma; | 11 | package cuchaz.enigma; |
| 12 | 12 | ||
| 13 | import java.io.BufferedReader; | ||
| 13 | import java.io.File; | 14 | import java.io.File; |
| 14 | import java.io.FileInputStream; | 15 | import java.io.FileInputStream; |
| 15 | import java.io.IOException; | 16 | import java.io.IOException; |
| 16 | import java.io.InputStream; | 17 | import java.io.InputStream; |
| 18 | import java.io.StringReader; | ||
| 17 | import java.io.StringWriter; | 19 | import java.io.StringWriter; |
| 18 | import java.util.Enumeration; | 20 | import java.util.Enumeration; |
| 19 | import java.util.List; | 21 | import java.util.List; |
| @@ -21,6 +23,7 @@ import java.util.Map; | |||
| 21 | import java.util.jar.JarEntry; | 23 | import java.util.jar.JarEntry; |
| 22 | import java.util.jar.JarFile; | 24 | import java.util.jar.JarFile; |
| 23 | 25 | ||
| 26 | import com.beust.jcommander.internal.Lists; | ||
| 24 | import com.strobel.decompiler.Decompiler; | 27 | import com.strobel.decompiler.Decompiler; |
| 25 | import com.strobel.decompiler.DecompilerSettings; | 28 | import com.strobel.decompiler.DecompilerSettings; |
| 26 | import com.strobel.decompiler.PlainTextOutput; | 29 | import com.strobel.decompiler.PlainTextOutput; |
| @@ -45,6 +48,7 @@ public class Deobfuscator | |||
| 45 | private Ancestries m_ancestries; | 48 | private Ancestries m_ancestries; |
| 46 | private Mappings m_mappings; | 49 | private Mappings m_mappings; |
| 47 | private Renamer m_renamer; | 50 | private Renamer m_renamer; |
| 51 | private List<String> m_obfClassNames; | ||
| 48 | 52 | ||
| 49 | public Deobfuscator( File file ) | 53 | public Deobfuscator( File file ) |
| 50 | throws IOException | 54 | throws IOException |
| @@ -65,6 +69,26 @@ public class Deobfuscator | |||
| 65 | Util.closeQuietly( jarIn ); | 69 | Util.closeQuietly( jarIn ); |
| 66 | } | 70 | } |
| 67 | 71 | ||
| 72 | // get the obf class names | ||
| 73 | m_obfClassNames = Lists.newArrayList(); | ||
| 74 | { | ||
| 75 | Enumeration<JarEntry> entries = m_jar.entries(); | ||
| 76 | while( entries.hasMoreElements() ) | ||
| 77 | { | ||
| 78 | JarEntry entry = entries.nextElement(); | ||
| 79 | |||
| 80 | // skip everything but class files | ||
| 81 | if( !entry.getName().endsWith( ".class" ) ) | ||
| 82 | { | ||
| 83 | continue; | ||
| 84 | } | ||
| 85 | |||
| 86 | // get the class name from the file | ||
| 87 | String className = entry.getName().substring( 0, entry.getName().length() - 6 ); | ||
| 88 | m_obfClassNames.add( className ); | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 68 | // config the decompiler | 92 | // config the decompiler |
| 69 | m_settings = DecompilerSettings.javaDefaults(); | 93 | m_settings = DecompilerSettings.javaDefaults(); |
| 70 | m_settings.setForceExplicitImports( true ); | 94 | m_settings.setForceExplicitImports( true ); |
| @@ -112,20 +136,9 @@ public class Deobfuscator | |||
| 112 | 136 | ||
| 113 | public void getSeparatedClasses( List<ClassFile> obfClasses, Map<ClassFile,String> deobfClasses ) | 137 | public void getSeparatedClasses( List<ClassFile> obfClasses, Map<ClassFile,String> deobfClasses ) |
| 114 | { | 138 | { |
| 115 | Enumeration<JarEntry> entries = m_jar.entries(); | 139 | for( String obfClassName : m_obfClassNames ) |
| 116 | while( entries.hasMoreElements() ) | ||
| 117 | { | 140 | { |
| 118 | JarEntry entry = entries.nextElement(); | 141 | ClassFile classFile = new ClassFile( obfClassName ); |
| 119 | |||
| 120 | // skip everything but class files | ||
| 121 | if( !entry.getName().endsWith( ".class" ) ) | ||
| 122 | { | ||
| 123 | continue; | ||
| 124 | } | ||
| 125 | |||
| 126 | // get the class name from the file | ||
| 127 | String className = entry.getName().substring( 0, entry.getName().length() - 6 ); | ||
| 128 | ClassFile classFile = new ClassFile( className ); | ||
| 129 | 142 | ||
| 130 | // separate the classes | 143 | // separate the classes |
| 131 | ClassMapping classMapping = m_mappings.getClassByObf( classFile.getName() ); | 144 | ClassMapping classMapping = m_mappings.getClassByObf( classFile.getName() ); |
| @@ -159,7 +172,41 @@ public class Deobfuscator | |||
| 159 | // decompile it! | 172 | // decompile it! |
| 160 | StringWriter buf = new StringWriter(); | 173 | StringWriter buf = new StringWriter(); |
| 161 | Decompiler.decompile( deobfName, new PlainTextOutput( buf ), m_settings ); | 174 | Decompiler.decompile( deobfName, new PlainTextOutput( buf ), m_settings ); |
| 162 | return buf.toString(); | 175 | return fixSource( buf.toString() ); |
| 176 | } | ||
| 177 | |||
| 178 | private String fixSource( String source ) | ||
| 179 | { | ||
| 180 | // fix the imports from the default package in the source | ||
| 181 | try | ||
| 182 | { | ||
| 183 | StringBuilder buf = new StringBuilder(); | ||
| 184 | BufferedReader reader = new BufferedReader( new StringReader( source ) ); | ||
| 185 | String line = null; | ||
| 186 | while( ( line = reader.readLine() ) != null ) | ||
| 187 | { | ||
| 188 | String[] parts = line.trim().split( " " ); | ||
| 189 | if( parts.length == 2 && parts[0].equals( "import" ) ) | ||
| 190 | { | ||
| 191 | // is this an (illegal) import from the default package? | ||
| 192 | String className = parts[1]; | ||
| 193 | if( className.indexOf( '.' ) < 0 ) | ||
| 194 | { | ||
| 195 | // this is an illegal import, replace it | ||
| 196 | line = "import __DEFAULT__." + parts[1]; | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | buf.append( line ); | ||
| 201 | buf.append( "\n" ); | ||
| 202 | } | ||
| 203 | return buf.toString(); | ||
| 204 | } | ||
| 205 | catch( IOException ex ) | ||
| 206 | { | ||
| 207 | // dealing with IOExceptions on StringReaders is silly... | ||
| 208 | throw new Error( ex ); | ||
| 209 | } | ||
| 163 | } | 210 | } |
| 164 | 211 | ||
| 165 | // NOTE: these methods are a bit messy... oh well | 212 | // NOTE: these methods are a bit messy... oh well |
| @@ -265,4 +312,16 @@ public class Deobfuscator | |||
| 265 | throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() ); | 312 | throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() ); |
| 266 | } | 313 | } |
| 267 | } | 314 | } |
| 315 | |||
| 316 | public boolean entryIsObfuscatedIdenfitier( Entry obfEntry ) | ||
| 317 | { | ||
| 318 | if( obfEntry instanceof ClassEntry ) | ||
| 319 | { | ||
| 320 | // obf classes must be in the list | ||
| 321 | return m_obfClassNames.contains( obfEntry.getName() ); | ||
| 322 | } | ||
| 323 | |||
| 324 | // assume everything else is an identifier | ||
| 325 | return true; | ||
| 326 | } | ||
| 268 | } | 327 | } |