diff options
| author | 2014-08-06 00:22:25 -0400 | |
|---|---|---|
| committer | 2014-08-06 00:22:25 -0400 | |
| commit | d71c0af8ed298bfb4b35b4e3e61b5678bc1c7d9f (patch) | |
| tree | 103fea72601d989d1a1bb503c6bcfe662c6dc541 /src/cuchaz | |
| parent | started on inheritance viewer (diff) | |
| download | enigma-fork-d71c0af8ed298bfb4b35b4e3e61b5678bc1c7d9f.tar.gz enigma-fork-d71c0af8ed298bfb4b35b4e3e61b5678bc1c7d9f.tar.xz enigma-fork-d71c0af8ed298bfb4b35b4e3e61b5678bc1c7d9f.zip | |
added simple class inheritance browsing
Diffstat (limited to 'src/cuchaz')
| -rw-r--r-- | src/cuchaz/enigma/Deobfuscator.java | 5 | ||||
| -rw-r--r-- | src/cuchaz/enigma/TranslatingTypeLoader.java | 16 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/ClassInheritanceTreeNode.java | 56 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/Gui.java | 61 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/GuiController.java | 22 | ||||
| -rw-r--r-- | src/cuchaz/enigma/mapping/Ancestries.java | 22 |
6 files changed, 169 insertions, 13 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java index a3937b4..65e618a 100644 --- a/src/cuchaz/enigma/Deobfuscator.java +++ b/src/cuchaz/enigma/Deobfuscator.java | |||
| @@ -79,6 +79,11 @@ public class Deobfuscator | |||
| 79 | return m_file.getName(); | 79 | return m_file.getName(); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | public Ancestries getAncestries( ) | ||
| 83 | { | ||
| 84 | return m_ancestries; | ||
| 85 | } | ||
| 86 | |||
| 82 | public Mappings getMappings( ) | 87 | public Mappings getMappings( ) |
| 83 | { | 88 | { |
| 84 | return m_mappings; | 89 | return m_mappings; |
diff --git a/src/cuchaz/enigma/TranslatingTypeLoader.java b/src/cuchaz/enigma/TranslatingTypeLoader.java index e57a09d..44fe980 100644 --- a/src/cuchaz/enigma/TranslatingTypeLoader.java +++ b/src/cuchaz/enigma/TranslatingTypeLoader.java | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | package cuchaz.enigma; | 11 | package cuchaz.enigma; |
| 12 | 12 | ||
| 13 | import java.io.ByteArrayOutputStream; | ||
| 13 | import java.io.IOException; | 14 | import java.io.IOException; |
| 14 | import java.io.InputStream; | 15 | import java.io.InputStream; |
| 15 | import java.util.jar.JarEntry; | 16 | import java.util.jar.JarEntry; |
| @@ -59,10 +60,19 @@ public class TranslatingTypeLoader implements ITypeLoader | |||
| 59 | try | 60 | try |
| 60 | { | 61 | { |
| 61 | // read the class file into a buffer | 62 | // read the class file into a buffer |
| 62 | byte[] buf = new byte[(int)entry.getSize()]; | 63 | ByteArrayOutputStream data = new ByteArrayOutputStream(); |
| 64 | byte[] buf = new byte[1024*1024]; // 1 KiB | ||
| 63 | InputStream in = m_jar.getInputStream( entry ); | 65 | InputStream in = m_jar.getInputStream( entry ); |
| 64 | int bytesRead = in.read( buf ); | 66 | while( true ) |
| 65 | assert( bytesRead == buf.length ); | 67 | { |
| 68 | int bytesRead = in.read( buf ); | ||
| 69 | if( bytesRead <= 0 ) | ||
| 70 | { | ||
| 71 | break; | ||
| 72 | } | ||
| 73 | data.write( buf, 0, bytesRead ); | ||
| 74 | } | ||
| 75 | buf = data.toByteArray(); | ||
| 66 | 76 | ||
| 67 | // translate the class | 77 | // translate the class |
| 68 | ClassPool classPool = new ClassPool(); | 78 | ClassPool classPool = new ClassPool(); |
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 @@ | |||
| 1 | package cuchaz.enigma.gui; | ||
| 2 | |||
| 3 | import java.util.List; | ||
| 4 | |||
| 5 | import javax.swing.tree.DefaultMutableTreeNode; | ||
| 6 | |||
| 7 | import com.beust.jcommander.internal.Lists; | ||
| 8 | |||
| 9 | import cuchaz.enigma.mapping.Ancestries; | ||
| 10 | |||
| 11 | public class ClassInheritanceTreeNode extends DefaultMutableTreeNode | ||
| 12 | { | ||
| 13 | private static final long serialVersionUID = 4432367405826178490L; | ||
| 14 | |||
| 15 | String m_className; | ||
| 16 | |||
| 17 | public ClassInheritanceTreeNode( String className ) | ||
| 18 | { | ||
| 19 | m_className = className; | ||
| 20 | } | ||
| 21 | |||
| 22 | public String getClassName( ) | ||
| 23 | { | ||
| 24 | return m_className; | ||
| 25 | } | ||
| 26 | |||
| 27 | @Override | ||
| 28 | public String toString( ) | ||
| 29 | { | ||
| 30 | return m_className; | ||
| 31 | } | ||
| 32 | |||
| 33 | public void load( Ancestries ancestries, boolean recurse ) | ||
| 34 | { | ||
| 35 | // get all the child nodes | ||
| 36 | List<ClassInheritanceTreeNode> nodes = Lists.newArrayList(); | ||
| 37 | for( String subclassName : ancestries.getSubclasses( m_className ) ) | ||
| 38 | { | ||
| 39 | nodes.add( new ClassInheritanceTreeNode( subclassName ) ); | ||
| 40 | } | ||
| 41 | |||
| 42 | // add then to this node | ||
| 43 | for( ClassInheritanceTreeNode node : nodes ) | ||
| 44 | { | ||
| 45 | this.add( node ); | ||
| 46 | } | ||
| 47 | |||
| 48 | if( recurse ) | ||
| 49 | { | ||
| 50 | for( ClassInheritanceTreeNode node : nodes ) | ||
| 51 | { | ||
| 52 | node.load( ancestries, true ); | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 | } | ||
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; | |||
| 49 | import javax.swing.JSplitPane; | 49 | import javax.swing.JSplitPane; |
| 50 | import javax.swing.JTabbedPane; | 50 | import javax.swing.JTabbedPane; |
| 51 | import javax.swing.JTextField; | 51 | import javax.swing.JTextField; |
| 52 | import javax.swing.JTree; | ||
| 52 | import javax.swing.ListSelectionModel; | 53 | import javax.swing.ListSelectionModel; |
| 53 | import javax.swing.WindowConstants; | 54 | import javax.swing.WindowConstants; |
| 54 | import javax.swing.event.CaretEvent; | 55 | import javax.swing.event.CaretEvent; |
| 55 | import javax.swing.event.CaretListener; | 56 | import javax.swing.event.CaretListener; |
| 56 | import javax.swing.text.BadLocationException; | 57 | import javax.swing.text.BadLocationException; |
| 57 | import javax.swing.text.Highlighter; | 58 | import javax.swing.text.Highlighter; |
| 59 | import javax.swing.tree.DefaultTreeModel; | ||
| 60 | import javax.swing.tree.TreeNode; | ||
| 61 | import javax.swing.tree.TreePath; | ||
| 62 | |||
| 63 | import com.beust.jcommander.internal.Lists; | ||
| 58 | 64 | ||
| 59 | import jsyntaxpane.DefaultSyntaxKit; | 65 | import jsyntaxpane.DefaultSyntaxKit; |
| 60 | import jsyntaxpane.SyntaxDocument; | 66 | import jsyntaxpane.SyntaxDocument; |
| @@ -100,7 +106,7 @@ public class Gui | |||
| 100 | private JPanel m_infoPanel; | 106 | private JPanel m_infoPanel; |
| 101 | private BoxHighlightPainter m_obfuscatedHighlightPainter; | 107 | private BoxHighlightPainter m_obfuscatedHighlightPainter; |
| 102 | private BoxHighlightPainter m_deobfuscatedHighlightPainter; | 108 | private BoxHighlightPainter m_deobfuscatedHighlightPainter; |
| 103 | private JPanel m_inheritancePanel; | 109 | private JTree m_inheritanceTree; |
| 104 | 110 | ||
| 105 | // dynamic menu items | 111 | // dynamic menu items |
| 106 | private JMenuItem m_closeJarMenu; | 112 | private JMenuItem m_closeJarMenu; |
| @@ -136,6 +142,7 @@ public class Gui | |||
| 136 | m_obfClasses.setCellRenderer( new ObfuscatedClassListCellRenderer() ); | 142 | m_obfClasses.setCellRenderer( new ObfuscatedClassListCellRenderer() ); |
| 137 | m_obfClasses.addMouseListener( new MouseAdapter() | 143 | m_obfClasses.addMouseListener( new MouseAdapter() |
| 138 | { | 144 | { |
| 145 | @Override | ||
| 139 | public void mouseClicked( MouseEvent event ) | 146 | public void mouseClicked( MouseEvent event ) |
| 140 | { | 147 | { |
| 141 | if( event.getClickCount() == 2 ) | 148 | if( event.getClickCount() == 2 ) |
| @@ -161,6 +168,7 @@ public class Gui | |||
| 161 | m_deobfClasses.setCellRenderer( new DeobfuscatedClassListCellRenderer() ); | 168 | m_deobfClasses.setCellRenderer( new DeobfuscatedClassListCellRenderer() ); |
| 162 | m_deobfClasses.addMouseListener( new MouseAdapter() | 169 | m_deobfClasses.addMouseListener( new MouseAdapter() |
| 163 | { | 170 | { |
| 171 | @Override | ||
| 164 | public void mouseClicked( MouseEvent event ) | 172 | public void mouseClicked( MouseEvent event ) |
| 165 | { | 173 | { |
| 166 | if( event.getClickCount() == 2 ) | 174 | if( event.getClickCount() == 2 ) |
| @@ -252,7 +260,26 @@ public class Gui | |||
| 252 | } | 260 | } |
| 253 | 261 | ||
| 254 | // init inheritance panel | 262 | // init inheritance panel |
| 255 | m_inheritancePanel = new JPanel(); | 263 | m_inheritanceTree = new JTree(); |
| 264 | m_inheritanceTree.setModel( null ); | ||
| 265 | m_inheritanceTree.addMouseListener( new MouseAdapter( ) | ||
| 266 | { | ||
| 267 | @Override | ||
| 268 | public void mouseClicked( MouseEvent event ) | ||
| 269 | { | ||
| 270 | if( event.getClickCount() == 2 ) | ||
| 271 | { | ||
| 272 | ClassInheritanceTreeNode node = (ClassInheritanceTreeNode)m_inheritanceTree.getSelectionPath().getLastPathComponent(); | ||
| 273 | if( node != null ) | ||
| 274 | { | ||
| 275 | m_controller.deobfuscateClass( new ClassFile( node.getClassName() ) ); | ||
| 276 | } | ||
| 277 | } | ||
| 278 | } | ||
| 279 | } ); | ||
| 280 | JPanel inheritancePanel = new JPanel(); | ||
| 281 | inheritancePanel.setLayout( new BorderLayout() ); | ||
| 282 | inheritancePanel.add( new JScrollPane( m_inheritanceTree ) ); | ||
| 256 | 283 | ||
| 257 | // layout controls | 284 | // layout controls |
| 258 | JSplitPane splitLeft = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel ); | 285 | JSplitPane splitLeft = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel ); |
| @@ -263,7 +290,7 @@ public class Gui | |||
| 263 | centerPanel.add( sourceScroller, BorderLayout.CENTER ); | 290 | centerPanel.add( sourceScroller, BorderLayout.CENTER ); |
| 264 | JTabbedPane tabbedPane = new JTabbedPane(); | 291 | JTabbedPane tabbedPane = new JTabbedPane(); |
| 265 | tabbedPane.setPreferredSize( new Dimension( 200, 0 ) ); | 292 | tabbedPane.setPreferredSize( new Dimension( 200, 0 ) ); |
| 266 | tabbedPane.addTab( "Inheritance", m_inheritancePanel ); | 293 | tabbedPane.addTab( "Inheritance", inheritancePanel ); |
| 267 | JSplitPane splitRight = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, true, centerPanel, tabbedPane ); | 294 | JSplitPane splitRight = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, true, centerPanel, tabbedPane ); |
| 268 | splitRight.setResizeWeight( 1 ); // let the left side take all the slack | 295 | splitRight.setResizeWeight( 1 ); // let the left side take all the slack |
| 269 | splitRight.resetToPreferredSizes(); | 296 | splitRight.resetToPreferredSizes(); |
| @@ -748,12 +775,28 @@ public class Gui | |||
| 748 | 775 | ||
| 749 | private void showInheritance( ) | 776 | private void showInheritance( ) |
| 750 | { | 777 | { |
| 751 | m_inheritancePanel.removeAll(); | 778 | // get the current class |
| 752 | 779 | if( m_selectedEntryPair.obf instanceof ClassEntry ) | |
| 753 | // TEMP | 780 | { |
| 754 | m_inheritancePanel.add( new JLabel( m_selectedEntryPair.obf.getName() ) ); | 781 | ClassInheritanceTreeNode classNode = m_controller.getClassInheritance( (ClassEntry)m_selectedEntryPair.obf ); |
| 755 | m_inheritancePanel.add( new JLabel( m_selectedEntryPair.deobf.getName() ) ); | 782 | |
| 756 | 783 | // build the path from the root to the class node | |
| 784 | List<TreeNode> nodes = Lists.newArrayList(); | ||
| 785 | TreeNode node = classNode; | ||
| 786 | do | ||
| 787 | { | ||
| 788 | nodes.add( node ); | ||
| 789 | node = node.getParent(); | ||
| 790 | } | ||
| 791 | while( node != null ); | ||
| 792 | Collections.reverse( nodes ); | ||
| 793 | TreePath path = new TreePath( nodes.toArray() ); | ||
| 794 | |||
| 795 | // show the tree at the root | ||
| 796 | m_inheritanceTree.setModel( new DefaultTreeModel( (TreeNode)path.getPathComponent( 0 ) ) ); | ||
| 797 | m_inheritanceTree.expandPath( path ); | ||
| 798 | m_inheritanceTree.setSelectionRow( m_inheritanceTree.getRowForPath( path ) ); | ||
| 799 | } | ||
| 757 | redraw(); | 800 | redraw(); |
| 758 | } | 801 | } |
| 759 | 802 | ||
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; | |||
| 26 | import cuchaz.enigma.Deobfuscator; | 26 | import cuchaz.enigma.Deobfuscator; |
| 27 | import cuchaz.enigma.analysis.Analyzer; | 27 | import cuchaz.enigma.analysis.Analyzer; |
| 28 | import cuchaz.enigma.analysis.SourceIndex; | 28 | import cuchaz.enigma.analysis.SourceIndex; |
| 29 | import cuchaz.enigma.mapping.ClassEntry; | ||
| 29 | import cuchaz.enigma.mapping.Entry; | 30 | import cuchaz.enigma.mapping.Entry; |
| 30 | import cuchaz.enigma.mapping.EntryPair; | 31 | import cuchaz.enigma.mapping.EntryPair; |
| 31 | import cuchaz.enigma.mapping.MappingsReader; | 32 | import cuchaz.enigma.mapping.MappingsReader; |
| @@ -129,6 +130,27 @@ public class GuiController | |||
| 129 | return m_deobfuscator.hasMapping( pair.obf ); | 130 | return m_deobfuscator.hasMapping( pair.obf ); |
| 130 | } | 131 | } |
| 131 | 132 | ||
| 133 | public ClassInheritanceTreeNode getClassInheritance( ClassEntry classEntry ) | ||
| 134 | { | ||
| 135 | // create a node for this class | ||
| 136 | ClassInheritanceTreeNode thisNode = new ClassInheritanceTreeNode( classEntry.getName() ); | ||
| 137 | |||
| 138 | // expand all children recursively | ||
| 139 | thisNode.load( m_deobfuscator.getAncestries(), true ); | ||
| 140 | |||
| 141 | // get the ancestors too | ||
| 142 | ClassInheritanceTreeNode node = thisNode; | ||
| 143 | for( String superclassName : m_deobfuscator.getAncestries().getAncestry( classEntry.getName() ) ) | ||
| 144 | { | ||
| 145 | // add the parent node | ||
| 146 | ClassInheritanceTreeNode parentNode = new ClassInheritanceTreeNode( superclassName ); | ||
| 147 | parentNode.add( node ); | ||
| 148 | node = parentNode; | ||
| 149 | } | ||
| 150 | |||
| 151 | return thisNode; | ||
| 152 | } | ||
| 153 | |||
| 132 | public void rename( Entry obfsEntry, String newName, int lineNum ) | 154 | public void rename( Entry obfsEntry, String newName, int lineNum ) |
| 133 | { | 155 | { |
| 134 | m_deobfuscator.rename( obfsEntry, newName ); | 156 | m_deobfuscator.rename( obfsEntry, newName ); |
diff --git a/src/cuchaz/enigma/mapping/Ancestries.java b/src/cuchaz/enigma/mapping/Ancestries.java index b7a5e24..f77a00e 100644 --- a/src/cuchaz/enigma/mapping/Ancestries.java +++ b/src/cuchaz/enigma/mapping/Ancestries.java | |||
| @@ -26,6 +26,7 @@ import javassist.CtClass; | |||
| 26 | import javassist.NotFoundException; | 26 | import javassist.NotFoundException; |
| 27 | import javassist.bytecode.Descriptor; | 27 | import javassist.bytecode.Descriptor; |
| 28 | 28 | ||
| 29 | import com.beust.jcommander.internal.Lists; | ||
| 29 | import com.google.common.collect.Maps; | 30 | import com.google.common.collect.Maps; |
| 30 | 31 | ||
| 31 | import cuchaz.enigma.Constants; | 32 | import cuchaz.enigma.Constants; |
| @@ -121,11 +122,30 @@ public class Ancestries implements Serializable | |||
| 121 | while( className != null ) | 122 | while( className != null ) |
| 122 | { | 123 | { |
| 123 | className = getSuperclassName( className ); | 124 | className = getSuperclassName( className ); |
| 124 | ancestors.add( className ); | 125 | if( className != null ) |
| 126 | { | ||
| 127 | ancestors.add( className ); | ||
| 128 | } | ||
| 125 | } | 129 | } |
| 126 | return ancestors; | 130 | return ancestors; |
| 127 | } | 131 | } |
| 128 | 132 | ||
| 133 | public List<String> getSubclasses( String className ) | ||
| 134 | { | ||
| 135 | // linear search is fast enough for now | ||
| 136 | List<String> subclasses = Lists.newArrayList(); | ||
| 137 | for( Map.Entry<String,String> entry : m_superclasses.entrySet() ) | ||
| 138 | { | ||
| 139 | String subclass = entry.getKey(); | ||
| 140 | String superclass = entry.getValue(); | ||
| 141 | if( className.equals( superclass ) ) | ||
| 142 | { | ||
| 143 | subclasses.add( subclass ); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | return subclasses; | ||
| 147 | } | ||
| 148 | |||
| 129 | private boolean isJre( String className ) | 149 | private boolean isJre( String className ) |
| 130 | { | 150 | { |
| 131 | return className.startsWith( "java/" ) | 151 | return className.startsWith( "java/" ) |