11/4/2014 - Officially been 1 month of development.
11/4/2014 - Replaced ""+ with String.valueOf (cheers bibl).
11/4/2014 - Changed how the temp directory was created.
11/4/2014 - Put a file.seperator  to the end of tempDirectory.
11/4/2014 - Made the exit button work.
11/4/2014 - Added a GUI for all Exception Stack Trace's.
11/4/2014 - The plugin system now shows a message instead of just
printing to the console when it's not going to run a plugin.
11/4/2014 - Updated the search function, it's now perfect.
11/5/2014 - Made the Show All Strings plugin instant.
11/5/2014 - Kinda added middle mouse button closes tab (only if you
click the exit button).
11/5/2014 - Improved the Malicious Code Scanner, also made it instant.
11/5/2014 - Added icons to the program (cheers Fluke).
This commit is contained in:
Kalen Kinloch 2014-11-05 21:06:58 -08:00
parent 05ecf04a78
commit 132d8e678f
35 changed files with 454 additions and 230 deletions

BIN
BytecodeViewer 2.0.jar Normal file

Binary file not shown.

View File

@ -1,4 +1,4 @@
Bytecode Viewer is a Java Bytecode Viewer, GUI Procyon Java Decompiler, GUI CFR Java Decompiler, GUI FernFlower Java Decompiler, GUI Jar-Jar, Hex Viewer, Code Searcher, Debugger and more.
Bytecode Viewer is an Advanced Lightweight Java Bytecode Viewer, GUI Procyon Java Decompiler, GUI CFR Java Decompiler, GUI FernFlower Java Decompiler, GUI Jar-Jar, Hex Viewer, Code Searcher, Debugger and more.
It's written completely in Java, and it's open sourced. It's currently being maintained and developed by Konloch.
There is also a plugin system that will allow you to interact with the loaded classfiles, for example you can write a String deobfuscator, a malicious code searcher, or something else you can think of.
@ -16,6 +16,8 @@ CFR by Lee Benfield
Video of Beta 1.5.2: http://the.bytecode.club/pages.php?page=bytecode-viewer
Download the latest version here: https://github.com/Konloch/bytecode-viewer/releases
Features:
Java Decompiler - It uses a modified version of FernFlower, Procyon and CFR.
Bytecode Decompiler - A modified version of J-RET's.
@ -132,4 +134,17 @@ Changelog:
11/3/2014 - The GUI setttings now save.
11/3/2014 - Removed the option to disable syntax highlighting (since it's lightweight now).
11/3/2014 - About window now contains the version number and the BCV directory.
11/3/2014 - Added an option to toggle to outdated status.
11/3/2014 - Added an option to toggle to outdated status.
--- 2.0 ---: //Out of beta, WOO
11/4/2014 - Officially been 1 month of development.
11/4/2014 - Replaced ""+ with String.valueOf (cheers bibl).
11/4/2014 - Changed how the temp directory was created.
11/4/2014 - Put a file.seperator to the end of tempDirectory.
11/4/2014 - Made the exit button work.
11/4/2014 - Added a GUI for all Exception Stack Trace's.
11/4/2014 - The plugin system now shows a message instead of just printing to the console when it's not going to run a plugin.
11/4/2014 - Updated the search function, it's now perfect.
11/5/2014 - Made the Show All Strings plugin instant.
11/5/2014 - Kinda added middle mouse button closes tab (only if you click the exit button).
11/5/2014 - Improved the Malicious Code Scanner, also made it instant.
11/5/2014 - Added icons to the program (cheers Fluke).

View File

@ -1 +1 @@
Beta 1.5.3
2.0

BIN
libs/imgscalr-lib-4.2.jar Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -357,13 +357,13 @@ public class FileDrop {
} // end try
catch (final java.io.IOException io) {
log(out, "FileDrop: IOException - abort:");
io.printStackTrace(out);
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(io);
evt.rejectDrop();
} // end catch IOException
catch (final java.awt.datatransfer.UnsupportedFlavorException ufe) {
log(out,
"FileDrop: UnsupportedFlavorException - abort:");
ufe.printStackTrace(out);
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ufe);
evt.rejectDrop();
} // end catch: UnsupportedFlavorException
finally {
@ -467,7 +467,7 @@ public class FileDrop {
dt.addDropTargetListener(dropListener);
} // end try
catch (final java.util.TooManyListenersException e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
log(out,
"FileDrop: Drop will not work due to previous error. Do you have another listener attached?");
} // end catch

View File

@ -101,7 +101,7 @@ public class JarUtils {
out.close();
} catch (IOException e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
}
@ -128,7 +128,7 @@ public class JarUtils {
out.close();
} catch (IOException e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
}

View File

@ -218,7 +218,7 @@ public class InstructionPrinter {
try {
return nameOpcode(tin.getOpcode()) + " " + Type.getType(tin.desc).getClassName();
} catch(Exception e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
return "//error";
}
@ -295,7 +295,7 @@ public class InstructionPrinter {
}
bw.close();
} catch (IOException e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
}
}

View File

@ -46,7 +46,7 @@ public class CFRDecompiler extends JavaDecompiler {
fos.close();
} catch (final IOException e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
String fuckery = fuckery(fileStart);
@ -81,7 +81,7 @@ public class CFRDecompiler extends JavaDecompiler {
try {
s = DiskReader.loadAsString(f.getAbsolutePath());
} catch(Exception e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com";
}
return s;
@ -205,7 +205,7 @@ public class CFRDecompiler extends JavaDecompiler {
try {
zip(fuck, new File(zipName));
} catch (IOException e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
fuck.delete();

View File

@ -59,7 +59,7 @@ public class FernFlowerDecompiler extends JavaDecompiler {
fos.close();
} catch (final IOException e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempClass.getAbsolutePath(), "."));
@ -76,7 +76,7 @@ public class FernFlowerDecompiler extends JavaDecompiler {
return s;
} catch (Exception e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
}
return "FernFlower error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com";

View File

@ -84,7 +84,7 @@ public class ProcyonDecompiler extends JavaDecompiler {
fos.close();
} catch (final IOException e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
@ -109,7 +109,7 @@ public class ProcyonDecompiler extends JavaDecompiler {
return decompiledSource;
} catch(Exception e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
return "Procyon error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com";
}
@ -125,7 +125,7 @@ public class ProcyonDecompiler extends JavaDecompiler {
try {
doSaveJarDecompiled(tempZip, new File(zipName));
} catch (Exception e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
}

View File

@ -13,6 +13,7 @@ import java.awt.Color;
public class AboutWindow extends JFrame {
public AboutWindow() {
this.setIconImages(BytecodeViewer.iconList);
setSize(new Dimension(446, 374));
setType(Type.UTILITY);
setTitle("Bytecode Viewer - About");

View File

@ -14,6 +14,7 @@ import java.util.ArrayList;
import static javax.swing.ScrollPaneConstants.*;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
@ -113,25 +114,97 @@ public class ClassViewer extends JPanel {
public JPanel bytePanel = new JPanel(new BorderLayout());
public JPanel decompPanel = new JPanel(new BorderLayout());
public void search(int pane, String search) {
/**
* This was really interesting to write.
*
* @author Konloch
*
*/
public void search(int pane, String search, boolean next) {
try {
if(pane == 0) { //bytecode
for(Component c : bytePanel.getComponents()) {
Component[] com = null;
if(pane == 0) //bytecode
com = bytePanel.getComponents();
else if(pane == 1)
com = decompPanel.getComponents();
if(com == null) //someone fucked up, lets prevent a nullpointer.
return;
for(Component c : com) {
if(c instanceof RTextScrollPane) {
RSyntaxTextArea area = (RSyntaxTextArea) ((RTextScrollPane)c).getViewport().getComponent(0);
if(search.isEmpty()) {
highlight(pane, area, "");
return;
}
int startLine = area.getDocument().getDefaultRootElement().getElementIndex(area.getCaretPosition())+1;
int currentLine = 1;
boolean canSearch = false;
String[] test = null;
if(area.getText().split("\n").length >= 2)
test = area.getText().split("\n");
else
test = area.getText().split("\r");
int lastGoodLine = -1;
int firstPos = -1;
boolean found = false;
if(next) {
for(String s : test) {
if(currentLine == startLine) {
canSearch = true;
} else if(s.contains(search)) {
if(canSearch) {
area.setCaretPosition(area.getDocument()
.getDefaultRootElement().getElement(currentLine-1)
.getStartOffset());
canSearch = false;
found = true;
}
if(firstPos == -1)
firstPos = currentLine;
}
currentLine++;
}
if(!found && firstPos != -1) {
area.setCaretPosition(area.getDocument()
.getDefaultRootElement().getElement(firstPos-1)
.getStartOffset());
}
} else {
canSearch = true;
for(String s : test) {
if(s.contains(search)) {
if(lastGoodLine != -1 && canSearch)
area.setCaretPosition(area.getDocument()
.getDefaultRootElement().getElement(lastGoodLine-1)
.getStartOffset());
lastGoodLine = currentLine;
if(currentLine >= startLine)
canSearch = false;
}
currentLine++;
}
if(lastGoodLine != -1 && area.getDocument().getDefaultRootElement().getElementIndex(area.getCaretPosition())+1 == startLine) {
area.setCaretPosition(area.getDocument()
.getDefaultRootElement().getElement(lastGoodLine-1)
.getStartOffset());
}
}
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();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
}
@ -162,32 +235,56 @@ public class ClassViewer extends JPanel {
pos += pattern.length();
}
} catch (Exception e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
}
public ClassViewer(final String name, final ClassNode cn) {
JButton byteSearch = new JButton("Search");
bytePanelSearch.add(byteSearch, BorderLayout.WEST);
JButton byteSearchNext = new JButton();
JButton byteSearchPrev = new JButton();
JPanel byteButtonPane = new JPanel(new BorderLayout());
byteButtonPane.add(byteSearchNext, BorderLayout.WEST);
byteButtonPane.add(byteSearchPrev, BorderLayout.EAST);
byteSearchNext.setIcon(new ImageIcon(BytecodeViewer.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYqPBJSG/ZAAAASUlEQVR42mNgwAbS0oAEE4yHyWBmYAzjYDC694OJ4f9+BoY3H0BSbz6A2MxA6VciFyDqGAWQTWVkYEkCUrcOsDD8OwtkvMViMwAb8xEUHlHcFAAAAABJRU5ErkJggg==")));
byteSearchPrev.setIcon(new ImageIcon(BytecodeViewer.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYgKhxpRi1AAAATElEQVR42mNgwAZYHIAEExA7qUAYLApMDmCGEwODCojByM/A8FEAyPi/moFh9QewYjCAM1iA+D2KqYwMrIlA6tUGFoa/Z4GMt1hsBgCe1wuKber+SwAAAABJRU5ErkJggg==")));
bytePanelSearch.add(byteButtonPane, BorderLayout.WEST);
final JTextField byteField = new JTextField();
bytePanelSearch.add(byteField, BorderLayout.CENTER);
bytePanelSearch.add(byteCheck, BorderLayout.EAST);
byteSearch.addActionListener(new ActionListener() {
byteSearchNext.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
search(0,byteField.getText());
search(0,byteField.getText(), true);
}
});
byteSearchPrev.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
search(0,byteField.getText(), false);
}
});
JButton decompSearch = new JButton("Search");
decompPanelSearch.add(decompSearch, BorderLayout.WEST);
JButton decompSearchNext = new JButton();
JButton decompSearchPrev = new JButton();
JPanel decompButtonPane = new JPanel(new BorderLayout());
decompButtonPane.add(decompSearchNext, BorderLayout.WEST);
decompButtonPane.add(decompSearchPrev, BorderLayout.EAST);
decompSearchNext.setIcon(new ImageIcon(BytecodeViewer.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYqPBJSG/ZAAAASUlEQVR42mNgwAbS0oAEE4yHyWBmYAzjYDC694OJ4f9+BoY3H0BSbz6A2MxA6VciFyDqGAWQTWVkYEkCUrcOsDD8OwtkvMViMwAb8xEUHlHcFAAAAABJRU5ErkJggg==")));
decompSearchPrev.setIcon(new ImageIcon(BytecodeViewer.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYgKhxpRi1AAAATElEQVR42mNgwAZYHIAEExA7qUAYLApMDmCGEwODCojByM/A8FEAyPi/moFh9QewYjCAM1iA+D2KqYwMrIlA6tUGFoa/Z4GMt1hsBgCe1wuKber+SwAAAABJRU5ErkJggg==")));
decompPanelSearch.add(decompButtonPane, BorderLayout.WEST);
final JTextField decompField = new JTextField();
decompPanelSearch.add(decompField, BorderLayout.CENTER);
decompPanelSearch.add(decompCheck, BorderLayout.EAST);
decompSearch.addActionListener(new ActionListener() {
decompSearchNext.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
search(1,decompField.getText());
search(1,decompField.getText(), true);
}
});
decompSearchPrev.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
search(1,decompField.getText(), false);
}
});
@ -363,7 +460,6 @@ public class ClassViewer extends JPanel {
return new IconView(elem);
}
// default to text display
return new LabelView(elem);
}
}

View File

@ -1,12 +1,13 @@
package the.bytecode.club.bytecodeviewer.gui;
import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.BoxLayout;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
@ -20,7 +21,6 @@ import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import javax.swing.JCheckBoxMenuItem;
import org.apache.commons.codec.binary.Base64;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
@ -37,8 +37,6 @@ import the.bytecode.club.bytecodeviewer.plugins.ZKMStringDecrypter;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.ArrayList;
@ -209,7 +207,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
try {
mntmNewMenuItem_4.setIcon(new ImageIcon(getClass().getResource("/resources/1.gif")));
} catch(NullPointerException e) {
mntmNewMenuItem_4.setIcon(new ImageIcon(b642IMG("R0lGODlhEAALAPQAAP///wAAANra2tDQ0Orq6gcHBwAAAC8vL4KCgmFhYbq6uiMjI0tLS4qKimVlZb6+vicnJwUFBU9PT+bm5tjY2PT09Dk5Odzc3PLy8ra2tqCgoMrKyu7u7gAAAAAAAAAAACH5BAkLAAAAIf4aQ3JlYXRlZCB3aXRoIGFqYXhsb2FkLmluZm8AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7"), ""));
mntmNewMenuItem_4.setIcon(new ImageIcon(BytecodeViewer.b642IMG("R0lGODlhEAALAPQAAP///wAAANra2tDQ0Orq6gcHBwAAAC8vL4KCgmFhYbq6uiMjI0tLS4qKimVlZb6+vicnJwUFBU9PT+bm5tjY2PT09Dk5Odzc3PLy8ra2tqCgoMrKyu7u7gAAAAAAAAAAACH5BAkLAAAAIf4aQ3JlYXRlZCB3aXRoIGFqYXhsb2FkLmluZm8AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7"), ""));
}
} else
mntmNewMenuItem_4.setIcon(null);
@ -217,27 +215,9 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
}
});
}
/**
* Decodes a Base64 String as a BufferedImage
*/
public BufferedImage b642IMG(String imageString) {
BufferedImage image = null;
byte[] imageByte;
try {
imageByte = Base64.decodeBase64(imageString);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
return image;
}
public MainViewerGUI() {
this.setIconImages(BytecodeViewer.iconList);
decompilerGroup.add(fernflowerDec);
decompilerGroup.add(procyonDec);
decompilerGroup.add(cfrDec);
@ -335,7 +315,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
BytecodeViewer.openFiles(new File[]{fc.getSelectedFile()});
BytecodeViewer.viewer.setC(false);
} catch (Exception e1) {
e1.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e1);
}
}
});
@ -424,6 +404,26 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
mnNewMenu.add(chckbxmntmNewCheckItem_12);
JMenuItem mntmExit = new JMenuItem("Exit");
mntmExit.addActionListener(new ActionListener() {
@SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent arg0) {
JOptionPane pane = new JOptionPane("Are you sure you want to exit?");
Object[] options = new String[] { "Yes", "No" };
pane.setOptions(options);
JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Exit");
dialog.show();
Object obj = pane.getValue();
int result = -1;
for (int k = 0; k < options.length; k++)
if (options[k].equals(obj))
result = k;
if(result == 0) {
System.exit(0);
}
}
});
mnNewMenu.add(mntmExit);
JMenu mnView = new JMenu("View");
@ -611,8 +611,10 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
public void actionPerformed(ActionEvent arg0) {
if(!BytecodeViewer.loadedClasses.isEmpty())
new ReplaceStringsOptions().setVisible(true);
else
else {
System.out.println("Plugin not ran, put some classes in first.");
BytecodeViewer.showMessage("Plugin not ran, put some classes in first.");
}
}
});
@ -637,7 +639,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
BytecodeViewer.startPlugin(fc.getSelectedFile());
BytecodeViewer.viewer.setC(false);
} catch (Exception e1) {
e1.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e1);
}
}
});
@ -655,8 +657,10 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
public void actionPerformed(ActionEvent e) {
if(!BytecodeViewer.loadedClasses.isEmpty())
new MaliciousCodeScannerOptions().setVisible(true);
else
else {
System.out.println("Plugin not ran, put some classes in first.");
BytecodeViewer.showMessage("Plugin not ran, put some classes in first.");
}
}
});
mntmShowAllStrings.addActionListener(new ActionListener() {

View File

@ -7,6 +7,7 @@ import java.awt.Dimension;
import javax.swing.JCheckBox;
import javax.swing.JButton;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.plugins.MaliciousCodeScanner;
import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
@ -15,6 +16,7 @@ import java.awt.event.ActionEvent;
public class MaliciousCodeScannerOptions extends JFrame {
public MaliciousCodeScannerOptions() {
this.setIconImages(BytecodeViewer.iconList);
setSize(new Dimension(250, 277));
setResizable(false);
setTitle("Malicious Code Scanner Options");

View File

@ -1,20 +1,24 @@
package the.bytecode.club.bytecodeviewer.gui;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
import the.bytecode.club.bytecodeviewer.plugins.ReplaceStrings;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JCheckBox;
public class ReplaceStringsOptions extends JFrame {
public ReplaceStringsOptions() {
this.setIconImages(BytecodeViewer.iconList);
setSize(new Dimension(250, 176));
setResizable(false);
setTitle("Replace Strings");

View File

@ -0,0 +1,40 @@
package the.bytecode.club.bytecodeviewer.gui;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import java.awt.Dimension;
import java.awt.CardLayout;
import javax.swing.JTextArea;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import java.awt.Color;
import java.io.PrintWriter;
import java.io.StringWriter;
public class StackTraceUI extends JFrame {
public StackTraceUI(Exception e) {
this.setIconImages(BytecodeViewer.iconList);
setSize(new Dimension(600, 400));
setTitle("Bytecode Viewer "+BytecodeViewer.version+" - Stack Trace - Send this to @Konloch.");
getContentPane().setLayout(new CardLayout(0, 0));
JTextArea txtrBytecodeViewerIs = new JTextArea();
txtrBytecodeViewerIs.setDisabledTextColor(Color.BLACK);
txtrBytecodeViewerIs.setWrapStyleWord(true);
getContentPane().add(new JScrollPane(txtrBytecodeViewerIs), "name_140466576080695");
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
txtrBytecodeViewerIs.setText(sw.toString());
this.setLocationRelativeTo(null);
this.setVisible(true);
}
private static final long serialVersionUID = -5230501978224926296L;
}

View File

@ -34,7 +34,8 @@ public class TabbedPane extends JPanel {
private static final long serialVersionUID = -4774885688297538774L;
private final JTabbedPane pane;
final JButton button = new TabButton();
private static long zero = System.currentTimeMillis();
public TabbedPane(final JTabbedPane pane) {
//unset default FlowLayout' gaps
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
@ -63,46 +64,22 @@ public class TabbedPane extends JPanel {
add(button);
//add more space to the top of the component
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
pane.addMouseListener(new MouseListener() {
button.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent arg0) {
public void mouseClicked(MouseEvent e) {
if(e.getModifiers() == 8) {
if(System.currentTimeMillis()-zero >= 500) {
zero = System.currentTimeMillis();
final int i = pane.indexOfTabComponent(TabbedPane.this);
if (i != -1)
pane.remove(i);
}
}
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent e) {
//final Component component = e.getComponent();
// if(component instanceof JTabbedPane) {
if(e.getModifiers() == 8) {
for(Component c : pane.getComponents()) {
if(c.getMousePosition() != null && c instanceof JPanel) {
System.out.println("gotten here...");
/*BytecodeViewer.viewer.getComponent(WorkPane.class).tabs.remove(component);
final int i = BytecodeViewer.viewer.getComponent(WorkPane.class).tabs.indexOfTabComponent(c);
if (i != -1)
BytecodeViewer.viewer.getComponent(WorkPane.class).tabs.remove(i);
BytecodeViewer.viewer.getComponent(WorkPane.class).tabs.updateUI();
BytecodeViewer.viewer.getComponent(WorkPane.class).tabs.repaint();
*////if(c.getComponentAt((int)c.getMousePosition().getX(), (int)c.getMousePosition().getY())button.)
// button.doClick();
}
//System.out.println(c.getMousePosition() + ":" + e.getX());
//System.out.println(c.getWidth() + ":" + e.getX());
//if( e.getX() >= &&
// e.getY())
// button.doClick();
}
}
}
//}
@Override public void mouseEntered(MouseEvent arg0) {}
@Override public void mouseExited(MouseEvent arg0) {}
@Override public void mousePressed(MouseEvent arg0) {}
@Override public void mouseReleased(MouseEvent e) {}
});
}

View File

@ -17,9 +17,6 @@ public class AllatoriStringDecrypter extends Plugin {
@Override
public void execute(ArrayList<ClassNode> classNodeList) {
for(ClassNode classNode : classNodeList) {
}
BytecodeViewer.showMessage("This is a planned feature.");
}

View File

@ -4,11 +4,14 @@ import java.util.ArrayList;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
/**
* The idea/core was based off of J-RET's Malicious Code Searcher
* I improved it, and added more stuff to search for.
@ -45,7 +48,35 @@ public class MaliciousCodeScanner extends Plugin {
@Override
public void execute(ArrayList<ClassNode> classNodeList) {
PluginConsole frame = new PluginConsole("Malicious Code Scanner");
StringBuilder sb = new StringBuilder();
for(ClassNode classNode : classNodeList) {
for(Object o : classNode.fields.toArray()) {
FieldNode f = (FieldNode) o;
Object v = f.value;
if(v instanceof String) {
String s = (String)v;
if ((LWW && s.contains("www.")) ||
(LHT && s.contains("http://")) ||
(LHS && s.contains("https://")) ||
(ORE && s.contains("java/lang/Runtime")) ||
(ORE && s.contains("java.lang.Runtime")) ||
(LIP && s.matches("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b")))
sb.append("Found LDC \"" + s + "\" at field " + classNode.name + "." +f.name+"("+f.desc+")"+BytecodeViewer.nl);
}
if(v instanceof String[]) {
for(int i = 0; i < ((String[])v).length; i++) {
String s = ((String[])v)[i];
if ((LWW && s.contains("www.")) ||
(LHT && s.contains("http://")) ||
(LHS && s.contains("https://")) ||
(ORE && s.contains("java/lang/Runtime")) ||
(ORE && s.contains("java.lang.Runtime")) ||
(LIP && s.matches("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b")))
sb.append("Found LDC \"" + s + "\" at field " + classNode.name + "." +f.name+"("+f.desc+")"+BytecodeViewer.nl);
}
}
}
for(Object o : classNode.methods.toArray()) {
MethodNode m = (MethodNode) o;
@ -58,7 +89,7 @@ public class MaliciousCodeScanner extends Plugin {
(ORU && min.owner.equals("java/lang/Runtime")) ||
(OIO && min.owner.startsWith("java/io")))
{
frame.appendText("Found Method call to " + min.owner + "." + min.name + "(" + min.desc + ") at " + classNode.name + "." +m.name+"("+m.desc+")");
sb.append("Found Method call to " + min.owner + "." + min.name + "(" + min.desc + ") at " + classNode.name + "." +m.name+"("+m.desc+")"+BytecodeViewer.nl);
}
}
if (a instanceof LdcInsnNode) {
@ -71,13 +102,15 @@ public class MaliciousCodeScanner extends Plugin {
(ORE && s.contains("java.lang.Runtime")) ||
(LIP && s.matches("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b")))
{
frame.appendText("Found LDC \"" + s + "\" at " + classNode.name + "." +m.name+"("+m.desc+")");
sb.append("Found LDC \"" + s + "\" at method " + classNode.name + "." +m.name+"("+m.desc+")"+BytecodeViewer.nl);
}
}
}
}
}
}
frame.appendText(sb.toString());
frame.setVisible(true);
}

View File

@ -21,10 +21,12 @@ public abstract class Plugin extends Thread {
try {
if(!BytecodeViewer.getLoadedClasses().isEmpty())
execute(BytecodeViewer.getLoadedClasses());
else
else {
System.out.println("Plugin not ran, put some classes in first.");
BytecodeViewer.showMessage("Plugin not ran, put some classes in first.");
}
} catch(Exception e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
} finally {
finished = true;
BytecodeViewer.viewer.setIcon(false);

View File

@ -1,11 +1,17 @@
package the.bytecode.club.bytecodeviewer.plugins;
import javax.swing.JFrame;
import java.awt.Dimension;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import javax.swing.JTextArea;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
/**
* A simple console GUI.
*
@ -16,6 +22,7 @@ import javax.swing.JTextArea;
public class PluginConsole extends JFrame {
JTextArea textArea = new JTextArea();
public PluginConsole(String pluginName) {
this.setIconImages(BytecodeViewer.iconList);
setTitle("Bytecode Viewer - Plugin Console - " + pluginName);
setSize(new Dimension(542, 316));
@ -28,7 +35,7 @@ public class PluginConsole extends JFrame {
public void appendText(String t) {
textArea.setText((textArea.getText().isEmpty() ? "" : textArea.getText()+"\r\n")+t);
textArea.setCaretPosition(textArea.getLineCount());
textArea.setCaretPosition(0);
}
private static final long serialVersionUID = -6556940545421437508L;

View File

@ -9,6 +9,8 @@ import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
/**
* Simply shows all the non-empty strings in every single class
*
@ -21,6 +23,7 @@ public class ShowAllStrings extends Plugin {
@Override
public void execute(ArrayList<ClassNode> classNodeList) {
PluginConsole frame = new PluginConsole("Show All Strings");
StringBuilder sb = new StringBuilder();
for(ClassNode classNode : classNodeList) {
for(Object o : classNode.fields.toArray()) {
FieldNode f = (FieldNode) o;
@ -28,13 +31,13 @@ public class ShowAllStrings extends Plugin {
if(v instanceof String) {
String s = (String)v;
if(!s.isEmpty())
frame.appendText(classNode.name + "." +f.name+""+f.desc+" -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\"");
sb.append(classNode.name + "." +f.name+""+f.desc+" -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""+BytecodeViewer.nl);
}
if(v instanceof String[]) {
for(int i = 0; i < ((String[])v).length; i++) {
String s = ((String[])v)[i];
if(!s.isEmpty())
frame.appendText(classNode.name + "." +f.name+""+f.desc+"["+i+"] -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\"");
sb.append(classNode.name + "." +f.name+""+f.desc+"["+i+"] -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""+BytecodeViewer.nl);
}
}
}
@ -48,12 +51,14 @@ public class ShowAllStrings extends Plugin {
if(((LdcInsnNode)a).cst instanceof String) {
final String s = (String) ((LdcInsnNode)a).cst;
if(!s.isEmpty())
frame.appendText(classNode.name + "." +m.name+""+m.desc+" -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\"");
sb.append(classNode.name + "." +m.name+""+m.desc+" -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""+BytecodeViewer.nl);
}
}
}
}
}
frame.appendText(sb.toString());
frame.setVisible(true);
}

View File

@ -17,9 +17,6 @@ public class ZKMStringDecrypter extends Plugin {
@Override
public void execute(ArrayList<ClassNode> classNodeList) {
for(ClassNode classNode : classNodeList) {
}
BytecodeViewer.showMessage("This is a planned feature.");
}

View File

@ -223,7 +223,7 @@ public class RegexInsnFinder {
"Unknown opcode encountered: "
+ ain.getOpcode());
} catch (final UnexpectedException e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
}
}
offsets[i] = insnString.length();
@ -309,7 +309,7 @@ public class RegexInsnFinder {
if (regexMatcher.find())
return makeResult(regexMatcher.start(), regexMatcher.end());
} catch (final PatternSyntaxException ex) {
ex.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex);
}
return new AbstractInsnNode[0];
}
@ -328,7 +328,7 @@ public class RegexInsnFinder {
results.add(makeResult(regexMatcher.start(), regexMatcher.end()));
}
} catch (final PatternSyntaxException ex) {
ex.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex);
}
return results;
}
@ -350,7 +350,7 @@ public class RegexInsnFinder {
return result;
}
} catch (final PatternSyntaxException ex) {
ex.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex);
}
return new AbstractInsnNode[0][0];
}
@ -373,7 +373,7 @@ public class RegexInsnFinder {
results.add(result);
}
} catch (final PatternSyntaxException ex) {
ex.printStackTrace();
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex);
}
return results;
}