summaryrefslogtreecommitdiff
path: root/src/cuchaz
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz')
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java78
-rw-r--r--src/cuchaz/enigma/gui/Gui.java38
-rw-r--r--src/cuchaz/enigma/gui/GuiController.java26
-rw-r--r--src/cuchaz/enigma/gui/GuiTricks.java25
-rw-r--r--src/cuchaz/enigma/gui/ProgressDialog.java89
5 files changed, 233 insertions, 23 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index 38f7af56..5d87ad0a 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -11,6 +11,7 @@
11package cuchaz.enigma; 11package cuchaz.enigma;
12 12
13import java.io.File; 13import java.io.File;
14import java.io.FileWriter;
14import java.io.IOException; 15import java.io.IOException;
15import java.io.StringWriter; 16import java.io.StringWriter;
16import java.util.List; 17import java.util.List;
@@ -44,6 +45,12 @@ import cuchaz.enigma.mapping.Translator;
44 45
45public class Deobfuscator 46public class Deobfuscator
46{ 47{
48 public interface ProgressListener
49 {
50 void init( int totalWork );
51 void onProgress( int numDone, String message );
52 }
53
47 private File m_file; 54 private File m_file;
48 private JarFile m_jar; 55 private JarFile m_jar;
49 private DecompilerSettings m_settings; 56 private DecompilerSettings m_settings;
@@ -137,7 +144,7 @@ public class Deobfuscator
137 } 144 }
138 } 145 }
139 146
140 public SourceIndex getSource( String className ) 147 public CompilationUnit getSourceTree( String className )
141 { 148 {
142 // is this class deobfuscated? 149 // is this class deobfuscated?
143 // we need to tell the decompiler the deobfuscated name so it doesn't get freaked out 150 // we need to tell the decompiler the deobfuscated name so it doesn't get freaked out
@@ -156,19 +163,18 @@ public class Deobfuscator
156 AstBuilder builder = new AstBuilder( context ); 163 AstBuilder builder = new AstBuilder( context );
157 builder.addType( resolvedType ); 164 builder.addType( resolvedType );
158 builder.runTransformations( null ); 165 builder.runTransformations( null );
159 CompilationUnit root = builder.getCompilationUnit(); 166 return builder.getCompilationUnit();
167 }
168
169 public SourceIndex getSourceIndex( CompilationUnit sourceTree, String source )
170 {
171 // build the source index
172 SourceIndex index = new SourceIndex( source );
173 sourceTree.acceptVisitor( new SourceIndexVisitor(), index );
160 174
161 // render the AST into source
162 StringWriter buf = new StringWriter();
163 root.acceptVisitor( new InsertParenthesesVisitor(), null );
164 // DEBUG 175 // DEBUG
165 //root.acceptVisitor( new TreeDumpVisitor( new File( "tree.txt" ) ), null ); 176 //root.acceptVisitor( new TreeDumpVisitor( new File( "tree.txt" ) ), null );
166 root.acceptVisitor( new JavaOutputVisitor( new PlainTextOutput( buf ), m_settings ), null ); 177
167
168 // build the source index
169 SourceIndex index = new SourceIndex( buf.toString() );
170 root.acceptVisitor( new SourceIndexVisitor(), index );
171
172 /* DEBUG 178 /* DEBUG
173 for( Token token : index.referenceTokens() ) 179 for( Token token : index.referenceTokens() )
174 { 180 {
@@ -180,6 +186,56 @@ public class Deobfuscator
180 return index; 186 return index;
181 } 187 }
182 188
189 public String getSource( CompilationUnit sourceTree )
190 {
191 // render the AST into source
192 StringWriter buf = new StringWriter();
193 sourceTree.acceptVisitor( new InsertParenthesesVisitor(), null );
194 sourceTree.acceptVisitor( new JavaOutputVisitor( new PlainTextOutput( buf ), m_settings ), null );
195 return buf.toString();
196 }
197
198 public void writeSources( File dirOut, ProgressListener progress )
199 throws IOException
200 {
201 int numClasses = m_jarIndex.getObfClassNames().size();
202 if( progress != null )
203 {
204 progress.init( numClasses );
205 }
206 int i = 0;
207
208 // DEOBFUSCATE ALL THE THINGS!! @_@
209 for( String obfClassName : m_jarIndex.getObfClassNames() )
210 {
211 // skip inner classes
212 if( m_jarIndex.getOuterClass( obfClassName ) != null )
213 {
214 continue;
215 }
216
217 ClassEntry deobfClassEntry = deobfuscateEntry( new ClassEntry( obfClassName ) );
218 if( progress != null )
219 {
220 progress.onProgress( i++, deobfClassEntry.toString() );
221 }
222
223 // get the source
224 String source = getSource( getSourceTree( obfClassName ) );
225
226 // write the file
227 File file = new File( dirOut, deobfClassEntry.getName().replace( '.', '/' ) + ".java" );
228 file.getParentFile().mkdirs();
229 try( FileWriter out = new FileWriter( file ) )
230 {
231 out.write( source );
232 }
233 }
234
235 // done!
236 progress.onProgress( numClasses, "Done!" );
237 }
238
183 public <T extends Entry> T obfuscateEntry( T deobfEntry ) 239 public <T extends Entry> T obfuscateEntry( T deobfEntry )
184 { 240 {
185 if( deobfEntry == null ) 241 if( deobfEntry == null )
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java
index dd82b8e0..febdfd43 100644
--- a/src/cuchaz/enigma/gui/Gui.java
+++ b/src/cuchaz/enigma/gui/Gui.java
@@ -15,7 +15,6 @@ import java.awt.Color;
15import java.awt.Container; 15import java.awt.Container;
16import java.awt.Dimension; 16import java.awt.Dimension;
17import java.awt.FlowLayout; 17import java.awt.FlowLayout;
18import java.awt.Font;
19import java.awt.GridLayout; 18import java.awt.GridLayout;
20import java.awt.Rectangle; 19import java.awt.Rectangle;
21import java.awt.event.ActionEvent; 20import java.awt.event.ActionEvent;
@@ -169,6 +168,7 @@ public class Gui
169 private EntryReference<Entry,Entry> m_reference; 168 private EntryReference<Entry,Entry> m_reference;
170 private JFileChooser m_jarFileChooser; 169 private JFileChooser m_jarFileChooser;
171 private JFileChooser m_mappingsFileChooser; 170 private JFileChooser m_mappingsFileChooser;
171 private JFileChooser m_exportFileChooser;
172 172
173 public Gui( ) 173 public Gui( )
174 { 174 {
@@ -177,6 +177,8 @@ public class Gui
177 // init file choosers 177 // init file choosers
178 m_jarFileChooser = new JFileChooser(); 178 m_jarFileChooser = new JFileChooser();
179 m_mappingsFileChooser = new JFileChooser(); 179 m_mappingsFileChooser = new JFileChooser();
180 m_exportFileChooser = new JFileChooser();
181 m_exportFileChooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
180 182
181 // init frame 183 // init frame
182 m_frame = new JFrame( Constants.Name ); 184 m_frame = new JFrame( Constants.Name );
@@ -637,6 +639,22 @@ public class Gui
637 } 639 }
638 menu.addSeparator(); 640 menu.addSeparator();
639 { 641 {
642 JMenuItem item = new JMenuItem( "Export..." );
643 menu.add( item );
644 item.addActionListener( new ActionListener( )
645 {
646 @Override
647 public void actionPerformed( ActionEvent event )
648 {
649 if( m_exportFileChooser.showSaveDialog( m_frame ) == JFileChooser.APPROVE_OPTION )
650 {
651 m_controller.export( m_exportFileChooser.getSelectedFile() );
652 }
653 }
654 } );
655 }
656 menu.addSeparator();
657 {
640 JMenuItem item = new JMenuItem( "Exit" ); 658 JMenuItem item = new JMenuItem( "Exit" );
641 menu.add( item ); 659 menu.add( item );
642 item.addActionListener( new ActionListener( ) 660 item.addActionListener( new ActionListener( )
@@ -686,6 +704,11 @@ public class Gui
686 m_frame.setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE ); 704 m_frame.setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE );
687 } 705 }
688 706
707 public JFrame getFrame( )
708 {
709 return m_frame;
710 }
711
689 public GuiController getController( ) 712 public GuiController getController( )
690 { 713 {
691 return m_controller; 714 return m_controller;
@@ -887,7 +910,7 @@ public class Gui
887 { 910 {
888 m_infoPanel.removeAll(); 911 m_infoPanel.removeAll();
889 JLabel label = new JLabel( "No identifier selected" ); 912 JLabel label = new JLabel( "No identifier selected" );
890 unboldLabel( label ); 913 GuiTricks.unboldLabel( label );
891 label.setHorizontalAlignment( JLabel.CENTER ); 914 label.setHorizontalAlignment( JLabel.CENTER );
892 m_infoPanel.add( label ); 915 m_infoPanel.add( label );
893 916
@@ -975,7 +998,7 @@ public class Gui
975 label.setPreferredSize( new Dimension( 100, label.getPreferredSize().height ) ); 998 label.setPreferredSize( new Dimension( 100, label.getPreferredSize().height ) );
976 panel.add( label ); 999 panel.add( label );
977 1000
978 panel.add( unboldLabel( new JLabel( value, JLabel.LEFT ) ) ); 1001 panel.add( GuiTricks.unboldLabel( new JLabel( value, JLabel.LEFT ) ) );
979 } 1002 }
980 1003
981 private void onCaretMove( int pos ) 1004 private void onCaretMove( int pos )
@@ -1059,7 +1082,7 @@ public class Gui
1059 // abort the rename 1082 // abort the rename
1060 JPanel panel = (JPanel)m_infoPanel.getComponent( 0 ); 1083 JPanel panel = (JPanel)m_infoPanel.getComponent( 0 );
1061 panel.remove( panel.getComponentCount() - 1 ); 1084 panel.remove( panel.getComponentCount() - 1 );
1062 panel.add( unboldLabel( new JLabel( m_reference.entry.getName(), JLabel.LEFT ) ) ); 1085 panel.add( GuiTricks.unboldLabel( new JLabel( m_reference.entry.getName(), JLabel.LEFT ) ) );
1063 1086
1064 m_editor.grabFocus(); 1087 m_editor.grabFocus();
1065 1088
@@ -1203,13 +1226,6 @@ public class Gui
1203 } 1226 }
1204 } 1227 }
1205 1228
1206 private JLabel unboldLabel( JLabel label )
1207 {
1208 Font font = label.getFont();
1209 label.setFont( font.deriveFont( font.getStyle() & ~Font.BOLD ) );
1210 return label;
1211 }
1212
1213 private void redraw( ) 1229 private void redraw( )
1214 { 1230 {
1215 m_frame.validate(); 1231 m_frame.validate();
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java
index a35db056..cf4f002e 100644
--- a/src/cuchaz/enigma/gui/GuiController.java
+++ b/src/cuchaz/enigma/gui/GuiController.java
@@ -20,6 +20,7 @@ import java.util.List;
20 20
21import com.google.common.collect.Lists; 21import com.google.common.collect.Lists;
22import com.google.common.collect.Queues; 22import com.google.common.collect.Queues;
23import com.strobel.decompiler.languages.java.ast.CompilationUnit;
23 24
24import cuchaz.enigma.Deobfuscator; 25import cuchaz.enigma.Deobfuscator;
25import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; 26import cuchaz.enigma.analysis.BehaviorReferenceTreeNode;
@@ -106,6 +107,27 @@ public class GuiController
106 refreshCurrentClass(); 107 refreshCurrentClass();
107 } 108 }
108 109
110 public void export( final File dirOut )
111 {
112 new Thread( )
113 {
114 @Override
115 public void run( )
116 {
117 try
118 {
119 ProgressDialog progress = new ProgressDialog( m_gui.getFrame() );
120 m_deobfuscator.writeSources( dirOut, progress );
121 progress.close();
122 }
123 catch( IOException ex )
124 {
125 throw new Error( ex );
126 }
127 }
128 }.start();
129 }
130
109 public Token getToken( int pos ) 131 public Token getToken( int pos )
110 { 132 {
111 if( m_index == null ) 133 if( m_index == null )
@@ -295,7 +317,9 @@ public class GuiController
295 public void run( ) 317 public void run( )
296 { 318 {
297 // decompile,deobfuscate the bytecode 319 // decompile,deobfuscate the bytecode
298 m_index = m_deobfuscator.getSource( classEntry.getClassName() ); 320 CompilationUnit sourceTree = m_deobfuscator.getSourceTree( classEntry.getClassName() );
321 String source = m_deobfuscator.getSource( sourceTree );
322 m_index = m_deobfuscator.getSourceIndex( sourceTree, source );
299 m_gui.setSource( m_index.getSource() ); 323 m_gui.setSource( m_index.getSource() );
300 if( obfReference != null ) 324 if( obfReference != null )
301 { 325 {
diff --git a/src/cuchaz/enigma/gui/GuiTricks.java b/src/cuchaz/enigma/gui/GuiTricks.java
new file mode 100644
index 00000000..c79f4329
--- /dev/null
+++ b/src/cuchaz/enigma/gui/GuiTricks.java
@@ -0,0 +1,25 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13import java.awt.Font;
14
15import javax.swing.JLabel;
16
17public class GuiTricks
18{
19 public static JLabel unboldLabel( JLabel label )
20 {
21 Font font = label.getFont();
22 label.setFont( font.deriveFont( font.getStyle() & ~Font.BOLD ) );
23 return label;
24 }
25}
diff --git a/src/cuchaz/enigma/gui/ProgressDialog.java b/src/cuchaz/enigma/gui/ProgressDialog.java
new file mode 100644
index 00000000..40ac6a69
--- /dev/null
+++ b/src/cuchaz/enigma/gui/ProgressDialog.java
@@ -0,0 +1,89 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13import java.awt.BorderLayout;
14import java.awt.Container;
15import java.awt.Dimension;
16import java.awt.FlowLayout;
17
18import javax.swing.BorderFactory;
19import javax.swing.JFrame;
20import javax.swing.JLabel;
21import javax.swing.JPanel;
22import javax.swing.JProgressBar;
23import javax.swing.WindowConstants;
24
25import cuchaz.enigma.Constants;
26import cuchaz.enigma.Deobfuscator.ProgressListener;
27
28public class ProgressDialog implements ProgressListener
29{
30 private JFrame m_frame;
31 private JLabel m_text;
32 private JProgressBar m_progress;
33
34 public ProgressDialog( JFrame parent )
35 {
36 // init frame
37 m_frame = new JFrame( Constants.Name + " - Export" );
38 final Container pane = m_frame.getContentPane();
39 FlowLayout layout = new FlowLayout();
40 layout.setAlignment( FlowLayout.LEFT );
41 pane.setLayout( layout );
42
43 pane.add( new JLabel( "Decompiling classes..." ) );
44
45 // set up the progress bar
46 JPanel panel = new JPanel();
47 pane.add( panel );
48 panel.setLayout( new BorderLayout() );
49 m_text = GuiTricks.unboldLabel( new JLabel() );
50 m_progress = new JProgressBar();
51 m_text.setBorder( BorderFactory.createEmptyBorder( 0, 0, 10, 0 ) );
52 panel.add( m_text, BorderLayout.NORTH );
53 panel.add( m_progress, BorderLayout.CENTER );
54 panel.setPreferredSize( new Dimension( 360, 50 ) );
55
56 // show the frame
57 pane.doLayout();
58 m_frame.setSize( 400, 120 );
59 m_frame.setResizable( false );
60 m_frame.setLocationRelativeTo( parent );
61 m_frame.setVisible( true );
62 m_frame.setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE );
63 }
64
65 public void close( )
66 {
67 m_frame.dispose();
68 }
69
70 @Override
71 public void init( int totalWork )
72 {
73 m_text.setText( "Decompiling " + totalWork + " classes..." );
74 m_progress.setMinimum( 0 );
75 m_progress.setMaximum( totalWork );
76 m_progress.setValue( 0 );
77 }
78
79 @Override
80 public void onProgress( int numDone, String message )
81 {
82 m_text.setText( message );
83 m_progress.setValue( numDone );
84
85 // update the frame
86 m_frame.validate();
87 m_frame.repaint();
88 }
89}