From c65a64fc89169456febc1b4c953dbcfbafdc5f0e Mon Sep 17 00:00:00 2001 From: jeff Date: Thu, 18 Sep 2014 00:17:43 -0400 Subject: added better error handling for source export added checks to make sure we don't try to decopmile classes outside of the jar --- src/cuchaz/enigma/Deobfuscator.java | 29 +++++++--- src/cuchaz/enigma/TranslatingTypeLoader.java | 8 ++- src/cuchaz/enigma/gui/Gui.java | 84 ++++++++++++++-------------- src/cuchaz/enigma/gui/GuiController.java | 13 ++++- 4 files changed, 80 insertions(+), 54 deletions(-) (limited to 'src/cuchaz/enigma') diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java index 0847049..1178ed6 100644 --- a/src/cuchaz/enigma/Deobfuscator.java +++ b/src/cuchaz/enigma/Deobfuscator.java @@ -200,6 +200,12 @@ public class Deobfuscator className = classMapping.getDeobfName(); } + // is this class even in the jar? + if( !m_jarIndex.containsObfClass( new ClassEntry( className ) ) ) + { + return null; + } + // set the type loader m_settings.setTypeLoader( new TranslatingTypeLoader( m_jar, @@ -279,15 +285,22 @@ public class Deobfuscator progress.onProgress( i++, deobfClassEntry.toString() ); } - // get the source - String source = getSource( getSourceTree( obfClassEntry.getName() ) ); - - // write the file - File file = new File( dirOut, deobfClassEntry.getName().replace( '.', '/' ) + ".java" ); - file.getParentFile().mkdirs(); - try( FileWriter out = new FileWriter( file ) ) + try + { + // get the source + String source = getSource( getSourceTree( obfClassEntry.getName() ) ); + + // write the file + File file = new File( dirOut, deobfClassEntry.getName().replace( '.', '/' ) + ".java" ); + file.getParentFile().mkdirs(); + try( FileWriter out = new FileWriter( file ) ) + { + out.write( source ); + } + } + catch( Throwable t ) { - out.write( source ); + throw new Error( "Unable to deobfuscate class " + deobfClassEntry.toString() + " (" + obfClassEntry.toString() + ")", t ); } } diff --git a/src/cuchaz/enigma/TranslatingTypeLoader.java b/src/cuchaz/enigma/TranslatingTypeLoader.java index e70093e..d321421 100644 --- a/src/cuchaz/enigma/TranslatingTypeLoader.java +++ b/src/cuchaz/enigma/TranslatingTypeLoader.java @@ -124,10 +124,11 @@ public class TranslatingTypeLoader implements ITypeLoader ClassEntry obfClassEntry = m_obfuscatingTranslator.translateEntry( deobfClassEntry ); // is this an inner class referenced directly? - if( m_jarIndex.getOuterClass( obfClassEntry.getName() ) != null ) + String obfOuterClassName = m_jarIndex.getOuterClass( obfClassEntry.getName() ); + if( obfOuterClassName != null ) { // this class doesn't really exist. Reference it by outer$inner instead - System.err.println( String.format( "WARNING: class %s referenced by bare inner name", deobfClassName ) ); + System.err.println( String.format( "WARNING: class %s referenced by bare inner name instead of via outer class %s", deobfClassName, obfOuterClassName ) ); return null; } @@ -210,6 +211,9 @@ public class TranslatingTypeLoader implements ITypeLoader // sanity checking assertClassName( c, deobfClassEntry ); + // DEBUG + Util.writeClass( c ); + // we have a transformed class! return c.toBytecode(); } diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java index 7fac02d..1995cb8 100644 --- a/src/cuchaz/enigma/gui/Gui.java +++ b/src/cuchaz/enigma/gui/Gui.java @@ -162,11 +162,7 @@ public class Gui @Override public void onSelectClass( ClassEntry classEntry ) { - if( m_reference != null ) - { - m_controller.savePreviousReference( m_reference ); - } - m_controller.openDeclaration( classEntry ); + navigateTo( classEntry ); } } ); JScrollPane obfScroller = new JScrollPane( m_obfClasses ); @@ -182,11 +178,7 @@ public class Gui @Override public void onSelectClass( ClassEntry classEntry ) { - if( m_reference != null ) - { - m_controller.savePreviousReference( m_reference ); - } - m_controller.openDeclaration( classEntry ); + navigateTo( classEntry ); } } ); JScrollPane deobfScroller = new JScrollPane( m_deobfClasses ); @@ -247,7 +239,7 @@ public class Gui break; case KeyEvent.VK_N: - openDeclaration(); + navigateTo( m_reference.entry ); break; case KeyEvent.VK_P: @@ -335,7 +327,7 @@ public class Gui @Override public void actionPerformed( ActionEvent event ) { - openDeclaration(); + navigateTo( m_reference.entry ); } } ); menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_N, 0 ) ); @@ -379,22 +371,15 @@ public class Gui Object node = path.getLastPathComponent(); if( node instanceof ClassInheritanceTreeNode ) { - if( m_reference != null ) - { - m_controller.savePreviousReference( m_reference ); - } - m_controller.openDeclaration( new ClassEntry( ((ClassInheritanceTreeNode)node).getObfClassName() ) ); + ClassInheritanceTreeNode classNode = (ClassInheritanceTreeNode)node; + navigateTo( new ClassEntry( classNode.getObfClassName() ) ); } else if( node instanceof MethodInheritanceTreeNode ) { MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode)node; if( methodNode.isImplemented() ) { - if( m_reference != null ) - { - m_controller.savePreviousReference( m_reference ); - } - m_controller.openDeclaration( methodNode.getMethodEntry() ); + navigateTo( methodNode.getMethodEntry() ); } } } @@ -425,12 +410,12 @@ public class Gui if( node instanceof ClassImplementationsTreeNode ) { ClassImplementationsTreeNode classNode = (ClassImplementationsTreeNode)node; - m_controller.openDeclaration( classNode.getClassEntry() ); + navigateTo( classNode.getClassEntry() ); } else if( node instanceof MethodImplementationsTreeNode ) { MethodImplementationsTreeNode methodNode = (MethodImplementationsTreeNode)node; - m_controller.openDeclaration( methodNode.getMethodEntry() ); + navigateTo( methodNode.getMethodEntry() ); } } } @@ -460,18 +445,14 @@ public class Gui Object node = path.getLastPathComponent(); if( node instanceof ReferenceTreeNode ) { - if( m_reference != null ) - { - m_controller.savePreviousReference( m_reference ); - } ReferenceTreeNode referenceNode = ((ReferenceTreeNode)node); if( referenceNode.getReference() != null ) { - m_controller.openReference( referenceNode.getReference() ); + navigateTo( referenceNode.getReference() ); } else { - m_controller.openDeclaration( referenceNode.getEntry() ); + navigateTo( referenceNode.getEntry() ); } } } @@ -1028,6 +1009,7 @@ public class Gui boolean isFieldEntry = isToken && m_reference.entry instanceof FieldEntry; boolean isMethodEntry = isToken && m_reference.entry instanceof MethodEntry; boolean isConstructorEntry = isToken && m_reference.entry instanceof ConstructorEntry; + boolean isInJar = isToken && m_controller.entryIsInJar( m_reference.entry.getClassEntry() ); if( isToken ) { @@ -1038,14 +1020,42 @@ public class Gui clearReference(); } - m_renameMenu.setEnabled( isToken ); + m_renameMenu.setEnabled( isInJar && isToken ); m_showInheritanceMenu.setEnabled( isClassEntry || isMethodEntry || isConstructorEntry ); m_showImplementationsMenu.setEnabled( isClassEntry || isMethodEntry ); m_showCallsMenu.setEnabled( isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry ); - m_openEntryMenu.setEnabled( isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry ); + m_openEntryMenu.setEnabled( isInJar && ( isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry ) ); m_openPreviousMenu.setEnabled( m_controller.hasPreviousLocation() ); } + private void navigateTo( Entry entry ) + { + if( !m_controller.entryIsInJar( entry ) ) + { + // entry is not in the jar. Ignore it + return; + } + if( m_reference != null ) + { + m_controller.savePreviousReference( m_reference ); + } + m_controller.openDeclaration( entry ); + } + + private void navigateTo( EntryReference reference ) + { + if( !m_controller.entryIsInJar( reference.getClassEntry() ) ) + { + // reference is not in the jar. Ignore it + return; + } + if( m_reference != null ) + { + m_controller.savePreviousReference( m_reference ); + } + m_controller.openReference( reference ); + } + private void startRename( ) { // init the text box @@ -1232,16 +1242,6 @@ public class Gui return new TreePath( nodes.toArray() ); } - private void openDeclaration( ) - { - if( m_reference == null ) - { - return; - } - m_controller.savePreviousReference( m_reference ); - m_controller.openDeclaration( m_reference.entry ); - } - private void close( ) { if( !m_controller.isDirty() ) diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java index c0fb2e4..3f54ecd 100644 --- a/src/cuchaz/enigma/gui/GuiController.java +++ b/src/cuchaz/enigma/gui/GuiController.java @@ -170,7 +170,7 @@ public class GuiController return m_deobfuscator.hasMapping( m_deobfuscator.obfuscateEntry( deobfEntry ) ); } - public boolean entryIsObfuscatedIdenfitier( Entry deobfEntry ) + public boolean entryIsInJar( Entry deobfEntry ) { return m_deobfuscator.isObfuscatedIdentifier( m_deobfuscator.obfuscateEntry( deobfEntry ) ); } @@ -268,6 +268,10 @@ public class GuiController // get the reference target class EntryReference obfReference = m_deobfuscator.obfuscateReference( deobfReference ); ClassEntry obfClassEntry = obfReference.getClassEntry().getOuterClassEntry(); + if( !m_deobfuscator.isObfuscatedIdentifier( obfClassEntry ) ) + { + throw new IllegalArgumentException( "Entry must be in the jar!" ); + } if( m_currentObfClass == null || !m_currentObfClass.equals( obfClassEntry ) ) { // deobfuscate the class, then navigate to the reference @@ -347,6 +351,11 @@ public class GuiController { // decompile,deobfuscate the bytecode CompilationUnit sourceTree = m_deobfuscator.getSourceTree( classEntry.getClassName() ); + if( sourceTree == null ) + { + // decompilation of this class is not supported + return; + } String source = m_deobfuscator.getSource( sourceTree ); m_index = m_deobfuscator.getSourceIndex( sourceTree, source ); m_gui.setSource( m_index.getSource() ); @@ -365,7 +374,7 @@ public class GuiController { deobfuscatedTokens.add( token ); } - else if( entryIsObfuscatedIdenfitier( reference.entry ) ) + else if( entryIsInJar( reference.entry ) ) { obfuscatedTokens.add( token ); } -- cgit v1.2.3