summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jeff2014-09-18 00:17:43 -0400
committerGravatar jeff2014-09-18 00:17:43 -0400
commitc65a64fc89169456febc1b4c953dbcfbafdc5f0e (patch)
tree136b8145423724c8a3392ff89edc492262cc995d
parentchanged "Show Calls" menu to search for calls to the default constructor when... (diff)
downloadenigma-c65a64fc89169456febc1b4c953dbcfbafdc5f0e.tar.gz
enigma-c65a64fc89169456febc1b4c953dbcfbafdc5f0e.tar.xz
enigma-c65a64fc89169456febc1b4c953dbcfbafdc5f0e.zip
added better error handling for source export
added checks to make sure we don't try to decopmile classes outside of the jar
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java29
-rw-r--r--src/cuchaz/enigma/TranslatingTypeLoader.java8
-rw-r--r--src/cuchaz/enigma/gui/Gui.java84
-rw-r--r--src/cuchaz/enigma/gui/GuiController.java13
4 files changed, 80 insertions, 54 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index 0847049e..1178ed60 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -200,6 +200,12 @@ public class Deobfuscator
200 className = classMapping.getDeobfName(); 200 className = classMapping.getDeobfName();
201 } 201 }
202 202
203 // is this class even in the jar?
204 if( !m_jarIndex.containsObfClass( new ClassEntry( className ) ) )
205 {
206 return null;
207 }
208
203 // set the type loader 209 // set the type loader
204 m_settings.setTypeLoader( new TranslatingTypeLoader( 210 m_settings.setTypeLoader( new TranslatingTypeLoader(
205 m_jar, 211 m_jar,
@@ -279,15 +285,22 @@ public class Deobfuscator
279 progress.onProgress( i++, deobfClassEntry.toString() ); 285 progress.onProgress( i++, deobfClassEntry.toString() );
280 } 286 }
281 287
282 // get the source 288 try
283 String source = getSource( getSourceTree( obfClassEntry.getName() ) ); 289 {
284 290 // get the source
285 // write the file 291 String source = getSource( getSourceTree( obfClassEntry.getName() ) );
286 File file = new File( dirOut, deobfClassEntry.getName().replace( '.', '/' ) + ".java" ); 292
287 file.getParentFile().mkdirs(); 293 // write the file
288 try( FileWriter out = new FileWriter( file ) ) 294 File file = new File( dirOut, deobfClassEntry.getName().replace( '.', '/' ) + ".java" );
295 file.getParentFile().mkdirs();
296 try( FileWriter out = new FileWriter( file ) )
297 {
298 out.write( source );
299 }
300 }
301 catch( Throwable t )
289 { 302 {
290 out.write( source ); 303 throw new Error( "Unable to deobfuscate class " + deobfClassEntry.toString() + " (" + obfClassEntry.toString() + ")", t );
291 } 304 }
292 } 305 }
293 306
diff --git a/src/cuchaz/enigma/TranslatingTypeLoader.java b/src/cuchaz/enigma/TranslatingTypeLoader.java
index e70093eb..d321421a 100644
--- a/src/cuchaz/enigma/TranslatingTypeLoader.java
+++ b/src/cuchaz/enigma/TranslatingTypeLoader.java
@@ -124,10 +124,11 @@ public class TranslatingTypeLoader implements ITypeLoader
124 ClassEntry obfClassEntry = m_obfuscatingTranslator.translateEntry( deobfClassEntry ); 124 ClassEntry obfClassEntry = m_obfuscatingTranslator.translateEntry( deobfClassEntry );
125 125
126 // is this an inner class referenced directly? 126 // is this an inner class referenced directly?
127 if( m_jarIndex.getOuterClass( obfClassEntry.getName() ) != null ) 127 String obfOuterClassName = m_jarIndex.getOuterClass( obfClassEntry.getName() );
128 if( obfOuterClassName != null )
128 { 129 {
129 // this class doesn't really exist. Reference it by outer$inner instead 130 // this class doesn't really exist. Reference it by outer$inner instead
130 System.err.println( String.format( "WARNING: class %s referenced by bare inner name", deobfClassName ) ); 131 System.err.println( String.format( "WARNING: class %s referenced by bare inner name instead of via outer class %s", deobfClassName, obfOuterClassName ) );
131 return null; 132 return null;
132 } 133 }
133 134
@@ -210,6 +211,9 @@ public class TranslatingTypeLoader implements ITypeLoader
210 // sanity checking 211 // sanity checking
211 assertClassName( c, deobfClassEntry ); 212 assertClassName( c, deobfClassEntry );
212 213
214 // DEBUG
215 Util.writeClass( c );
216
213 // we have a transformed class! 217 // we have a transformed class!
214 return c.toBytecode(); 218 return c.toBytecode();
215 } 219 }
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java
index 7fac02de..1995cb80 100644
--- a/src/cuchaz/enigma/gui/Gui.java
+++ b/src/cuchaz/enigma/gui/Gui.java
@@ -162,11 +162,7 @@ public class Gui
162 @Override 162 @Override
163 public void onSelectClass( ClassEntry classEntry ) 163 public void onSelectClass( ClassEntry classEntry )
164 { 164 {
165 if( m_reference != null ) 165 navigateTo( classEntry );
166 {
167 m_controller.savePreviousReference( m_reference );
168 }
169 m_controller.openDeclaration( classEntry );
170 } 166 }
171 } ); 167 } );
172 JScrollPane obfScroller = new JScrollPane( m_obfClasses ); 168 JScrollPane obfScroller = new JScrollPane( m_obfClasses );
@@ -182,11 +178,7 @@ public class Gui
182 @Override 178 @Override
183 public void onSelectClass( ClassEntry classEntry ) 179 public void onSelectClass( ClassEntry classEntry )
184 { 180 {
185 if( m_reference != null ) 181 navigateTo( classEntry );
186 {
187 m_controller.savePreviousReference( m_reference );
188 }
189 m_controller.openDeclaration( classEntry );
190 } 182 }
191 } ); 183 } );
192 JScrollPane deobfScroller = new JScrollPane( m_deobfClasses ); 184 JScrollPane deobfScroller = new JScrollPane( m_deobfClasses );
@@ -247,7 +239,7 @@ public class Gui
247 break; 239 break;
248 240
249 case KeyEvent.VK_N: 241 case KeyEvent.VK_N:
250 openDeclaration(); 242 navigateTo( m_reference.entry );
251 break; 243 break;
252 244
253 case KeyEvent.VK_P: 245 case KeyEvent.VK_P:
@@ -335,7 +327,7 @@ public class Gui
335 @Override 327 @Override
336 public void actionPerformed( ActionEvent event ) 328 public void actionPerformed( ActionEvent event )
337 { 329 {
338 openDeclaration(); 330 navigateTo( m_reference.entry );
339 } 331 }
340 } ); 332 } );
341 menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_N, 0 ) ); 333 menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_N, 0 ) );
@@ -379,22 +371,15 @@ public class Gui
379 Object node = path.getLastPathComponent(); 371 Object node = path.getLastPathComponent();
380 if( node instanceof ClassInheritanceTreeNode ) 372 if( node instanceof ClassInheritanceTreeNode )
381 { 373 {
382 if( m_reference != null ) 374 ClassInheritanceTreeNode classNode = (ClassInheritanceTreeNode)node;
383 { 375 navigateTo( new ClassEntry( classNode.getObfClassName() ) );
384 m_controller.savePreviousReference( m_reference );
385 }
386 m_controller.openDeclaration( new ClassEntry( ((ClassInheritanceTreeNode)node).getObfClassName() ) );
387 } 376 }
388 else if( node instanceof MethodInheritanceTreeNode ) 377 else if( node instanceof MethodInheritanceTreeNode )
389 { 378 {
390 MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode)node; 379 MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode)node;
391 if( methodNode.isImplemented() ) 380 if( methodNode.isImplemented() )
392 { 381 {
393 if( m_reference != null ) 382 navigateTo( methodNode.getMethodEntry() );
394 {
395 m_controller.savePreviousReference( m_reference );
396 }
397 m_controller.openDeclaration( methodNode.getMethodEntry() );
398 } 383 }
399 } 384 }
400 } 385 }
@@ -425,12 +410,12 @@ public class Gui
425 if( node instanceof ClassImplementationsTreeNode ) 410 if( node instanceof ClassImplementationsTreeNode )
426 { 411 {
427 ClassImplementationsTreeNode classNode = (ClassImplementationsTreeNode)node; 412 ClassImplementationsTreeNode classNode = (ClassImplementationsTreeNode)node;
428 m_controller.openDeclaration( classNode.getClassEntry() ); 413 navigateTo( classNode.getClassEntry() );
429 } 414 }
430 else if( node instanceof MethodImplementationsTreeNode ) 415 else if( node instanceof MethodImplementationsTreeNode )
431 { 416 {
432 MethodImplementationsTreeNode methodNode = (MethodImplementationsTreeNode)node; 417 MethodImplementationsTreeNode methodNode = (MethodImplementationsTreeNode)node;
433 m_controller.openDeclaration( methodNode.getMethodEntry() ); 418 navigateTo( methodNode.getMethodEntry() );
434 } 419 }
435 } 420 }
436 } 421 }
@@ -460,18 +445,14 @@ public class Gui
460 Object node = path.getLastPathComponent(); 445 Object node = path.getLastPathComponent();
461 if( node instanceof ReferenceTreeNode ) 446 if( node instanceof ReferenceTreeNode )
462 { 447 {
463 if( m_reference != null )
464 {
465 m_controller.savePreviousReference( m_reference );
466 }
467 ReferenceTreeNode<Entry,Entry> referenceNode = ((ReferenceTreeNode<Entry,Entry>)node); 448 ReferenceTreeNode<Entry,Entry> referenceNode = ((ReferenceTreeNode<Entry,Entry>)node);
468 if( referenceNode.getReference() != null ) 449 if( referenceNode.getReference() != null )
469 { 450 {
470 m_controller.openReference( referenceNode.getReference() ); 451 navigateTo( referenceNode.getReference() );
471 } 452 }
472 else 453 else
473 { 454 {
474 m_controller.openDeclaration( referenceNode.getEntry() ); 455 navigateTo( referenceNode.getEntry() );
475 } 456 }
476 } 457 }
477 } 458 }
@@ -1028,6 +1009,7 @@ public class Gui
1028 boolean isFieldEntry = isToken && m_reference.entry instanceof FieldEntry; 1009 boolean isFieldEntry = isToken && m_reference.entry instanceof FieldEntry;
1029 boolean isMethodEntry = isToken && m_reference.entry instanceof MethodEntry; 1010 boolean isMethodEntry = isToken && m_reference.entry instanceof MethodEntry;
1030 boolean isConstructorEntry = isToken && m_reference.entry instanceof ConstructorEntry; 1011 boolean isConstructorEntry = isToken && m_reference.entry instanceof ConstructorEntry;
1012 boolean isInJar = isToken && m_controller.entryIsInJar( m_reference.entry.getClassEntry() );
1031 1013
1032 if( isToken ) 1014 if( isToken )
1033 { 1015 {
@@ -1038,14 +1020,42 @@ public class Gui
1038 clearReference(); 1020 clearReference();
1039 } 1021 }
1040 1022
1041 m_renameMenu.setEnabled( isToken ); 1023 m_renameMenu.setEnabled( isInJar && isToken );
1042 m_showInheritanceMenu.setEnabled( isClassEntry || isMethodEntry || isConstructorEntry ); 1024 m_showInheritanceMenu.setEnabled( isClassEntry || isMethodEntry || isConstructorEntry );
1043 m_showImplementationsMenu.setEnabled( isClassEntry || isMethodEntry ); 1025 m_showImplementationsMenu.setEnabled( isClassEntry || isMethodEntry );
1044 m_showCallsMenu.setEnabled( isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry ); 1026 m_showCallsMenu.setEnabled( isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry );
1045 m_openEntryMenu.setEnabled( isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry ); 1027 m_openEntryMenu.setEnabled( isInJar && ( isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry ) );
1046 m_openPreviousMenu.setEnabled( m_controller.hasPreviousLocation() ); 1028 m_openPreviousMenu.setEnabled( m_controller.hasPreviousLocation() );
1047 } 1029 }
1048 1030
1031 private void navigateTo( Entry entry )
1032 {
1033 if( !m_controller.entryIsInJar( entry ) )
1034 {
1035 // entry is not in the jar. Ignore it
1036 return;
1037 }
1038 if( m_reference != null )
1039 {
1040 m_controller.savePreviousReference( m_reference );
1041 }
1042 m_controller.openDeclaration( entry );
1043 }
1044
1045 private void navigateTo( EntryReference<Entry,Entry> reference )
1046 {
1047 if( !m_controller.entryIsInJar( reference.getClassEntry() ) )
1048 {
1049 // reference is not in the jar. Ignore it
1050 return;
1051 }
1052 if( m_reference != null )
1053 {
1054 m_controller.savePreviousReference( m_reference );
1055 }
1056 m_controller.openReference( reference );
1057 }
1058
1049 private void startRename( ) 1059 private void startRename( )
1050 { 1060 {
1051 // init the text box 1061 // init the text box
@@ -1232,16 +1242,6 @@ public class Gui
1232 return new TreePath( nodes.toArray() ); 1242 return new TreePath( nodes.toArray() );
1233 } 1243 }
1234 1244
1235 private void openDeclaration( )
1236 {
1237 if( m_reference == null )
1238 {
1239 return;
1240 }
1241 m_controller.savePreviousReference( m_reference );
1242 m_controller.openDeclaration( m_reference.entry );
1243 }
1244
1245 private void close( ) 1245 private void close( )
1246 { 1246 {
1247 if( !m_controller.isDirty() ) 1247 if( !m_controller.isDirty() )
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java
index c0fb2e40..3f54ecd4 100644
--- a/src/cuchaz/enigma/gui/GuiController.java
+++ b/src/cuchaz/enigma/gui/GuiController.java
@@ -170,7 +170,7 @@ public class GuiController
170 return m_deobfuscator.hasMapping( m_deobfuscator.obfuscateEntry( deobfEntry ) ); 170 return m_deobfuscator.hasMapping( m_deobfuscator.obfuscateEntry( deobfEntry ) );
171 } 171 }
172 172
173 public boolean entryIsObfuscatedIdenfitier( Entry deobfEntry ) 173 public boolean entryIsInJar( Entry deobfEntry )
174 { 174 {
175 return m_deobfuscator.isObfuscatedIdentifier( m_deobfuscator.obfuscateEntry( deobfEntry ) ); 175 return m_deobfuscator.isObfuscatedIdentifier( m_deobfuscator.obfuscateEntry( deobfEntry ) );
176 } 176 }
@@ -268,6 +268,10 @@ public class GuiController
268 // get the reference target class 268 // get the reference target class
269 EntryReference<Entry,Entry> obfReference = m_deobfuscator.obfuscateReference( deobfReference ); 269 EntryReference<Entry,Entry> obfReference = m_deobfuscator.obfuscateReference( deobfReference );
270 ClassEntry obfClassEntry = obfReference.getClassEntry().getOuterClassEntry(); 270 ClassEntry obfClassEntry = obfReference.getClassEntry().getOuterClassEntry();
271 if( !m_deobfuscator.isObfuscatedIdentifier( obfClassEntry ) )
272 {
273 throw new IllegalArgumentException( "Entry must be in the jar!" );
274 }
271 if( m_currentObfClass == null || !m_currentObfClass.equals( obfClassEntry ) ) 275 if( m_currentObfClass == null || !m_currentObfClass.equals( obfClassEntry ) )
272 { 276 {
273 // deobfuscate the class, then navigate to the reference 277 // deobfuscate the class, then navigate to the reference
@@ -347,6 +351,11 @@ public class GuiController
347 { 351 {
348 // decompile,deobfuscate the bytecode 352 // decompile,deobfuscate the bytecode
349 CompilationUnit sourceTree = m_deobfuscator.getSourceTree( classEntry.getClassName() ); 353 CompilationUnit sourceTree = m_deobfuscator.getSourceTree( classEntry.getClassName() );
354 if( sourceTree == null )
355 {
356 // decompilation of this class is not supported
357 return;
358 }
350 String source = m_deobfuscator.getSource( sourceTree ); 359 String source = m_deobfuscator.getSource( sourceTree );
351 m_index = m_deobfuscator.getSourceIndex( sourceTree, source ); 360 m_index = m_deobfuscator.getSourceIndex( sourceTree, source );
352 m_gui.setSource( m_index.getSource() ); 361 m_gui.setSource( m_index.getSource() );
@@ -365,7 +374,7 @@ public class GuiController
365 { 374 {
366 deobfuscatedTokens.add( token ); 375 deobfuscatedTokens.add( token );
367 } 376 }
368 else if( entryIsObfuscatedIdenfitier( reference.entry ) ) 377 else if( entryIsInJar( reference.entry ) )
369 { 378 {
370 obfuscatedTokens.add( token ); 379 obfuscatedTokens.add( token );
371 } 380 }