Beta 1.5 Released
11/1/2014 - Updated and improved the search function, it now prints out more useful information. 11/1/2014 - Fixed a UI issue with the Replace All Strings plugin. 11/2/2014 - Added search function to the Class Viewer. 11/2/2014 - Updated Procyon to procyon-decompiler-0.5.27.
This commit is contained in:
parent
9e2bfbc002
commit
c31913265b
13 changed files with 146 additions and 23 deletions
BIN
BytecodeViewer Beta 1.5.jar
Normal file
BIN
BytecodeViewer Beta 1.5.jar
Normal file
Binary file not shown.
|
@ -118,3 +118,8 @@ Changelog:
|
|||
11/1/2014 - Added Procyon save Java files (It uses the settings).
|
||||
11/1/2014 - Updated CFR to cfr_0_89.
|
||||
11/1/2014 - Added CFR save Java files (It uses the settings), however it relies on the file system, because of this if there is heavy name obfuscation, it could mess up for windows.
|
||||
--- Beta 1.5 ---:
|
||||
11/1/2014 - Updated and improved the search function, it now prints out more useful information.
|
||||
11/1/2014 - Fixed a UI issue with the Replace All Strings plugin.
|
||||
11/2/2014 - Added search function to the Class Viewer.
|
||||
11/2/2014 - Updated Procyon to procyon-decompiler-0.5.27.
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
Beta 1.4
|
||||
Beta 1.5
|
Binary file not shown.
|
@ -58,7 +58,7 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
|||
* Make the search results clickable
|
||||
* Add a tool to build a flowchart of all the classes, and what methods execute what classes, and those method, read chatlog
|
||||
* Middle mouse click should close tabs
|
||||
* http://i.imgur.com/yHaai9D.png
|
||||
* Add more details on the search results.
|
||||
*
|
||||
*
|
||||
* ----Beta 1.0-----:
|
||||
|
@ -147,6 +147,11 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
|||
* 11/1/2014 - Added Procyon save Java files (It uses the settings).
|
||||
* 11/1/2014 - Updated CFR to cfr_0_89.
|
||||
* 11/1/2014 - Added CFR save Java files (It uses the settings), however it relies on the file system, because of this if there is heavy name obfuscation, it could mess up for windows.
|
||||
* ----Beta 1.5-----:
|
||||
* 11/1/2014 - Updated and improved the search function, it now prints out more useful information.
|
||||
* 11/1/2014 - Fixed a UI issue with the Replace All Strings plugin.
|
||||
* 11/2/2014 - Added search function to the Class Viewer.
|
||||
* 11/2/2014 - Updated Procyon to procyon-decompiler-0.5.27.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
|
@ -165,7 +170,7 @@ public class BytecodeViewer {
|
|||
public static String fs = System.getProperty("file.separator");
|
||||
public static String nl = System.getProperty("line.separator");
|
||||
public static String tempDirectory = "bcv_temp";
|
||||
public static String version = "Beta 1.4";
|
||||
public static String version = "Beta 1.5";
|
||||
|
||||
public static void main(String[] args) {
|
||||
cleanup();
|
||||
|
@ -385,7 +390,7 @@ public class BytecodeViewer {
|
|||
private static String quickConvert(ArrayList<String> a) {
|
||||
String s = "";
|
||||
for(String r : a)
|
||||
s += r+"\r";
|
||||
s += r+nl;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.HierarchyEvent;
|
||||
|
@ -10,15 +14,21 @@ import java.util.ArrayList;
|
|||
|
||||
import static javax.swing.ScrollPaneConstants.*;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.text.AbstractDocument;
|
||||
import javax.swing.text.BoxView;
|
||||
import javax.swing.text.ComponentView;
|
||||
import javax.swing.text.DefaultHighlighter;
|
||||
import javax.swing.text.Element;
|
||||
import javax.swing.text.Highlighter;
|
||||
import javax.swing.text.IconView;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.text.LabelView;
|
||||
import javax.swing.text.StyleConstants;
|
||||
import javax.swing.text.StyledEditorKit;
|
||||
|
@ -96,13 +106,100 @@ public class ClassViewer extends JPanel {
|
|||
ClassNode cn;
|
||||
JSplitPane sp;
|
||||
JSplitPane sp2;
|
||||
public JCheckBox byteCheck = new JCheckBox("Exact");
|
||||
public JPanel bytePanelSearch = new JPanel(new BorderLayout());
|
||||
public JPanel decompPanelSearch = new JPanel(new BorderLayout());
|
||||
public JCheckBox decompCheck = new JCheckBox("Exact");
|
||||
public JPanel bytePanel = new JPanel(new BorderLayout());
|
||||
public JPanel decompPanel = new JPanel(new BorderLayout());
|
||||
|
||||
public void search(int pane, String search) {
|
||||
try {
|
||||
if(pane == 0) { //bytecode
|
||||
for(Component c : bytePanel.getComponents()) {
|
||||
if(c instanceof RTextScrollPane) {
|
||||
RSyntaxTextArea area = (RSyntaxTextArea) ((RTextScrollPane)c).getViewport().getComponent(0);
|
||||
highlight(pane, area, search);
|
||||
}
|
||||
}
|
||||
} else if(pane == 1) { //decomp
|
||||
for(Component c : decompPanel.getComponents()) {
|
||||
if(c instanceof RTextScrollPane) {
|
||||
RSyntaxTextArea area = (RSyntaxTextArea) ((RTextScrollPane)c).getViewport().getComponent(0);
|
||||
highlight(pane, area, search);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private DefaultHighlighter.DefaultHighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter(new Color(255,62,150));
|
||||
|
||||
public void highlight(int pane, JTextComponent textComp, String pattern) {
|
||||
if(pattern.isEmpty()) {
|
||||
textComp.getHighlighter().removeAllHighlights();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Highlighter hilite = textComp.getHighlighter();
|
||||
hilite.removeAllHighlights();
|
||||
javax.swing.text.Document doc = textComp.getDocument();
|
||||
String text = doc.getText(0, doc.getLength());
|
||||
int pos = 0;
|
||||
|
||||
if((pane == 0 && !byteCheck.isSelected()) || pane == 1 && !decompCheck.isSelected()) {
|
||||
pattern = pattern.toLowerCase();
|
||||
text = text.toLowerCase();
|
||||
}
|
||||
|
||||
// Search for pattern
|
||||
while ((pos = text.indexOf(pattern, pos)) >= 0) {
|
||||
// Create highlighter using private painter and apply around pattern
|
||||
hilite.addHighlight(pos, pos + pattern.length(), painter);
|
||||
pos += pattern.length();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ClassViewer(final String name, final ClassNode cn) {
|
||||
JButton byteSearch = new JButton("Search");
|
||||
bytePanelSearch.add(byteSearch, BorderLayout.WEST);
|
||||
final JTextField byteField = new JTextField();
|
||||
bytePanelSearch.add(byteField, BorderLayout.CENTER);
|
||||
bytePanelSearch.add(byteCheck, BorderLayout.EAST);
|
||||
byteSearch.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent arg0) {
|
||||
search(0,byteField.getText());
|
||||
}
|
||||
});
|
||||
|
||||
JButton decompSearch = new JButton("Search");
|
||||
decompPanelSearch.add(decompSearch, BorderLayout.WEST);
|
||||
final JTextField decompField = new JTextField();
|
||||
decompPanelSearch.add(decompField, BorderLayout.CENTER);
|
||||
decompPanelSearch.add(decompCheck, BorderLayout.EAST);
|
||||
decompSearch.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent arg0) {
|
||||
search(1,decompField.getText());
|
||||
}
|
||||
});
|
||||
|
||||
sourcePane = BytecodeViewer.viewer.sourcePane.isSelected();
|
||||
bytecodePane = BytecodeViewer.viewer.bytecodePane.isSelected();
|
||||
hexPane = BytecodeViewer.viewer.hexPane.isSelected();
|
||||
|
||||
if(bytecodePane)
|
||||
bytePanel.add(bytePanelSearch, BorderLayout.NORTH);
|
||||
if(sourcePane)
|
||||
decompPanel.add(decompPanelSearch, BorderLayout.NORTH);
|
||||
|
||||
this.name = name;
|
||||
this.cn = cn;
|
||||
this.setName(name);
|
||||
|
|
|
@ -128,9 +128,8 @@ public class SearchingPane extends VisibleComponent {
|
|||
final SearchRadius radius = (SearchRadius) searchRadiusBox.getSelectedItem();
|
||||
final SearchResultNotifier srn = new SearchResultNotifier() {
|
||||
@Override
|
||||
public void notifyOfResult(final ClassNode clazz,
|
||||
final MethodNode method, final AbstractInsnNode insn) {
|
||||
treeRoot.add(new DefaultMutableTreeNode(clazz.name + "." + method.name));
|
||||
public void notifyOfResult(String debug) {
|
||||
treeRoot.add(new DefaultMutableTreeNode(debug));
|
||||
}
|
||||
};
|
||||
if (radius == SearchRadius.All_Classes) {
|
||||
|
|
|
@ -93,13 +93,13 @@ public class ReplaceStrings extends Plugin {
|
|||
if(s.contains(originalLDC)) {
|
||||
((LdcInsnNode)a).cst = ((String)((LdcInsnNode)a).cst).replaceAll(originalLDC, newLDC);
|
||||
String ugh = s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r");
|
||||
frame.appendText(classNode.name + "." +m.name+""+m.desc+" -> \"" + ugh + "\" replaced with \"" + s.replaceAll(originalLDC, newLDC) + "\"");
|
||||
frame.appendText(classNode.name + "." +m.name+""+m.desc+" -> \"" + ugh + "\" replaced with \"" + s.replaceAll(originalLDC, newLDC).replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\"");
|
||||
}
|
||||
} else {
|
||||
if(s.equals(originalLDC)) {
|
||||
((LdcInsnNode)a).cst = newLDC;
|
||||
String ugh = s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r");
|
||||
frame.appendText(classNode.name + "." +m.name+""+m.desc+" -> \"" + ugh + "\" replaced with \"" + newLDC + "\"");
|
||||
frame.appendText(classNode.name + "." +m.name+""+m.desc+" -> \"" + ugh + "\" replaced with \"" + newLDC.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,15 +8,19 @@ import javax.swing.JLabel;
|
|||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldInsnNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import eu.bibl.banalysis.asm.desc.OpcodeInfo;
|
||||
|
||||
/**
|
||||
* Field call searching
|
||||
*
|
||||
* @author Konloch
|
||||
* @author Water Wolf
|
||||
*
|
||||
*/
|
||||
|
@ -78,7 +82,7 @@ public class FieldCallSearch implements SearchTypeDetails {
|
|||
if (desc != null && !desc.equals(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
srn.notifyOfResult(node, method, insnNode);
|
||||
srn.notifyOfResult(node.name + "." + method.name + Type.getType(method.desc) + " > " + OpcodeInfo.OPCODES.get(insnNode.getOpcode()).toLowerCase());
|
||||
} else {
|
||||
|
||||
if (name != null && !name.contains(min.name)) {
|
||||
|
@ -90,7 +94,7 @@ public class FieldCallSearch implements SearchTypeDetails {
|
|||
if (desc != null && !desc.contains(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
srn.notifyOfResult(node, method, insnNode);
|
||||
srn.notifyOfResult(node.name + "." + method.name + Type.getType(method.desc) + " > " + OpcodeInfo.OPCODES.get(insnNode.getOpcode()).toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package the.bytecode.club.bytecodeviewer.searching;
|
||||
|
||||
import groovyjarjarasm.asm.tree.FieldNode;
|
||||
|
||||
import java.awt.GridLayout;
|
||||
import java.util.Iterator;
|
||||
import java.util.ListIterator;
|
||||
|
@ -8,6 +10,7 @@ import javax.swing.JLabel;
|
|||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
|
@ -17,6 +20,7 @@ import org.objectweb.asm.tree.MethodNode;
|
|||
/**
|
||||
* LDC Searching
|
||||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*/
|
||||
|
@ -51,16 +55,24 @@ public class LDCSearch implements SearchTypeDetails {
|
|||
while (instructions.hasNext()) {
|
||||
final AbstractInsnNode insnNode = instructions.next();
|
||||
if (insnNode instanceof LdcInsnNode) {
|
||||
final Object ldcObject = ((LdcInsnNode) insnNode).cst;
|
||||
final String ldcString = ldcObject.toString();
|
||||
final LdcInsnNode ldcObject = ((LdcInsnNode) insnNode);
|
||||
final String ldcString = ldcObject.cst.toString();
|
||||
if ((exact && ldcString.equals(srchText)) ||
|
||||
(!exact && ldcString.contains(srchText)))
|
||||
{
|
||||
srn.notifyOfResult(node, method, insnNode);
|
||||
srn.notifyOfResult(node.name + "." + method.name + Type.getType(method.desc).getInternalName() + " -> \""+ldcString + "\" > " + ldcObject.cst.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
final Iterator<FieldNode> fields = node.fields.iterator();
|
||||
while (methods.hasNext()) {
|
||||
final FieldNode field = fields.next();
|
||||
if(field.value instanceof String) {
|
||||
srn.notifyOfResult(node.name + "." + field.name + field.desc + " -> \"" + field.value + "\" > field");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -8,15 +8,19 @@ import javax.swing.JLabel;
|
|||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import eu.bibl.banalysis.asm.desc.OpcodeInfo;
|
||||
|
||||
/**
|
||||
* Method call searching
|
||||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*/
|
||||
|
@ -78,7 +82,7 @@ public class MethodCallSearch implements SearchTypeDetails {
|
|||
if (desc != null && !desc.equals(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
srn.notifyOfResult(node, method, insnNode);
|
||||
srn.notifyOfResult(node.name + "." + method.name + Type.getType(method.desc) + " > " + OpcodeInfo.OPCODES.get(insnNode.getOpcode()).toLowerCase());
|
||||
} else {
|
||||
if (name != null && !name.contains(min.name)) {
|
||||
continue;
|
||||
|
@ -89,7 +93,7 @@ public class MethodCallSearch implements SearchTypeDetails {
|
|||
if (desc != null && !desc.contains(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
srn.notifyOfResult(node, method, insnNode);
|
||||
srn.notifyOfResult(node.name + "." + method.name + Type.getType(method.desc) + " > " + OpcodeInfo.OPCODES.get(insnNode.getOpcode()).toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.objectweb.asm.tree.MethodNode;
|
|||
/**
|
||||
* Regex Searching
|
||||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*/
|
||||
|
@ -53,7 +54,7 @@ public class RegexSearch implements SearchTypeDetails {
|
|||
}
|
||||
|
||||
if (regexFinder.find(srchText).length > 0) {
|
||||
srn.notifyOfResult(node, method, null);
|
||||
srn.notifyOfResult(node.name + "." + method.name + method.desc);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
package the.bytecode.club.bytecodeviewer.searching;
|
||||
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
/**
|
||||
* Used to update the search pane that there's been a result found.
|
||||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*/
|
||||
|
||||
public interface SearchResultNotifier {
|
||||
public void notifyOfResult(ClassNode clazz, MethodNode method,
|
||||
AbstractInsnNode insn);
|
||||
public void notifyOfResult(String debug);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue