summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/Deobfuscator.java
diff options
context:
space:
mode:
authorGravatar jeff2014-08-10 01:03:40 -0400
committerGravatar jeff2014-08-10 01:03:40 -0400
commitd24d2b9ad9b5c895020b56f700a72906346482e5 (patch)
treeda360c07209e6e327325db53dbb4df05e77cb7e9 /src/cuchaz/enigma/Deobfuscator.java
parentadded sorting for deobfuscated classes (diff)
downloadenigma-fork-d24d2b9ad9b5c895020b56f700a72906346482e5.tar.gz
enigma-fork-d24d2b9ad9b5c895020b56f700a72906346482e5.tar.xz
enigma-fork-d24d2b9ad9b5c895020b56f700a72906346482e5.zip
completely re-wrote token recognizer to bootstrap from Procyon's AST
changed imports to guava instead of whatever collections library happened to be on my classpath
Diffstat (limited to 'src/cuchaz/enigma/Deobfuscator.java')
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java114
1 files changed, 80 insertions, 34 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index e6e647e..8eda889 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -10,12 +10,10 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma; 11package cuchaz.enigma;
12 12
13import java.io.BufferedReader;
14import java.io.File; 13import java.io.File;
15import java.io.FileInputStream; 14import java.io.FileInputStream;
16import java.io.IOException; 15import java.io.IOException;
17import java.io.InputStream; 16import java.io.InputStream;
18import java.io.StringReader;
19import java.io.StringWriter; 17import java.io.StringWriter;
20import java.util.Enumeration; 18import java.util.Enumeration;
21import java.util.List; 19import java.util.List;
@@ -23,11 +21,26 @@ import java.util.Map;
23import java.util.jar.JarEntry; 21import java.util.jar.JarEntry;
24import java.util.jar.JarFile; 22import java.util.jar.JarFile;
25 23
26import com.beust.jcommander.internal.Lists; 24import com.google.common.collect.Lists;
27import com.strobel.decompiler.Decompiler; 25import com.strobel.assembler.metadata.MemberReference;
26import com.strobel.assembler.metadata.MetadataSystem;
27import com.strobel.assembler.metadata.TypeDefinition;
28import com.strobel.componentmodel.Key;
29import com.strobel.decompiler.DecompilerContext;
28import com.strobel.decompiler.DecompilerSettings; 30import com.strobel.decompiler.DecompilerSettings;
29import com.strobel.decompiler.PlainTextOutput; 31import com.strobel.decompiler.PlainTextOutput;
32import com.strobel.decompiler.languages.java.JavaOutputVisitor;
33import com.strobel.decompiler.languages.java.ast.AstBuilder;
34import com.strobel.decompiler.languages.java.ast.AstNode;
35import com.strobel.decompiler.languages.java.ast.CompilationUnit;
36import com.strobel.decompiler.languages.java.ast.Identifier;
37import com.strobel.decompiler.languages.java.ast.InsertParenthesesVisitor;
38import com.strobel.decompiler.languages.java.ast.InvocationExpression;
39import com.strobel.decompiler.languages.java.ast.Keys;
40import com.strobel.decompiler.languages.java.ast.MemberReferenceExpression;
30 41
42import cuchaz.enigma.analysis.SourceIndex;
43import cuchaz.enigma.analysis.SourceIndexVisitor;
31import cuchaz.enigma.mapping.Ancestries; 44import cuchaz.enigma.mapping.Ancestries;
32import cuchaz.enigma.mapping.ArgumentEntry; 45import cuchaz.enigma.mapping.ArgumentEntry;
33import cuchaz.enigma.mapping.ClassEntry; 46import cuchaz.enigma.mapping.ClassEntry;
@@ -91,7 +104,6 @@ public class Deobfuscator
91 104
92 // config the decompiler 105 // config the decompiler
93 m_settings = DecompilerSettings.javaDefaults(); 106 m_settings = DecompilerSettings.javaDefaults();
94 m_settings.setForceExplicitImports( true );
95 m_settings.setShowSyntheticMembers( true ); 107 m_settings.setShowSyntheticMembers( true );
96 108
97 // init mappings 109 // init mappings
@@ -157,7 +169,7 @@ public class Deobfuscator
157 } 169 }
158 } 170 }
159 171
160 public String getSource( final ClassFile classFile ) 172 public SourceIndex getSource( final ClassFile classFile )
161 { 173 {
162 // is this class deobfuscated? 174 // is this class deobfuscated?
163 // we need to tell the decompiler the deobfuscated name so it doesn't get freaked out 175 // we need to tell the decompiler the deobfuscated name so it doesn't get freaked out
@@ -170,45 +182,79 @@ public class Deobfuscator
170 } 182 }
171 183
172 // decompile it! 184 // decompile it!
185 TypeDefinition resolvedType = new MetadataSystem( m_settings.getTypeLoader() ).lookupType( deobfName ).resolve();
186 DecompilerContext context = new DecompilerContext();
187 context.setCurrentType( resolvedType );
188 context.setSettings( m_settings );
189 AstBuilder builder = new AstBuilder( context );
190 builder.addType( resolvedType );
191 builder.runTransformations( null );
192 CompilationUnit root = builder.getCompilationUnit();
193
194 // render the AST into source
173 StringWriter buf = new StringWriter(); 195 StringWriter buf = new StringWriter();
174 Decompiler.decompile( deobfName, new PlainTextOutput( buf ), m_settings ); 196 root.acceptVisitor( new InsertParenthesesVisitor(), null );
175 return fixSource( buf.toString() ); 197 root.acceptVisitor( new JavaOutputVisitor( new PlainTextOutput( buf ), m_settings ), null );
198
199 // build the source index
200 SourceIndex index = new SourceIndex( buf.toString() );
201 root.acceptVisitor( new SourceIndexVisitor(), index );
202
203 return index;
176 } 204 }
177 205
178 private String fixSource( String source ) 206 private void dump( AstNode node, int depth )
179 { 207 {
180 // fix the imports from the default package in the source 208 StringBuilder buf = new StringBuilder();
181 try 209 for( int i=0; i<depth; i++ )
210 {
211 buf.append( "\t" );
212 }
213 buf.append( node.getClass().getSimpleName() );
214
215 MemberReference memberRef = node.getUserData( Keys.MEMBER_REFERENCE );
216 if( memberRef != null )
182 { 217 {
183 StringBuilder buf = new StringBuilder(); 218 buf.append( String.format( " (MemberReference: %s.%s -> %s)", memberRef.getDeclaringType(), memberRef.getName(), memberRef.getSignature() ) );
184 BufferedReader reader = new BufferedReader( new StringReader( source ) ); 219 }
185 String line = null; 220
186 while( ( line = reader.readLine() ) != null ) 221 for( Key<?> key : Keys.ALL_KEYS )
222 {
223 if( key == Keys.MEMBER_REFERENCE )
187 { 224 {
188 String[] parts = line.trim().split( " " ); 225 continue;
189 if( parts.length == 2 && parts[0].equals( "import" ) ) 226 }
190 { 227 Object val = node.getUserData( key );
191 // is this an (illegal) import from the default package? 228 if( val != null )
192 String className = parts[1]; 229 {
193 if( className.indexOf( '.' ) < 0 ) 230 buf.append( String.format( " (%s=%s)", key, val ) );
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 } 231 }
203 return buf.toString();
204 } 232 }
205 catch( IOException ex ) 233
234
235 if( node instanceof Identifier )
236 {
237 Identifier n = (Identifier)node;
238 buf.append( ": " + n.getName() );
239 }
240 else if( node instanceof MemberReferenceExpression )
241 {
242 MemberReferenceExpression n = (MemberReferenceExpression)node;
243 buf.append( ": " + n.getTarget() + "." + n.getMemberName() );
244 }
245 else if( node instanceof InvocationExpression )
206 { 246 {
207 // dealing with IOExceptions on StringReaders is silly... 247
208 throw new Error( ex ); 248 }
249
250 System.out.println( buf );
251
252 for( AstNode child : node.getChildren() )
253 {
254 dump( child, depth + 1 );
209 } 255 }
210 } 256 }
211 257
212 // NOTE: these methods are a bit messy... oh well 258 // NOTE: these methods are a bit messy... oh well
213 259
214 public void rename( Entry obfEntry, String newName ) 260 public void rename( Entry obfEntry, String newName )