2.0
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:
parent
05ecf04a78
commit
132d8e678f
35 changed files with 454 additions and 230 deletions
BIN
BytecodeViewer 2.0.jar
Normal file
BIN
BytecodeViewer 2.0.jar
Normal file
Binary file not shown.
17
README.txt
17
README.txt
|
@ -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.
|
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.
|
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
|
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:
|
Features:
|
||||||
Java Decompiler - It uses a modified version of FernFlower, Procyon and CFR.
|
Java Decompiler - It uses a modified version of FernFlower, Procyon and CFR.
|
||||||
Bytecode Decompiler - A modified version of J-RET's.
|
Bytecode Decompiler - A modified version of J-RET's.
|
||||||
|
@ -133,3 +135,16 @@ Changelog:
|
||||||
11/3/2014 - Removed the option to disable syntax highlighting (since it's lightweight now).
|
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 - 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).
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
Beta 1.5.3
|
2.0
|
BIN
libs/imgscalr-lib-4.2.jar
Normal file
BIN
libs/imgscalr-lib-4.2.jar
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -357,13 +357,13 @@ public class FileDrop {
|
||||||
} // end try
|
} // end try
|
||||||
catch (final java.io.IOException io) {
|
catch (final java.io.IOException io) {
|
||||||
log(out, "FileDrop: IOException - abort:");
|
log(out, "FileDrop: IOException - abort:");
|
||||||
io.printStackTrace(out);
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(io);
|
||||||
evt.rejectDrop();
|
evt.rejectDrop();
|
||||||
} // end catch IOException
|
} // end catch IOException
|
||||||
catch (final java.awt.datatransfer.UnsupportedFlavorException ufe) {
|
catch (final java.awt.datatransfer.UnsupportedFlavorException ufe) {
|
||||||
log(out,
|
log(out,
|
||||||
"FileDrop: UnsupportedFlavorException - abort:");
|
"FileDrop: UnsupportedFlavorException - abort:");
|
||||||
ufe.printStackTrace(out);
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ufe);
|
||||||
evt.rejectDrop();
|
evt.rejectDrop();
|
||||||
} // end catch: UnsupportedFlavorException
|
} // end catch: UnsupportedFlavorException
|
||||||
finally {
|
finally {
|
||||||
|
@ -467,7 +467,7 @@ public class FileDrop {
|
||||||
dt.addDropTargetListener(dropListener);
|
dt.addDropTargetListener(dropListener);
|
||||||
} // end try
|
} // end try
|
||||||
catch (final java.util.TooManyListenersException e) {
|
catch (final java.util.TooManyListenersException e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
log(out,
|
log(out,
|
||||||
"FileDrop: Drop will not work due to previous error. Do you have another listener attached?");
|
"FileDrop: Drop will not work due to previous error. Do you have another listener attached?");
|
||||||
} // end catch
|
} // end catch
|
||||||
|
|
|
@ -101,7 +101,7 @@ public class JarUtils {
|
||||||
|
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ public class JarUtils {
|
||||||
|
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,7 +218,7 @@ public class InstructionPrinter {
|
||||||
try {
|
try {
|
||||||
return nameOpcode(tin.getOpcode()) + " " + Type.getType(tin.desc).getClassName();
|
return nameOpcode(tin.getOpcode()) + " " + Type.getType(tin.desc).getClassName();
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
}
|
}
|
||||||
return "//error";
|
return "//error";
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ public class InstructionPrinter {
|
||||||
}
|
}
|
||||||
bw.close();
|
bw.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -46,7 +46,7 @@ public class CFRDecompiler extends JavaDecompiler {
|
||||||
|
|
||||||
fos.close();
|
fos.close();
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
String fuckery = fuckery(fileStart);
|
String fuckery = fuckery(fileStart);
|
||||||
|
@ -81,7 +81,7 @@ public class CFRDecompiler extends JavaDecompiler {
|
||||||
try {
|
try {
|
||||||
s = DiskReader.loadAsString(f.getAbsolutePath());
|
s = DiskReader.loadAsString(f.getAbsolutePath());
|
||||||
} catch(Exception e) {
|
} 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 "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com";
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
@ -205,7 +205,7 @@ public class CFRDecompiler extends JavaDecompiler {
|
||||||
try {
|
try {
|
||||||
zip(fuck, new File(zipName));
|
zip(fuck, new File(zipName));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
fuck.delete();
|
fuck.delete();
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class FernFlowerDecompiler extends JavaDecompiler {
|
||||||
|
|
||||||
fos.close();
|
fos.close();
|
||||||
} catch (final IOException e) {
|
} 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(), "."));
|
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempClass.getAbsolutePath(), "."));
|
||||||
|
@ -76,7 +76,7 @@ public class FernFlowerDecompiler extends JavaDecompiler {
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
} catch (Exception e) {
|
} 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";
|
return "FernFlower error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com";
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class ProcyonDecompiler extends JavaDecompiler {
|
||||||
|
|
||||||
fos.close();
|
fos.close();
|
||||||
} catch (final IOException e) {
|
} 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;
|
return decompiledSource;
|
||||||
} catch(Exception e) {
|
} 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";
|
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 {
|
try {
|
||||||
doSaveJarDecompiled(tempZip, new File(zipName));
|
doSaveJarDecompiled(tempZip, new File(zipName));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.awt.Color;
|
||||||
|
|
||||||
public class AboutWindow extends JFrame {
|
public class AboutWindow extends JFrame {
|
||||||
public AboutWindow() {
|
public AboutWindow() {
|
||||||
|
this.setIconImages(BytecodeViewer.iconList);
|
||||||
setSize(new Dimension(446, 374));
|
setSize(new Dimension(446, 374));
|
||||||
setType(Type.UTILITY);
|
setType(Type.UTILITY);
|
||||||
setTitle("Bytecode Viewer - About");
|
setTitle("Bytecode Viewer - About");
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
import static javax.swing.ScrollPaneConstants.*;
|
import static javax.swing.ScrollPaneConstants.*;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
@ -113,25 +114,97 @@ public class ClassViewer extends JPanel {
|
||||||
public JPanel bytePanel = new JPanel(new BorderLayout());
|
public JPanel bytePanel = new JPanel(new BorderLayout());
|
||||||
public JPanel decompPanel = 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 {
|
try {
|
||||||
if(pane == 0) { //bytecode
|
Component[] com = null;
|
||||||
for(Component c : bytePanel.getComponents()) {
|
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) {
|
if(c instanceof RTextScrollPane) {
|
||||||
RSyntaxTextArea area = (RSyntaxTextArea) ((RTextScrollPane)c).getViewport().getComponent(0);
|
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);
|
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) {
|
} 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();
|
pos += pattern.length();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassViewer(final String name, final ClassNode cn) {
|
public ClassViewer(final String name, final ClassNode cn) {
|
||||||
JButton byteSearch = new JButton("Search");
|
JButton byteSearchNext = new JButton();
|
||||||
bytePanelSearch.add(byteSearch, BorderLayout.WEST);
|
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();
|
final JTextField byteField = new JTextField();
|
||||||
bytePanelSearch.add(byteField, BorderLayout.CENTER);
|
bytePanelSearch.add(byteField, BorderLayout.CENTER);
|
||||||
bytePanelSearch.add(byteCheck, BorderLayout.EAST);
|
bytePanelSearch.add(byteCheck, BorderLayout.EAST);
|
||||||
byteSearch.addActionListener(new ActionListener() {
|
byteSearchNext.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(final ActionEvent arg0) {
|
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");
|
JButton decompSearchNext = new JButton();
|
||||||
decompPanelSearch.add(decompSearch, BorderLayout.WEST);
|
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();
|
final JTextField decompField = new JTextField();
|
||||||
decompPanelSearch.add(decompField, BorderLayout.CENTER);
|
decompPanelSearch.add(decompField, BorderLayout.CENTER);
|
||||||
decompPanelSearch.add(decompCheck, BorderLayout.EAST);
|
decompPanelSearch.add(decompCheck, BorderLayout.EAST);
|
||||||
decompSearch.addActionListener(new ActionListener() {
|
decompSearchNext.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(final ActionEvent arg0) {
|
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);
|
return new IconView(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// default to text display
|
|
||||||
return new LabelView(elem);
|
return new LabelView(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package the.bytecode.club.bytecodeviewer.gui;
|
package the.bytecode.club.bytecodeviewer.gui;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.swing.ButtonGroup;
|
import javax.swing.ButtonGroup;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JSplitPane;
|
import javax.swing.JSplitPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ import javax.swing.JMenuItem;
|
||||||
import javax.swing.JSeparator;
|
import javax.swing.JSeparator;
|
||||||
import javax.swing.JCheckBoxMenuItem;
|
import javax.swing.JCheckBoxMenuItem;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
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.ActionListener;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@ -209,7 +207,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
try {
|
try {
|
||||||
mntmNewMenuItem_4.setIcon(new ImageIcon(getClass().getResource("/resources/1.gif")));
|
mntmNewMenuItem_4.setIcon(new ImageIcon(getClass().getResource("/resources/1.gif")));
|
||||||
} catch(NullPointerException e) {
|
} 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
|
} else
|
||||||
mntmNewMenuItem_4.setIcon(null);
|
mntmNewMenuItem_4.setIcon(null);
|
||||||
|
@ -218,26 +216,8 @@ 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() {
|
public MainViewerGUI() {
|
||||||
|
this.setIconImages(BytecodeViewer.iconList);
|
||||||
decompilerGroup.add(fernflowerDec);
|
decompilerGroup.add(fernflowerDec);
|
||||||
decompilerGroup.add(procyonDec);
|
decompilerGroup.add(procyonDec);
|
||||||
decompilerGroup.add(cfrDec);
|
decompilerGroup.add(cfrDec);
|
||||||
|
@ -335,7 +315,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
BytecodeViewer.openFiles(new File[]{fc.getSelectedFile()});
|
BytecodeViewer.openFiles(new File[]{fc.getSelectedFile()});
|
||||||
BytecodeViewer.viewer.setC(false);
|
BytecodeViewer.viewer.setC(false);
|
||||||
} catch (Exception e1) {
|
} 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);
|
mnNewMenu.add(chckbxmntmNewCheckItem_12);
|
||||||
|
|
||||||
JMenuItem mntmExit = new JMenuItem("Exit");
|
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);
|
mnNewMenu.add(mntmExit);
|
||||||
|
|
||||||
JMenu mnView = new JMenu("View");
|
JMenu mnView = new JMenu("View");
|
||||||
|
@ -611,8 +611,10 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
public void actionPerformed(ActionEvent arg0) {
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
if(!BytecodeViewer.loadedClasses.isEmpty())
|
if(!BytecodeViewer.loadedClasses.isEmpty())
|
||||||
new ReplaceStringsOptions().setVisible(true);
|
new ReplaceStringsOptions().setVisible(true);
|
||||||
else
|
else {
|
||||||
System.out.println("Plugin not ran, put some classes in first.");
|
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.startPlugin(fc.getSelectedFile());
|
||||||
BytecodeViewer.viewer.setC(false);
|
BytecodeViewer.viewer.setC(false);
|
||||||
} catch (Exception e1) {
|
} 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) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
if(!BytecodeViewer.loadedClasses.isEmpty())
|
if(!BytecodeViewer.loadedClasses.isEmpty())
|
||||||
new MaliciousCodeScannerOptions().setVisible(true);
|
new MaliciousCodeScannerOptions().setVisible(true);
|
||||||
else
|
else {
|
||||||
System.out.println("Plugin not ran, put some classes in first.");
|
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() {
|
mntmShowAllStrings.addActionListener(new ActionListener() {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.awt.Dimension;
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
import the.bytecode.club.bytecodeviewer.plugins.MaliciousCodeScanner;
|
import the.bytecode.club.bytecodeviewer.plugins.MaliciousCodeScanner;
|
||||||
import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ import java.awt.event.ActionEvent;
|
||||||
|
|
||||||
public class MaliciousCodeScannerOptions extends JFrame {
|
public class MaliciousCodeScannerOptions extends JFrame {
|
||||||
public MaliciousCodeScannerOptions() {
|
public MaliciousCodeScannerOptions() {
|
||||||
|
this.setIconImages(BytecodeViewer.iconList);
|
||||||
setSize(new Dimension(250, 277));
|
setSize(new Dimension(250, 277));
|
||||||
setResizable(false);
|
setResizable(false);
|
||||||
setTitle("Malicious Code Scanner Options");
|
setTitle("Malicious Code Scanner Options");
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
package the.bytecode.club.bytecodeviewer.gui;
|
package the.bytecode.club.bytecodeviewer.gui;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
||||||
import the.bytecode.club.bytecodeviewer.plugins.ReplaceStrings;
|
import the.bytecode.club.bytecodeviewer.plugins.ReplaceStrings;
|
||||||
|
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
|
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
|
|
||||||
public class ReplaceStringsOptions extends JFrame {
|
public class ReplaceStringsOptions extends JFrame {
|
||||||
public ReplaceStringsOptions() {
|
public ReplaceStringsOptions() {
|
||||||
|
this.setIconImages(BytecodeViewer.iconList);
|
||||||
setSize(new Dimension(250, 176));
|
setSize(new Dimension(250, 176));
|
||||||
setResizable(false);
|
setResizable(false);
|
||||||
setTitle("Replace Strings");
|
setTitle("Replace Strings");
|
||||||
|
|
40
src/the/bytecode/club/bytecodeviewer/gui/StackTraceUI.java
Normal file
40
src/the/bytecode/club/bytecodeviewer/gui/StackTraceUI.java
Normal 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;
|
||||||
|
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ public class TabbedPane extends JPanel {
|
||||||
private static final long serialVersionUID = -4774885688297538774L;
|
private static final long serialVersionUID = -4774885688297538774L;
|
||||||
private final JTabbedPane pane;
|
private final JTabbedPane pane;
|
||||||
final JButton button = new TabButton();
|
final JButton button = new TabButton();
|
||||||
|
private static long zero = System.currentTimeMillis();
|
||||||
|
|
||||||
public TabbedPane(final JTabbedPane pane) {
|
public TabbedPane(final JTabbedPane pane) {
|
||||||
//unset default FlowLayout' gaps
|
//unset default FlowLayout' gaps
|
||||||
|
@ -63,46 +64,22 @@ public class TabbedPane extends JPanel {
|
||||||
add(button);
|
add(button);
|
||||||
//add more space to the top of the component
|
//add more space to the top of the component
|
||||||
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
|
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
|
||||||
pane.addMouseListener(new MouseListener() {
|
button.addMouseListener(new MouseListener() {
|
||||||
@Override
|
@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
|
@Override public void mouseEntered(MouseEvent arg0) {}
|
||||||
public void mouseEntered(MouseEvent arg0) {
|
@Override public void mouseExited(MouseEvent arg0) {}
|
||||||
}
|
@Override public void mousePressed(MouseEvent arg0) {}
|
||||||
@Override
|
@Override public void mouseReleased(MouseEvent e) {}
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,6 @@ public class AllatoriStringDecrypter extends Plugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ArrayList<ClassNode> classNodeList) {
|
public void execute(ArrayList<ClassNode> classNodeList) {
|
||||||
for(ClassNode classNode : classNodeList) {
|
|
||||||
|
|
||||||
}
|
|
||||||
BytecodeViewer.showMessage("This is a planned feature.");
|
BytecodeViewer.showMessage("This is a planned feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,14 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
import org.objectweb.asm.tree.FieldNode;
|
||||||
import org.objectweb.asm.tree.InsnList;
|
import org.objectweb.asm.tree.InsnList;
|
||||||
import org.objectweb.asm.tree.LdcInsnNode;
|
import org.objectweb.asm.tree.LdcInsnNode;
|
||||||
import org.objectweb.asm.tree.MethodInsnNode;
|
import org.objectweb.asm.tree.MethodInsnNode;
|
||||||
import org.objectweb.asm.tree.MethodNode;
|
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
|
* The idea/core was based off of J-RET's Malicious Code Searcher
|
||||||
* I improved it, and added more stuff to search for.
|
* I improved it, and added more stuff to search for.
|
||||||
|
@ -45,7 +48,35 @@ public class MaliciousCodeScanner extends Plugin {
|
||||||
@Override
|
@Override
|
||||||
public void execute(ArrayList<ClassNode> classNodeList) {
|
public void execute(ArrayList<ClassNode> classNodeList) {
|
||||||
PluginConsole frame = new PluginConsole("Malicious Code Scanner");
|
PluginConsole frame = new PluginConsole("Malicious Code Scanner");
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
for(ClassNode classNode : classNodeList) {
|
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()) {
|
for(Object o : classNode.methods.toArray()) {
|
||||||
MethodNode m = (MethodNode) o;
|
MethodNode m = (MethodNode) o;
|
||||||
|
|
||||||
|
@ -58,7 +89,7 @@ public class MaliciousCodeScanner extends Plugin {
|
||||||
(ORU && min.owner.equals("java/lang/Runtime")) ||
|
(ORU && min.owner.equals("java/lang/Runtime")) ||
|
||||||
(OIO && min.owner.startsWith("java/io")))
|
(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) {
|
if (a instanceof LdcInsnNode) {
|
||||||
|
@ -71,13 +102,15 @@ public class MaliciousCodeScanner extends Plugin {
|
||||||
(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")))
|
(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);
|
frame.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,12 @@ public abstract class Plugin extends Thread {
|
||||||
try {
|
try {
|
||||||
if(!BytecodeViewer.getLoadedClasses().isEmpty())
|
if(!BytecodeViewer.getLoadedClasses().isEmpty())
|
||||||
execute(BytecodeViewer.getLoadedClasses());
|
execute(BytecodeViewer.getLoadedClasses());
|
||||||
else
|
else {
|
||||||
System.out.println("Plugin not ran, put some classes in first.");
|
System.out.println("Plugin not ran, put some classes in first.");
|
||||||
|
BytecodeViewer.showMessage("Plugin not ran, put some classes in first.");
|
||||||
|
}
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
} finally {
|
} finally {
|
||||||
finished = true;
|
finished = true;
|
||||||
BytecodeViewer.viewer.setIcon(false);
|
BytecodeViewer.viewer.setIcon(false);
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
package the.bytecode.club.bytecodeviewer.plugins;
|
package the.bytecode.club.bytecodeviewer.plugins;
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
|
|
||||||
import javax.swing.JTextArea;
|
import javax.swing.JTextArea;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple console GUI.
|
* A simple console GUI.
|
||||||
*
|
*
|
||||||
|
@ -16,6 +22,7 @@ import javax.swing.JTextArea;
|
||||||
public class PluginConsole extends JFrame {
|
public class PluginConsole extends JFrame {
|
||||||
JTextArea textArea = new JTextArea();
|
JTextArea textArea = new JTextArea();
|
||||||
public PluginConsole(String pluginName) {
|
public PluginConsole(String pluginName) {
|
||||||
|
this.setIconImages(BytecodeViewer.iconList);
|
||||||
setTitle("Bytecode Viewer - Plugin Console - " + pluginName);
|
setTitle("Bytecode Viewer - Plugin Console - " + pluginName);
|
||||||
setSize(new Dimension(542, 316));
|
setSize(new Dimension(542, 316));
|
||||||
|
|
||||||
|
@ -28,7 +35,7 @@ public class PluginConsole extends JFrame {
|
||||||
|
|
||||||
public void appendText(String t) {
|
public void appendText(String t) {
|
||||||
textArea.setText((textArea.getText().isEmpty() ? "" : textArea.getText()+"\r\n")+t);
|
textArea.setText((textArea.getText().isEmpty() ? "" : textArea.getText()+"\r\n")+t);
|
||||||
textArea.setCaretPosition(textArea.getLineCount());
|
textArea.setCaretPosition(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final long serialVersionUID = -6556940545421437508L;
|
private static final long serialVersionUID = -6556940545421437508L;
|
||||||
|
|
|
@ -9,6 +9,8 @@ import org.objectweb.asm.tree.InsnList;
|
||||||
import org.objectweb.asm.tree.LdcInsnNode;
|
import org.objectweb.asm.tree.LdcInsnNode;
|
||||||
import org.objectweb.asm.tree.MethodNode;
|
import org.objectweb.asm.tree.MethodNode;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simply shows all the non-empty strings in every single class
|
* Simply shows all the non-empty strings in every single class
|
||||||
*
|
*
|
||||||
|
@ -21,6 +23,7 @@ public class ShowAllStrings extends Plugin {
|
||||||
@Override
|
@Override
|
||||||
public void execute(ArrayList<ClassNode> classNodeList) {
|
public void execute(ArrayList<ClassNode> classNodeList) {
|
||||||
PluginConsole frame = new PluginConsole("Show All Strings");
|
PluginConsole frame = new PluginConsole("Show All Strings");
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
for(ClassNode classNode : classNodeList) {
|
for(ClassNode classNode : classNodeList) {
|
||||||
for(Object o : classNode.fields.toArray()) {
|
for(Object o : classNode.fields.toArray()) {
|
||||||
FieldNode f = (FieldNode) o;
|
FieldNode f = (FieldNode) o;
|
||||||
|
@ -28,13 +31,13 @@ public class ShowAllStrings extends Plugin {
|
||||||
if(v instanceof String) {
|
if(v instanceof String) {
|
||||||
String s = (String)v;
|
String s = (String)v;
|
||||||
if(!s.isEmpty())
|
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[]) {
|
if(v instanceof String[]) {
|
||||||
for(int i = 0; i < ((String[])v).length; i++) {
|
for(int i = 0; i < ((String[])v).length; i++) {
|
||||||
String s = ((String[])v)[i];
|
String s = ((String[])v)[i];
|
||||||
if(!s.isEmpty())
|
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) {
|
if(((LdcInsnNode)a).cst instanceof String) {
|
||||||
final String s = (String) ((LdcInsnNode)a).cst;
|
final String s = (String) ((LdcInsnNode)a).cst;
|
||||||
if(!s.isEmpty())
|
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);
|
frame.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,6 @@ public class ZKMStringDecrypter extends Plugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ArrayList<ClassNode> classNodeList) {
|
public void execute(ArrayList<ClassNode> classNodeList) {
|
||||||
for(ClassNode classNode : classNodeList) {
|
|
||||||
|
|
||||||
}
|
|
||||||
BytecodeViewer.showMessage("This is a planned feature.");
|
BytecodeViewer.showMessage("This is a planned feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,7 +223,7 @@ public class RegexInsnFinder {
|
||||||
"Unknown opcode encountered: "
|
"Unknown opcode encountered: "
|
||||||
+ ain.getOpcode());
|
+ ain.getOpcode());
|
||||||
} catch (final UnexpectedException e) {
|
} catch (final UnexpectedException e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offsets[i] = insnString.length();
|
offsets[i] = insnString.length();
|
||||||
|
@ -309,7 +309,7 @@ public class RegexInsnFinder {
|
||||||
if (regexMatcher.find())
|
if (regexMatcher.find())
|
||||||
return makeResult(regexMatcher.start(), regexMatcher.end());
|
return makeResult(regexMatcher.start(), regexMatcher.end());
|
||||||
} catch (final PatternSyntaxException ex) {
|
} catch (final PatternSyntaxException ex) {
|
||||||
ex.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex);
|
||||||
}
|
}
|
||||||
return new AbstractInsnNode[0];
|
return new AbstractInsnNode[0];
|
||||||
}
|
}
|
||||||
|
@ -328,7 +328,7 @@ public class RegexInsnFinder {
|
||||||
results.add(makeResult(regexMatcher.start(), regexMatcher.end()));
|
results.add(makeResult(regexMatcher.start(), regexMatcher.end()));
|
||||||
}
|
}
|
||||||
} catch (final PatternSyntaxException ex) {
|
} catch (final PatternSyntaxException ex) {
|
||||||
ex.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
@ -350,7 +350,7 @@ public class RegexInsnFinder {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} catch (final PatternSyntaxException ex) {
|
} catch (final PatternSyntaxException ex) {
|
||||||
ex.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex);
|
||||||
}
|
}
|
||||||
return new AbstractInsnNode[0][0];
|
return new AbstractInsnNode[0][0];
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ public class RegexInsnFinder {
|
||||||
results.add(result);
|
results.add(result);
|
||||||
}
|
}
|
||||||
} catch (final PatternSyntaxException ex) {
|
} catch (final PatternSyntaxException ex) {
|
||||||
ex.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue