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:
Kalen Kinloch 2014-11-02 15:01:29 -08:00
parent 9e2bfbc002
commit c31913265b
13 changed files with 146 additions and 23 deletions

BIN
BytecodeViewer Beta 1.5.jar Normal file

Binary file not shown.

View file

@ -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.

View file

@ -1 +1 @@
Beta 1.4
Beta 1.5

View file

@ -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;
}

View file

@ -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);

View file

@ -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) {

View file

@ -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") + "\"");
}
}
}

View file

@ -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());
}
}
}

View file

@ -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");
}
}
}
}

View file

@ -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());
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}