From d71c0af8ed298bfb4b35b4e3e61b5678bc1c7d9f Mon Sep 17 00:00:00 2001 From: jeff Date: Wed, 6 Aug 2014 00:22:25 -0400 Subject: added simple class inheritance browsing --- .../enigma/gui/ClassInheritanceTreeNode.java | 56 ++++++++++++++++++++ src/cuchaz/enigma/gui/Gui.java | 61 ++++++++++++++++++---- src/cuchaz/enigma/gui/GuiController.java | 22 ++++++++ 3 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 src/cuchaz/enigma/gui/ClassInheritanceTreeNode.java (limited to 'src/cuchaz/enigma/gui') diff --git a/src/cuchaz/enigma/gui/ClassInheritanceTreeNode.java b/src/cuchaz/enigma/gui/ClassInheritanceTreeNode.java new file mode 100644 index 0000000..921a1e9 --- /dev/null +++ b/src/cuchaz/enigma/gui/ClassInheritanceTreeNode.java @@ -0,0 +1,56 @@ +package cuchaz.enigma.gui; + +import java.util.List; + +import javax.swing.tree.DefaultMutableTreeNode; + +import com.beust.jcommander.internal.Lists; + +import cuchaz.enigma.mapping.Ancestries; + +public class ClassInheritanceTreeNode extends DefaultMutableTreeNode +{ + private static final long serialVersionUID = 4432367405826178490L; + + String m_className; + + public ClassInheritanceTreeNode( String className ) + { + m_className = className; + } + + public String getClassName( ) + { + return m_className; + } + + @Override + public String toString( ) + { + return m_className; + } + + public void load( Ancestries ancestries, boolean recurse ) + { + // get all the child nodes + List nodes = Lists.newArrayList(); + for( String subclassName : ancestries.getSubclasses( m_className ) ) + { + nodes.add( new ClassInheritanceTreeNode( subclassName ) ); + } + + // add then to this node + for( ClassInheritanceTreeNode node : nodes ) + { + this.add( node ); + } + + if( recurse ) + { + for( ClassInheritanceTreeNode node : nodes ) + { + node.load( ancestries, true ); + } + } + } +} diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java index f9afb64..2002a4d 100644 --- a/src/cuchaz/enigma/gui/Gui.java +++ b/src/cuchaz/enigma/gui/Gui.java @@ -49,12 +49,18 @@ import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; +import javax.swing.JTree; import javax.swing.ListSelectionModel; import javax.swing.WindowConstants; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.text.BadLocationException; import javax.swing.text.Highlighter; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; + +import com.beust.jcommander.internal.Lists; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.SyntaxDocument; @@ -100,7 +106,7 @@ public class Gui private JPanel m_infoPanel; private BoxHighlightPainter m_obfuscatedHighlightPainter; private BoxHighlightPainter m_deobfuscatedHighlightPainter; - private JPanel m_inheritancePanel; + private JTree m_inheritanceTree; // dynamic menu items private JMenuItem m_closeJarMenu; @@ -136,6 +142,7 @@ public class Gui m_obfClasses.setCellRenderer( new ObfuscatedClassListCellRenderer() ); m_obfClasses.addMouseListener( new MouseAdapter() { + @Override public void mouseClicked( MouseEvent event ) { if( event.getClickCount() == 2 ) @@ -161,6 +168,7 @@ public class Gui m_deobfClasses.setCellRenderer( new DeobfuscatedClassListCellRenderer() ); m_deobfClasses.addMouseListener( new MouseAdapter() { + @Override public void mouseClicked( MouseEvent event ) { if( event.getClickCount() == 2 ) @@ -252,7 +260,26 @@ public class Gui } // init inheritance panel - m_inheritancePanel = new JPanel(); + m_inheritanceTree = new JTree(); + m_inheritanceTree.setModel( null ); + m_inheritanceTree.addMouseListener( new MouseAdapter( ) + { + @Override + public void mouseClicked( MouseEvent event ) + { + if( event.getClickCount() == 2 ) + { + ClassInheritanceTreeNode node = (ClassInheritanceTreeNode)m_inheritanceTree.getSelectionPath().getLastPathComponent(); + if( node != null ) + { + m_controller.deobfuscateClass( new ClassFile( node.getClassName() ) ); + } + } + } + } ); + JPanel inheritancePanel = new JPanel(); + inheritancePanel.setLayout( new BorderLayout() ); + inheritancePanel.add( new JScrollPane( m_inheritanceTree ) ); // layout controls JSplitPane splitLeft = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel ); @@ -263,7 +290,7 @@ public class Gui centerPanel.add( sourceScroller, BorderLayout.CENTER ); JTabbedPane tabbedPane = new JTabbedPane(); tabbedPane.setPreferredSize( new Dimension( 200, 0 ) ); - tabbedPane.addTab( "Inheritance", m_inheritancePanel ); + tabbedPane.addTab( "Inheritance", inheritancePanel ); JSplitPane splitRight = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, true, centerPanel, tabbedPane ); splitRight.setResizeWeight( 1 ); // let the left side take all the slack splitRight.resetToPreferredSizes(); @@ -748,12 +775,28 @@ public class Gui private void showInheritance( ) { - m_inheritancePanel.removeAll(); - - // TEMP - m_inheritancePanel.add( new JLabel( m_selectedEntryPair.obf.getName() ) ); - m_inheritancePanel.add( new JLabel( m_selectedEntryPair.deobf.getName() ) ); - + // get the current class + if( m_selectedEntryPair.obf instanceof ClassEntry ) + { + ClassInheritanceTreeNode classNode = m_controller.getClassInheritance( (ClassEntry)m_selectedEntryPair.obf ); + + // build the path from the root to the class node + List nodes = Lists.newArrayList(); + TreeNode node = classNode; + do + { + nodes.add( node ); + node = node.getParent(); + } + while( node != null ); + Collections.reverse( nodes ); + TreePath path = new TreePath( nodes.toArray() ); + + // show the tree at the root + m_inheritanceTree.setModel( new DefaultTreeModel( (TreeNode)path.getPathComponent( 0 ) ) ); + m_inheritanceTree.expandPath( path ); + m_inheritanceTree.setSelectionRow( m_inheritanceTree.getRowForPath( path ) ); + } redraw(); } diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java index e1ba49a..452632f 100644 --- a/src/cuchaz/enigma/gui/GuiController.java +++ b/src/cuchaz/enigma/gui/GuiController.java @@ -26,6 +26,7 @@ import cuchaz.enigma.ClassFile; import cuchaz.enigma.Deobfuscator; import cuchaz.enigma.analysis.Analyzer; import cuchaz.enigma.analysis.SourceIndex; +import cuchaz.enigma.mapping.ClassEntry; import cuchaz.enigma.mapping.Entry; import cuchaz.enigma.mapping.EntryPair; import cuchaz.enigma.mapping.MappingsReader; @@ -129,6 +130,27 @@ public class GuiController return m_deobfuscator.hasMapping( pair.obf ); } + public ClassInheritanceTreeNode getClassInheritance( ClassEntry classEntry ) + { + // create a node for this class + ClassInheritanceTreeNode thisNode = new ClassInheritanceTreeNode( classEntry.getName() ); + + // expand all children recursively + thisNode.load( m_deobfuscator.getAncestries(), true ); + + // get the ancestors too + ClassInheritanceTreeNode node = thisNode; + for( String superclassName : m_deobfuscator.getAncestries().getAncestry( classEntry.getName() ) ) + { + // add the parent node + ClassInheritanceTreeNode parentNode = new ClassInheritanceTreeNode( superclassName ); + parentNode.add( node ); + node = parentNode; + } + + return thisNode; + } + public void rename( Entry obfsEntry, String newName, int lineNum ) { m_deobfuscator.rename( obfsEntry, newName ); -- cgit v1.2.3