2.3.0 Release
12/16/2014 - Started updating the class viewer. 12/18/2014 - Finished a basic concept of the new class viewer. 12/18/2014 - Fixed an error with importing some jars. 12/18/2014 - Fixed the about window. 12/18/2014 - Finished the final concept for the new class viewer. 12/18/2014 - Threaded save Java files as zip, it now runs in a background thread. 12/18/2014 - Save Java files as zip now prompts you to select a decompiler. 12/18/2014 - Removed the cursor waiting for save Java files as zip. 12/18/2014 - Wrapped the save Java files as zip around an exception handler, it will now safely show the exception if any is thrown. 12/18/2014 - Fixed not escaping the Java strings by default for the Bytecode decompiler. - http://i.imgur.com/YrRnZA7.png 12/18/2014 - Used Eclipse's code formatting tool and formatted the code 12/19/2014 - Priav03 fixed the quick class searcher.
This commit is contained in:
parent
a8220ecb61
commit
4e6647be19
Binary file not shown.
26
README.txt
26
README.txt
|
@ -13,7 +13,16 @@ Code from various projects has been used, including but not limited to:
|
|||
FernFlower by Stiver
|
||||
Procyon by Mstrobel
|
||||
CFR by Lee Benfield
|
||||
CFIDE by Bibl
|
||||
CFIDE by Bibl
|
||||
|
||||
Contributors:
|
||||
Konloch
|
||||
Bibl
|
||||
Fluke
|
||||
Righteous
|
||||
sahitya-pavurala
|
||||
priav03
|
||||
If I missed you, please feel free to contact me @Konloch or konloch@gmail.com
|
||||
|
||||
Video: http://the.bytecode.club/bytecodeviewer-video/
|
||||
Source Code: https://github.com/konloch/bytecode-viewer
|
||||
|
@ -181,4 +190,17 @@ Changelog:
|
|||
12/13/2014 - Fixed an issue with the text search function.
|
||||
12/13/2014 - Search results are now clickable.
|
||||
--- 2.2.1 ---:
|
||||
12/13/2014 - Fixed an issue with the Bytecode Decompiler. - Thanks bibl
|
||||
12/13/2014 - Fixed an issue with the Bytecode Decompiler. - Thanks bibl
|
||||
--- 2.3.0 ---:
|
||||
12/16/2014 - Started updating the class viewer.
|
||||
12/18/2014 - Finished a basic concept of the new class viewer.
|
||||
12/18/2014 - Fixed an error with importing some jars.
|
||||
12/18/2014 - Fixed the about window.
|
||||
12/18/2014 - Finished the final concept for the new class viewer.
|
||||
12/18/2014 - Threaded save Java files as zip, it now runs in a background thread.
|
||||
12/18/2014 - Save Java files as zip now prompts you to select a decompiler.
|
||||
12/18/2014 - Removed the cursor waiting for save Java files as zip.
|
||||
12/18/2014 - Wrapped the save Java files as zip around an exception handler, it will now safely show the exception if any is thrown.
|
||||
12/18/2014 - Fixed not escaping the Java strings by default for the Bytecode decompiler. - http://i.imgur.com/YrRnZA7.png
|
||||
12/18/2014 - Used Eclipse's code formatting tool and formatted the code
|
||||
12/19/2014 - Priav03 fixed the quick class searcher.
|
|
@ -5,285 +5,253 @@ import java.awt.*;
|
|||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: laullon
|
||||
* Date: 08-abr-2003
|
||||
* Time: 13:21:09
|
||||
* Created by IntelliJ IDEA. User: laullon Date: 08-abr-2003 Time: 13:21:09
|
||||
*/
|
||||
public class JHexEditor extends JPanel implements FocusListener,AdjustmentListener,MouseWheelListener
|
||||
{
|
||||
public class JHexEditor extends JPanel implements FocusListener,
|
||||
AdjustmentListener, MouseWheelListener {
|
||||
private static final long serialVersionUID = 2289328616534802372L;
|
||||
byte[] buff;
|
||||
public int cursor;
|
||||
protected static Font font=new Font("Monospaced",0,12);
|
||||
protected int border=2;
|
||||
public boolean DEBUG=false;
|
||||
private JPanel panel;
|
||||
private JScrollBar sb;
|
||||
private int inicio=0;
|
||||
private int lineas=10;
|
||||
public int cursor;
|
||||
protected static Font font = new Font("Monospaced", 0, 12);
|
||||
protected int border = 2;
|
||||
public boolean DEBUG = false;
|
||||
private JPanel panel;
|
||||
private JScrollBar sb;
|
||||
private int inicio = 0;
|
||||
private int lineas = 10;
|
||||
|
||||
public JHexEditor(byte[] buff)
|
||||
{
|
||||
super();
|
||||
this.buff=buff;
|
||||
public JHexEditor(byte[] buff) {
|
||||
super();
|
||||
this.buff = buff;
|
||||
|
||||
this.addMouseWheelListener(this);
|
||||
this.addMouseWheelListener(this);
|
||||
|
||||
sb=new JScrollBar(JScrollBar.VERTICAL);
|
||||
sb.addAdjustmentListener(this);
|
||||
sb.setMinimum(0);
|
||||
sb.setMaximum(buff.length/getLineas());
|
||||
sb = new JScrollBar(JScrollBar.VERTICAL);
|
||||
sb.addAdjustmentListener(this);
|
||||
sb.setMinimum(0);
|
||||
sb.setMaximum(buff.length / getLineas());
|
||||
|
||||
JPanel p1,p2,p3;
|
||||
//centro
|
||||
p1=new JPanel(new BorderLayout(1,1));
|
||||
p1.add(new JHexEditorHEX(this),BorderLayout.CENTER);
|
||||
p1.add(new Columnas(),BorderLayout.NORTH);
|
||||
JPanel p1, p2, p3;
|
||||
// centro
|
||||
p1 = new JPanel(new BorderLayout(1, 1));
|
||||
p1.add(new JHexEditorHEX(this), BorderLayout.CENTER);
|
||||
p1.add(new Columnas(), BorderLayout.NORTH);
|
||||
|
||||
// izq.
|
||||
p2=new JPanel(new BorderLayout(1,1));
|
||||
p2.add(new Filas(),BorderLayout.CENTER);
|
||||
p2.add(new Caja(),BorderLayout.NORTH);
|
||||
// izq.
|
||||
p2 = new JPanel(new BorderLayout(1, 1));
|
||||
p2.add(new Filas(), BorderLayout.CENTER);
|
||||
p2.add(new Caja(), BorderLayout.NORTH);
|
||||
|
||||
// der
|
||||
p3=new JPanel(new BorderLayout(1,1));
|
||||
p3.add(sb,BorderLayout.EAST);
|
||||
p3.add(new JHexEditorASCII(this),BorderLayout.CENTER);
|
||||
p3.add(new Caja(),BorderLayout.NORTH);
|
||||
// der
|
||||
p3 = new JPanel(new BorderLayout(1, 1));
|
||||
p3.add(sb, BorderLayout.EAST);
|
||||
p3.add(new JHexEditorASCII(this), BorderLayout.CENTER);
|
||||
p3.add(new Caja(), BorderLayout.NORTH);
|
||||
|
||||
panel=new JPanel();
|
||||
panel.setLayout(new BorderLayout(1,1));
|
||||
panel.add(p1,BorderLayout.CENTER);
|
||||
panel.add(p2,BorderLayout.WEST);
|
||||
panel.add(p3,BorderLayout.EAST);
|
||||
panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout(1, 1));
|
||||
panel.add(p1, BorderLayout.CENTER);
|
||||
panel.add(p2, BorderLayout.WEST);
|
||||
panel.add(p3, BorderLayout.EAST);
|
||||
|
||||
this.setLayout(new BorderLayout(1,1));
|
||||
this.add(panel,BorderLayout.CENTER);
|
||||
}
|
||||
this.setLayout(new BorderLayout(1, 1));
|
||||
this.add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
FontMetrics fn=getFontMetrics(font);
|
||||
Rectangle rec=this.getBounds();
|
||||
lineas=(rec.height/fn.getHeight())-1;
|
||||
int n=(buff.length/16)-1;
|
||||
if(lineas>n) { lineas=n; inicio=0; }
|
||||
public void paint(Graphics g) {
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
Rectangle rec = this.getBounds();
|
||||
lineas = (rec.height / fn.getHeight()) - 1;
|
||||
int n = (buff.length / 16) - 1;
|
||||
if (lineas > n) {
|
||||
lineas = n;
|
||||
inicio = 0;
|
||||
}
|
||||
|
||||
sb.setValues(getInicio(),+getLineas(),0,buff.length/16);
|
||||
sb.setValueIsAdjusting(true);
|
||||
super.paint(g);
|
||||
}
|
||||
sb.setValues(getInicio(), +getLineas(), 0, buff.length / 16);
|
||||
sb.setValueIsAdjusting(true);
|
||||
super.paint(g);
|
||||
}
|
||||
|
||||
protected void actualizaCursor()
|
||||
{
|
||||
int n=(cursor/16);
|
||||
protected void actualizaCursor() {
|
||||
int n = (cursor / 16);
|
||||
|
||||
System.out.print("- "+inicio+"<"+n+"<"+(lineas+inicio)+"("+lineas+")");
|
||||
System.out.print("- " + inicio + "<" + n + "<" + (lineas + inicio)
|
||||
+ "(" + lineas + ")");
|
||||
|
||||
if(n<inicio) inicio=n;
|
||||
else if(n>=inicio+lineas) inicio=n-(lineas-1);
|
||||
if (n < inicio)
|
||||
inicio = n;
|
||||
else if (n >= inicio + lineas)
|
||||
inicio = n - (lineas - 1);
|
||||
|
||||
System.out.println(" - "+inicio+"<"+n+"<"+(lineas+inicio)+"("+lineas+")");
|
||||
System.out.println(" - " + inicio + "<" + n + "<" + (lineas + inicio)
|
||||
+ "(" + lineas + ")");
|
||||
|
||||
repaint();
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
protected int getInicio()
|
||||
{
|
||||
return inicio;
|
||||
}
|
||||
protected int getInicio() {
|
||||
return inicio;
|
||||
}
|
||||
|
||||
protected int getLineas()
|
||||
{
|
||||
return lineas;
|
||||
}
|
||||
protected int getLineas() {
|
||||
return lineas;
|
||||
}
|
||||
|
||||
protected void fondo(Graphics g,int x,int y,int s)
|
||||
{
|
||||
FontMetrics fn=getFontMetrics(font);
|
||||
g.fillRect(((fn.stringWidth(" ")+1)*x)+border,(fn.getHeight()*y)+border,((fn.stringWidth(" ")+1)*s),fn.getHeight()+1);
|
||||
}
|
||||
protected void fondo(Graphics g, int x, int y, int s) {
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
g.fillRect(((fn.stringWidth(" ") + 1) * x) + border,
|
||||
(fn.getHeight() * y) + border, ((fn.stringWidth(" ") + 1) * s),
|
||||
fn.getHeight() + 1);
|
||||
}
|
||||
|
||||
protected void cuadro(Graphics g,int x,int y,int s)
|
||||
{
|
||||
FontMetrics fn=getFontMetrics(font);
|
||||
g.drawRect(((fn.stringWidth(" ")+1)*x)+border,(fn.getHeight()*y)+border,((fn.stringWidth(" ")+1)*s),fn.getHeight()+1);
|
||||
}
|
||||
protected void cuadro(Graphics g, int x, int y, int s) {
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
g.drawRect(((fn.stringWidth(" ") + 1) * x) + border,
|
||||
(fn.getHeight() * y) + border, ((fn.stringWidth(" ") + 1) * s),
|
||||
fn.getHeight() + 1);
|
||||
}
|
||||
|
||||
protected void printString(Graphics g,String s,int x,int y)
|
||||
{
|
||||
FontMetrics fn=getFontMetrics(font);
|
||||
g.drawString(s,((fn.stringWidth(" ")+1)*x)+border,((fn.getHeight()*(y+1))-fn.getMaxDescent())+border);
|
||||
}
|
||||
protected void printString(Graphics g, String s, int x, int y) {
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
g.drawString(s, ((fn.stringWidth(" ") + 1) * x) + border,
|
||||
((fn.getHeight() * (y + 1)) - fn.getMaxDescent()) + border);
|
||||
}
|
||||
|
||||
public void focusGained(FocusEvent e)
|
||||
{
|
||||
this.repaint();
|
||||
}
|
||||
public void focusGained(FocusEvent e) {
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e)
|
||||
{
|
||||
this.repaint();
|
||||
}
|
||||
public void focusLost(FocusEvent e) {
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
public void adjustmentValueChanged(AdjustmentEvent e)
|
||||
{
|
||||
inicio=e.getValue();
|
||||
if(inicio<0) inicio=0;
|
||||
repaint();
|
||||
}
|
||||
public void adjustmentValueChanged(AdjustmentEvent e) {
|
||||
inicio = e.getValue();
|
||||
if (inicio < 0)
|
||||
inicio = 0;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void mouseWheelMoved(MouseWheelEvent e)
|
||||
{
|
||||
inicio+=(e.getUnitsToScroll());
|
||||
if((inicio+lineas)>=buff.length/16) inicio=(buff.length/16)-lineas;
|
||||
if(inicio<0) inicio=0;
|
||||
repaint();
|
||||
}
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
inicio += (e.getUnitsToScroll());
|
||||
if ((inicio + lineas) >= buff.length / 16)
|
||||
inicio = (buff.length / 16) - lineas;
|
||||
if (inicio < 0)
|
||||
inicio = 0;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
/*switch(e.getKeyCode())
|
||||
{
|
||||
case 33: // rep
|
||||
if(cursor>=(16*lineas)) cursor-=(16*lineas);
|
||||
actualizaCursor();
|
||||
break;
|
||||
case 34: // fin
|
||||
if(cursor<(buff.length-(16*lineas))) cursor+=(16*lineas);
|
||||
actualizaCursor();
|
||||
break;
|
||||
case 35: // fin
|
||||
cursor=buff.length-1;
|
||||
actualizaCursor();
|
||||
break;
|
||||
case 36: // ini
|
||||
cursor=0;
|
||||
actualizaCursor();
|
||||
break;
|
||||
case 37: // <--
|
||||
if(cursor!=0) cursor--;
|
||||
actualizaCursor();
|
||||
break;
|
||||
case 38: // <--
|
||||
if(cursor>15) cursor-=16;
|
||||
actualizaCursor();
|
||||
break;
|
||||
case 39: // -->
|
||||
if(cursor!=(buff.length-1)) cursor++;
|
||||
actualizaCursor();
|
||||
break;
|
||||
case 40: // -->
|
||||
if(cursor<(buff.length-16)) cursor+=16;
|
||||
actualizaCursor();
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
public void keyPressed(KeyEvent e) {
|
||||
/*
|
||||
* switch(e.getKeyCode()) { case 33: // rep if(cursor>=(16*lineas))
|
||||
* cursor-=(16*lineas); actualizaCursor(); break; case 34: // fin
|
||||
* if(cursor<(buff.length-(16*lineas))) cursor+=(16*lineas);
|
||||
* actualizaCursor(); break; case 35: // fin cursor=buff.length-1;
|
||||
* actualizaCursor(); break; case 36: // ini cursor=0;
|
||||
* actualizaCursor(); break; case 37: // <-- if(cursor!=0) cursor--;
|
||||
* actualizaCursor(); break; case 38: // <-- if(cursor>15) cursor-=16;
|
||||
* actualizaCursor(); break; case 39: // --> if(cursor!=(buff.length-1))
|
||||
* cursor++; actualizaCursor(); break; case 40: // -->
|
||||
* if(cursor<(buff.length-16)) cursor+=16; actualizaCursor(); break; }
|
||||
*/
|
||||
}
|
||||
|
||||
private class Columnas extends JPanel
|
||||
{
|
||||
private class Columnas extends JPanel {
|
||||
private static final long serialVersionUID = -1734199617526339842L;
|
||||
|
||||
public Columnas()
|
||||
{
|
||||
this.setLayout(new BorderLayout(1,1));
|
||||
}
|
||||
public Dimension getPreferredSize()
|
||||
{
|
||||
return getMinimumSize();
|
||||
}
|
||||
public Columnas() {
|
||||
this.setLayout(new BorderLayout(1, 1));
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize()
|
||||
{
|
||||
Dimension d=new Dimension();
|
||||
FontMetrics fn=getFontMetrics(font);
|
||||
int h=fn.getHeight();
|
||||
int nl=1;
|
||||
d.setSize(((fn.stringWidth(" ")+1)*+((16*3)-1))+(border*2)+1,h*nl+(border*2)+1);
|
||||
return d;
|
||||
}
|
||||
public Dimension getPreferredSize() {
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
Dimension d=getMinimumSize();
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0,0,d.width,d.height);
|
||||
g.setColor(Color.black);
|
||||
g.setFont(font);
|
||||
public Dimension getMinimumSize() {
|
||||
Dimension d = new Dimension();
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
int h = fn.getHeight();
|
||||
int nl = 1;
|
||||
d.setSize(((fn.stringWidth(" ") + 1) * +((16 * 3) - 1))
|
||||
+ (border * 2) + 1, h * nl + (border * 2) + 1);
|
||||
return d;
|
||||
}
|
||||
|
||||
for(int n=0;n<16;n++)
|
||||
{
|
||||
if(n==(cursor%16)) cuadro(g,n*3,0,2);
|
||||
String s="00"+Integer.toHexString(n);
|
||||
s=s.substring(s.length()-2);
|
||||
printString(g,s,n*3,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void paint(Graphics g) {
|
||||
Dimension d = getMinimumSize();
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0, 0, d.width, d.height);
|
||||
g.setColor(Color.black);
|
||||
g.setFont(font);
|
||||
|
||||
private class Caja extends JPanel
|
||||
{
|
||||
for (int n = 0; n < 16; n++) {
|
||||
if (n == (cursor % 16))
|
||||
cuadro(g, n * 3, 0, 2);
|
||||
String s = "00" + Integer.toHexString(n);
|
||||
s = s.substring(s.length() - 2);
|
||||
printString(g, s, n * 3, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Caja extends JPanel {
|
||||
private static final long serialVersionUID = -6124062720565016834L;
|
||||
|
||||
public Dimension getPreferredSize()
|
||||
{
|
||||
return getMinimumSize();
|
||||
}
|
||||
public Dimension getPreferredSize() {
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize()
|
||||
{
|
||||
Dimension d=new Dimension();
|
||||
FontMetrics fn=getFontMetrics(font);
|
||||
int h=fn.getHeight();
|
||||
d.setSize((fn.stringWidth(" ")+1)+(border*2)+1,h+(border*2)+1);
|
||||
return d;
|
||||
}
|
||||
public Dimension getMinimumSize() {
|
||||
Dimension d = new Dimension();
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
int h = fn.getHeight();
|
||||
d.setSize((fn.stringWidth(" ") + 1) + (border * 2) + 1, h
|
||||
+ (border * 2) + 1);
|
||||
return d;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class Filas extends JPanel
|
||||
{
|
||||
private class Filas extends JPanel {
|
||||
private static final long serialVersionUID = 8797347523486018051L;
|
||||
|
||||
public Filas()
|
||||
{
|
||||
this.setLayout(new BorderLayout(1,1));
|
||||
}
|
||||
public Dimension getPreferredSize()
|
||||
{
|
||||
return getMinimumSize();
|
||||
}
|
||||
public Filas() {
|
||||
this.setLayout(new BorderLayout(1, 1));
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize()
|
||||
{
|
||||
Dimension d=new Dimension();
|
||||
FontMetrics fn=getFontMetrics(font);
|
||||
int h=fn.getHeight();
|
||||
int nl=getLineas();
|
||||
d.setSize((fn.stringWidth(" ")+1)*(8)+(border*2)+1,h*nl+(border*2)+1);
|
||||
return d;
|
||||
}
|
||||
public Dimension getPreferredSize() {
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
Dimension d=getMinimumSize();
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0,0,d.width,d.height);
|
||||
g.setColor(Color.black);
|
||||
g.setFont(font);
|
||||
public Dimension getMinimumSize() {
|
||||
Dimension d = new Dimension();
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
int h = fn.getHeight();
|
||||
int nl = getLineas();
|
||||
d.setSize((fn.stringWidth(" ") + 1) * (8) + (border * 2) + 1, h
|
||||
* nl + (border * 2) + 1);
|
||||
return d;
|
||||
}
|
||||
|
||||
int ini=getInicio();
|
||||
int fin=ini+getLineas();
|
||||
int y=0;
|
||||
for(int n=ini;n<fin;n++)
|
||||
{
|
||||
if(n==(cursor/16)) cuadro(g,0,y,8);
|
||||
String s="0000000000000"+Integer.toHexString(n);
|
||||
s=s.substring(s.length()-8);
|
||||
printString(g,s,0,y++);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void paint(Graphics g) {
|
||||
Dimension d = getMinimumSize();
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0, 0, d.width, d.height);
|
||||
g.setColor(Color.black);
|
||||
g.setFont(font);
|
||||
|
||||
int ini = getInicio();
|
||||
int fin = ini + getLineas();
|
||||
int y = 0;
|
||||
for (int n = ini; n < fin; n++) {
|
||||
if (n == (cursor / 16))
|
||||
cuadro(g, 0, y, 8);
|
||||
String s = "0000000000000" + Integer.toHexString(n);
|
||||
s = s.substring(s.length() - 8);
|
||||
printString(g, s, 0, y++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,148 +5,137 @@ import java.awt.*;
|
|||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: laullon
|
||||
* Date: 09-abr-2003
|
||||
* Time: 12:47:18
|
||||
* Created by IntelliJ IDEA. User: laullon Date: 09-abr-2003 Time: 12:47:18
|
||||
*/
|
||||
public class JHexEditorASCII extends JComponent implements MouseListener,KeyListener
|
||||
{
|
||||
public class JHexEditorASCII extends JComponent implements MouseListener,
|
||||
KeyListener {
|
||||
private static final long serialVersionUID = 5505374841731053461L;
|
||||
private JHexEditor he;
|
||||
|
||||
public JHexEditorASCII(JHexEditor he)
|
||||
{
|
||||
this.he=he;
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
addFocusListener(he);
|
||||
}
|
||||
public JHexEditorASCII(JHexEditor he) {
|
||||
this.he = he;
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
addFocusListener(he);
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize()
|
||||
{
|
||||
debug("getPreferredSize()");
|
||||
return getMinimumSize();
|
||||
}
|
||||
public Dimension getPreferredSize() {
|
||||
debug("getPreferredSize()");
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize()
|
||||
{
|
||||
debug("getMinimumSize()");
|
||||
public Dimension getMinimumSize() {
|
||||
debug("getMinimumSize()");
|
||||
|
||||
Dimension d=new Dimension();
|
||||
FontMetrics fn=getFontMetrics(JHexEditor.font);
|
||||
int h=fn.getHeight();
|
||||
int nl=he.getLineas();
|
||||
d.setSize((fn.stringWidth(" ")+1)*(16)+(he.border*2)+1,h*nl+(he.border*2)+1);
|
||||
return d;
|
||||
}
|
||||
Dimension d = new Dimension();
|
||||
FontMetrics fn = getFontMetrics(JHexEditor.font);
|
||||
int h = fn.getHeight();
|
||||
int nl = he.getLineas();
|
||||
d.setSize((fn.stringWidth(" ") + 1) * (16) + (he.border * 2) + 1, h
|
||||
* nl + (he.border * 2) + 1);
|
||||
return d;
|
||||
}
|
||||
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
debug("paint("+g+")");
|
||||
debug("cursor="+he.cursor+" buff.length="+he.buff.length);
|
||||
Dimension d=getMinimumSize();
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0,0,d.width,d.height);
|
||||
g.setColor(Color.black);
|
||||
public void paint(Graphics g) {
|
||||
debug("paint(" + g + ")");
|
||||
debug("cursor=" + he.cursor + " buff.length=" + he.buff.length);
|
||||
Dimension d = getMinimumSize();
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0, 0, d.width, d.height);
|
||||
g.setColor(Color.black);
|
||||
|
||||
g.setFont(JHexEditor.font);
|
||||
g.setFont(JHexEditor.font);
|
||||
|
||||
//datos ascii
|
||||
int ini=he.getInicio()*16;
|
||||
int fin=ini+(he.getLineas()*16);
|
||||
if(fin>he.buff.length) fin=he.buff.length;
|
||||
// datos ascii
|
||||
int ini = he.getInicio() * 16;
|
||||
int fin = ini + (he.getLineas() * 16);
|
||||
if (fin > he.buff.length)
|
||||
fin = he.buff.length;
|
||||
|
||||
int x=0;
|
||||
int y=0;
|
||||
for(int n=ini;n<fin;n++)
|
||||
{
|
||||
if(n==he.cursor)
|
||||
{
|
||||
g.setColor(Color.blue);
|
||||
if(hasFocus()) he.fondo(g,x,y,1); else he.cuadro(g,x,y,1);
|
||||
if(hasFocus()) g.setColor(Color.white); else g.setColor(Color.black);
|
||||
} else
|
||||
{
|
||||
g.setColor(Color.black);
|
||||
}
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
for (int n = ini; n < fin; n++) {
|
||||
if (n == he.cursor) {
|
||||
g.setColor(Color.blue);
|
||||
if (hasFocus())
|
||||
he.fondo(g, x, y, 1);
|
||||
else
|
||||
he.cuadro(g, x, y, 1);
|
||||
if (hasFocus())
|
||||
g.setColor(Color.white);
|
||||
else
|
||||
g.setColor(Color.black);
|
||||
} else {
|
||||
g.setColor(Color.black);
|
||||
}
|
||||
|
||||
String s=""+new Character((char)he.buff[n]);
|
||||
if((he.buff[n]<20)||(he.buff[n]>126)) s=""+(char)16;
|
||||
he.printString(g,s,(x++),y);
|
||||
if(x==16)
|
||||
{
|
||||
x=0;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
String s = "" + new Character((char) he.buff[n]);
|
||||
if ((he.buff[n] < 20) || (he.buff[n] > 126))
|
||||
s = "" + (char) 16;
|
||||
he.printString(g, s, (x++), y);
|
||||
if (x == 16) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void debug(String s)
|
||||
{
|
||||
if(he.DEBUG) System.out.println("JHexEditorASCII ==> "+s);
|
||||
}
|
||||
private void debug(String s) {
|
||||
if (he.DEBUG)
|
||||
System.out.println("JHexEditorASCII ==> " + s);
|
||||
}
|
||||
|
||||
// calcular la posicion del raton
|
||||
public int calcularPosicionRaton(int x,int y)
|
||||
{
|
||||
FontMetrics fn=getFontMetrics(JHexEditor.font);
|
||||
x=x/(fn.stringWidth(" ")+1);
|
||||
y=y/fn.getHeight();
|
||||
debug("x="+x+" ,y="+y);
|
||||
return x+((y+he.getInicio())*16);
|
||||
}
|
||||
// calcular la posicion del raton
|
||||
public int calcularPosicionRaton(int x, int y) {
|
||||
FontMetrics fn = getFontMetrics(JHexEditor.font);
|
||||
x = x / (fn.stringWidth(" ") + 1);
|
||||
y = y / fn.getHeight();
|
||||
debug("x=" + x + " ,y=" + y);
|
||||
return x + ((y + he.getInicio()) * 16);
|
||||
}
|
||||
|
||||
// mouselistener
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
debug("mouseClicked("+e+")");
|
||||
he.cursor=calcularPosicionRaton(e.getX(),e.getY());
|
||||
this.requestFocus();
|
||||
he.repaint();
|
||||
}
|
||||
// mouselistener
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
debug("mouseClicked(" + e + ")");
|
||||
he.cursor = calcularPosicionRaton(e.getX(), e.getY());
|
||||
this.requestFocus();
|
||||
he.repaint();
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e)
|
||||
{
|
||||
}
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseReleased(MouseEvent e)
|
||||
{
|
||||
}
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseEntered(MouseEvent e)
|
||||
{
|
||||
}
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseExited(MouseEvent e)
|
||||
{
|
||||
}
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
//KeyListener
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
/*debug("keyTyped("+e+")");
|
||||
// KeyListener
|
||||
public void keyTyped(KeyEvent e) {
|
||||
/*
|
||||
* debug("keyTyped("+e+")");
|
||||
*
|
||||
* he.buff[he.cursor]=(byte)e.getKeyChar();
|
||||
*
|
||||
* if(he.cursor!=(he.buff.length-1)) he.cursor++; he.repaint();
|
||||
*/
|
||||
}
|
||||
|
||||
he.buff[he.cursor]=(byte)e.getKeyChar();
|
||||
public void keyPressed(KeyEvent e) {
|
||||
debug("keyPressed(" + e + ")");
|
||||
he.keyPressed(e);
|
||||
}
|
||||
|
||||
if(he.cursor!=(he.buff.length-1)) he.cursor++;
|
||||
he.repaint();*/
|
||||
}
|
||||
public void keyReleased(KeyEvent e) {
|
||||
debug("keyReleased(" + e + ")");
|
||||
}
|
||||
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
debug("keyPressed("+e+")");
|
||||
he.keyPressed(e);
|
||||
}
|
||||
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
debug("keyReleased("+e+")");
|
||||
}
|
||||
|
||||
public boolean isFocusTraversable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public boolean isFocusTraversable() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,174 +5,150 @@ import java.awt.*;
|
|||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: laullon
|
||||
* Date: 09-abr-2003
|
||||
* Time: 12:47:32
|
||||
* Created by IntelliJ IDEA. User: laullon Date: 09-abr-2003 Time: 12:47:32
|
||||
*/
|
||||
public class JHexEditorHEX extends JComponent implements MouseListener,KeyListener
|
||||
{
|
||||
public class JHexEditorHEX extends JComponent implements MouseListener,
|
||||
KeyListener {
|
||||
private static final long serialVersionUID = 1481995655372014571L;
|
||||
private JHexEditor he;
|
||||
private int cursor=0;
|
||||
private int cursor = 0;
|
||||
|
||||
public JHexEditorHEX(JHexEditor he)
|
||||
{
|
||||
this.he=he;
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
addFocusListener(he);
|
||||
}
|
||||
public JHexEditorHEX(JHexEditor he) {
|
||||
this.he = he;
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
addFocusListener(he);
|
||||
}
|
||||
|
||||
/*public Dimension getPreferredSize()
|
||||
{
|
||||
debug("getPreferredSize()");
|
||||
return getMinimumSize();
|
||||
}*/
|
||||
/*
|
||||
* public Dimension getPreferredSize() { debug("getPreferredSize()"); return
|
||||
* getMinimumSize(); }
|
||||
*/
|
||||
|
||||
public Dimension getMaximumSize()
|
||||
{
|
||||
debug("getMaximumSize()");
|
||||
return getMinimumSize();
|
||||
}
|
||||
public Dimension getMaximumSize() {
|
||||
debug("getMaximumSize()");
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
/*public Dimension getMinimumSize()
|
||||
{
|
||||
debug("getMinimumSize()");
|
||||
/*
|
||||
* public Dimension getMinimumSize() { debug("getMinimumSize()");
|
||||
*
|
||||
* Dimension d=new Dimension(); FontMetrics fn=getFontMetrics(he.font); int
|
||||
* h=fn.getHeight(); int nl=he.getLineas();
|
||||
* d.setSize(((fn.stringWidth(" ")+1
|
||||
* )*+((16*3)-1))+(he.border*2)+1,h*nl+(he.border*2)+1); return d; }
|
||||
*/
|
||||
|
||||
Dimension d=new Dimension();
|
||||
FontMetrics fn=getFontMetrics(he.font);
|
||||
int h=fn.getHeight();
|
||||
int nl=he.getLineas();
|
||||
d.setSize(((fn.stringWidth(" ")+1)*+((16*3)-1))+(he.border*2)+1,h*nl+(he.border*2)+1);
|
||||
return d;
|
||||
}*/
|
||||
public void paint(Graphics g) {
|
||||
debug("paint(" + g + ")");
|
||||
debug("cursor=" + he.cursor + " buff.length=" + he.buff.length);
|
||||
Dimension d = getMinimumSize();
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0, 0, d.width, d.height);
|
||||
g.setColor(Color.black);
|
||||
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
debug("paint("+g+")");
|
||||
debug("cursor="+he.cursor+" buff.length="+he.buff.length);
|
||||
Dimension d=getMinimumSize();
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0,0,d.width,d.height);
|
||||
g.setColor(Color.black);
|
||||
g.setFont(JHexEditor.font);
|
||||
|
||||
g.setFont(JHexEditor.font);
|
||||
int ini = he.getInicio() * 16;
|
||||
int fin = ini + (he.getLineas() * 16);
|
||||
if (fin > he.buff.length)
|
||||
fin = he.buff.length;
|
||||
|
||||
int ini=he.getInicio()*16;
|
||||
int fin=ini+(he.getLineas()*16);
|
||||
if(fin>he.buff.length) fin=he.buff.length;
|
||||
// datos hex
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
for (int n = ini; n < fin; n++) {
|
||||
if (n == he.cursor) {
|
||||
if (hasFocus()) {
|
||||
g.setColor(Color.black);
|
||||
he.fondo(g, (x * 3), y, 2);
|
||||
g.setColor(Color.blue);
|
||||
he.fondo(g, (x * 3) + cursor, y, 1);
|
||||
} else {
|
||||
g.setColor(Color.blue);
|
||||
he.cuadro(g, (x * 3), y, 2);
|
||||
}
|
||||
|
||||
//datos hex
|
||||
int x=0;
|
||||
int y=0;
|
||||
for(int n=ini;n<fin;n++)
|
||||
{
|
||||
if(n==he.cursor)
|
||||
{
|
||||
if(hasFocus())
|
||||
{
|
||||
g.setColor(Color.black);
|
||||
he.fondo(g,(x*3),y,2);
|
||||
g.setColor(Color.blue);
|
||||
he.fondo(g,(x*3)+cursor,y,1);
|
||||
} else
|
||||
{
|
||||
g.setColor(Color.blue);
|
||||
he.cuadro(g,(x*3),y,2);
|
||||
}
|
||||
if (hasFocus())
|
||||
g.setColor(Color.white);
|
||||
else
|
||||
g.setColor(Color.black);
|
||||
} else {
|
||||
g.setColor(Color.black);
|
||||
}
|
||||
|
||||
if(hasFocus()) g.setColor(Color.white); else g.setColor(Color.black);
|
||||
} else
|
||||
{
|
||||
g.setColor(Color.black);
|
||||
}
|
||||
String s = ("0" + Integer.toHexString(he.buff[n]));
|
||||
s = s.substring(s.length() - 2);
|
||||
he.printString(g, s, ((x++) * 3), y);
|
||||
if (x == 16) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String s=("0"+Integer.toHexString(he.buff[n]));
|
||||
s=s.substring(s.length()-2);
|
||||
he.printString(g,s,((x++)*3),y);
|
||||
if(x==16)
|
||||
{
|
||||
x=0;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void debug(String s) {
|
||||
if (he.DEBUG)
|
||||
System.out.println("JHexEditorHEX ==> " + s);
|
||||
}
|
||||
|
||||
private void debug(String s)
|
||||
{
|
||||
if(he.DEBUG) System.out.println("JHexEditorHEX ==> "+s);
|
||||
}
|
||||
// calcular la posicion del raton
|
||||
public int calcularPosicionRaton(int x, int y) {
|
||||
FontMetrics fn = getFontMetrics(JHexEditor.font);
|
||||
x = x / ((fn.stringWidth(" ") + 1) * 3);
|
||||
y = y / fn.getHeight();
|
||||
debug("x=" + x + " ,y=" + y);
|
||||
return x + ((y + he.getInicio()) * 16);
|
||||
}
|
||||
|
||||
// calcular la posicion del raton
|
||||
public int calcularPosicionRaton(int x,int y)
|
||||
{
|
||||
FontMetrics fn=getFontMetrics(JHexEditor.font);
|
||||
x=x/((fn.stringWidth(" ")+1)*3);
|
||||
y=y/fn.getHeight();
|
||||
debug("x="+x+" ,y="+y);
|
||||
return x+((y+he.getInicio())*16);
|
||||
}
|
||||
// mouselistener
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
debug("mouseClicked(" + e + ")");
|
||||
he.cursor = calcularPosicionRaton(e.getX(), e.getY());
|
||||
this.requestFocus();
|
||||
he.repaint();
|
||||
}
|
||||
|
||||
// mouselistener
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
debug("mouseClicked("+e+")");
|
||||
he.cursor=calcularPosicionRaton(e.getX(),e.getY());
|
||||
this.requestFocus();
|
||||
he.repaint();
|
||||
}
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e)
|
||||
{
|
||||
}
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseReleased(MouseEvent e)
|
||||
{
|
||||
}
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseEntered(MouseEvent e)
|
||||
{
|
||||
}
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseExited(MouseEvent e)
|
||||
{
|
||||
}
|
||||
// KeyListener
|
||||
public void keyTyped(KeyEvent e) {
|
||||
debug("keyTyped(" + e + ")");
|
||||
|
||||
//KeyListener
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
debug("keyTyped("+e+")");
|
||||
/*
|
||||
* char c=e.getKeyChar();
|
||||
* if(((c>='0')&&(c<='9'))||((c>='A')&&(c<='F'))||((c>='a')&&(c<='f')))
|
||||
* { char[] str=new char[2]; String
|
||||
* n="00"+Integer.toHexString((int)he.buff[he.cursor]); if(n.length()>2)
|
||||
* n=n.substring(n.length()-2); str[1-cursor]=n.charAt(1-cursor);
|
||||
* str[cursor]=e.getKeyChar();
|
||||
* he.buff[he.cursor]=(byte)Integer.parseInt(new String(str),16);
|
||||
*
|
||||
* if(cursor!=1) cursor=1; else if(he.cursor!=(he.buff.length-1)){
|
||||
* he.cursor++; cursor=0;} he.actualizaCursor(); }
|
||||
*/
|
||||
}
|
||||
|
||||
/*char c=e.getKeyChar();
|
||||
if(((c>='0')&&(c<='9'))||((c>='A')&&(c<='F'))||((c>='a')&&(c<='f')))
|
||||
{
|
||||
char[] str=new char[2];
|
||||
String n="00"+Integer.toHexString((int)he.buff[he.cursor]);
|
||||
if(n.length()>2) n=n.substring(n.length()-2);
|
||||
str[1-cursor]=n.charAt(1-cursor);
|
||||
str[cursor]=e.getKeyChar();
|
||||
he.buff[he.cursor]=(byte)Integer.parseInt(new String(str),16);
|
||||
public void keyPressed(KeyEvent e) {
|
||||
debug("keyPressed(" + e + ")");
|
||||
he.keyPressed(e);
|
||||
}
|
||||
|
||||
if(cursor!=1) cursor=1;
|
||||
else if(he.cursor!=(he.buff.length-1)){ he.cursor++; cursor=0;}
|
||||
he.actualizaCursor();
|
||||
}*/
|
||||
}
|
||||
public void keyReleased(KeyEvent e) {
|
||||
debug("keyReleased(" + e + ")");
|
||||
}
|
||||
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
debug("keyPressed("+e+")");
|
||||
he.keyPressed(e);
|
||||
}
|
||||
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
debug("keyReleased("+e+")");
|
||||
}
|
||||
|
||||
public boolean isFocusTraversable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public boolean isFocusTraversable() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,82 +18,85 @@ public class DiskReader {
|
|||
|
||||
public static Random random = new Random();
|
||||
public static HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
|
||||
|
||||
|
||||
/**
|
||||
* Used to load from file, allows caching
|
||||
*/
|
||||
public synchronized static ArrayList<String> loadArrayList(String fileName, boolean cache) {
|
||||
public synchronized static ArrayList<String> loadArrayList(String fileName,
|
||||
boolean cache) {
|
||||
ArrayList<String> array = new ArrayList<String>();
|
||||
if(!map.containsKey(fileName)) {
|
||||
if (!map.containsKey(fileName)) {
|
||||
try {
|
||||
File file = new File(fileName);
|
||||
if(!file.exists()) //doesnt exist, return empty
|
||||
if (!file.exists()) // doesnt exist, return empty
|
||||
return array;
|
||||
|
||||
|
||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||
String add;
|
||||
|
||||
while((add = reader.readLine()) != null)
|
||||
|
||||
while ((add = reader.readLine()) != null)
|
||||
array.add(add);
|
||||
|
||||
|
||||
reader.close();
|
||||
|
||||
if(cache)
|
||||
|
||||
if (cache)
|
||||
map.put(fileName, array);
|
||||
} catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
array = map.get(fileName);
|
||||
}
|
||||
|
||||
|
||||
return array;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to load from file
|
||||
*/
|
||||
public synchronized static String loadAsString(String fileName) throws Exception {
|
||||
public synchronized static String loadAsString(String fileName)
|
||||
throws Exception {
|
||||
String s = "";
|
||||
|
||||
BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));
|
||||
BufferedReader reader = new BufferedReader(new FileReader(new File(
|
||||
fileName)));
|
||||
String add;
|
||||
|
||||
while((add = reader.readLine()) != null)
|
||||
|
||||
while ((add = reader.readLine()) != null)
|
||||
s += add + System.getProperty("line.separator");
|
||||
|
||||
|
||||
reader.close();
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to load a string via line number
|
||||
* lineNumber = -1 means random.
|
||||
* Used to load a string via line number lineNumber = -1 means random.
|
||||
*/
|
||||
public static String loadString(String fileName, int lineNumber, boolean cache) throws Exception {
|
||||
public static String loadString(String fileName, int lineNumber,
|
||||
boolean cache) throws Exception {
|
||||
|
||||
ArrayList<String> array;
|
||||
if(!map.containsKey(fileName)) {
|
||||
if (!map.containsKey(fileName)) {
|
||||
array = new ArrayList<String>();
|
||||
File file = new File(fileName);
|
||||
|
||||
|
||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||
String add;
|
||||
|
||||
while((add = reader.readLine()) != null)
|
||||
|
||||
while ((add = reader.readLine()) != null)
|
||||
array.add(add);
|
||||
|
||||
|
||||
reader.close();
|
||||
|
||||
if(cache)
|
||||
|
||||
if (cache)
|
||||
map.put(fileName, array);
|
||||
} else {
|
||||
array = map.get(fileName);
|
||||
}
|
||||
|
||||
if(lineNumber == -1) {
|
||||
|
||||
if (lineNumber == -1) {
|
||||
int size = array.size();
|
||||
return array.get(random.nextInt(size));
|
||||
} else
|
||||
|
|
|
@ -13,55 +13,64 @@ import java.io.PrintWriter;
|
|||
*/
|
||||
|
||||
public class DiskWriter {
|
||||
|
||||
|
||||
/**
|
||||
* Used to insert a difference string with preserving the file extension
|
||||
* @param fileName The file name
|
||||
* @param difference Normally an integer
|
||||
* @return The filename with the difference inserted and the file extension preserved
|
||||
*
|
||||
* @param fileName
|
||||
* The file name
|
||||
* @param difference
|
||||
* Normally an integer
|
||||
* @return The filename with the difference inserted and the file extension
|
||||
* preserved
|
||||
*/
|
||||
public static String insertFileName(String fileName, String difference) {
|
||||
String[] babe = fileName.split("\\.");
|
||||
int count = 0;
|
||||
int math = babe.length;
|
||||
String m = "";
|
||||
|
||||
for(String s2 : babe) {
|
||||
|
||||
for (String s2 : babe) {
|
||||
m += s2;
|
||||
if(math-2 == count)
|
||||
m += difference+".";
|
||||
else if(math-1 != count)
|
||||
if (math - 2 == count)
|
||||
m += difference + ".";
|
||||
else if (math - 1 != count)
|
||||
m += ".";
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes a new line to the file, if it doesn't exist it will automatically create it.
|
||||
* Writes a new line to the file, if it doesn't exist it will automatically
|
||||
* create it.
|
||||
*
|
||||
* @param filename
|
||||
* @param fileContents
|
||||
* @param debug
|
||||
*/
|
||||
public static synchronized void writeNewLine(String filename, byte[] fileContents, boolean debug) {
|
||||
public static synchronized void writeNewLine(String filename,
|
||||
byte[] fileContents, boolean debug) {
|
||||
PrintWriter writer = null;
|
||||
String original = filename;
|
||||
int counter = 0;
|
||||
|
||||
|
||||
boolean saved = false;
|
||||
while(!saved) {
|
||||
while (!saved) {
|
||||
try {
|
||||
writer = new PrintWriter(new BufferedWriter(new FileWriter(filename, true)));
|
||||
writer = new PrintWriter(new BufferedWriter(new FileWriter(
|
||||
filename, true)));
|
||||
writer.println(fileContents);
|
||||
if(debug)
|
||||
if (debug)
|
||||
System.out.println("Saved " + filename + " to disk");
|
||||
saved = true;
|
||||
} catch(Exception e) {
|
||||
if(debug)
|
||||
System.out.println("Failed saving, trying to save as " + filename);
|
||||
if(original.contains(".")) {
|
||||
filename = insertFileName(original, ""+counter);
|
||||
} catch (Exception e) {
|
||||
if (debug)
|
||||
System.out.println("Failed saving, trying to save as "
|
||||
+ filename);
|
||||
if (original.contains(".")) {
|
||||
filename = insertFileName(original, "" + counter);
|
||||
} else
|
||||
filename = original + counter;
|
||||
counter++;
|
||||
|
@ -69,31 +78,36 @@ public class DiskWriter {
|
|||
}
|
||||
writer.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes a string to the file
|
||||
*
|
||||
* @param filename
|
||||
* @param lineToWrite
|
||||
* @param debug
|
||||
*/
|
||||
public static synchronized void writeNewLine(String filename, String lineToWrite, boolean debug) {
|
||||
public static synchronized void writeNewLine(String filename,
|
||||
String lineToWrite, boolean debug) {
|
||||
PrintWriter writer = null;
|
||||
String original = filename;
|
||||
int counter = 0;
|
||||
|
||||
|
||||
boolean saved = false;
|
||||
while(!saved) {
|
||||
while (!saved) {
|
||||
try {
|
||||
writer = new PrintWriter(new BufferedWriter(new FileWriter(filename, true)));
|
||||
writer = new PrintWriter(new BufferedWriter(new FileWriter(
|
||||
filename, true)));
|
||||
writer.println(lineToWrite);
|
||||
if(debug)
|
||||
System.out.println("Saved " + filename+">"+lineToWrite + " to disk");
|
||||
if (debug)
|
||||
System.out.println("Saved " + filename + ">" + lineToWrite
|
||||
+ " to disk");
|
||||
saved = true;
|
||||
} catch(Exception e) {
|
||||
if(debug)
|
||||
System.out.println("Failed saving, trying to save as " + filename);
|
||||
if(original.contains(".")) {
|
||||
filename = insertFileName(original, ""+counter);
|
||||
} catch (Exception e) {
|
||||
if (debug)
|
||||
System.out.println("Failed saving, trying to save as "
|
||||
+ filename);
|
||||
if (original.contains(".")) {
|
||||
filename = insertFileName(original, "" + counter);
|
||||
} else
|
||||
filename = original + counter;
|
||||
counter++;
|
||||
|
@ -101,34 +115,39 @@ public class DiskWriter {
|
|||
}
|
||||
writer.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes the original file if it exists, then writes the fileContents[] to the file.
|
||||
* Deletes the original file if it exists, then writes the fileContents[] to
|
||||
* the file.
|
||||
*
|
||||
* @param filename
|
||||
* @param fileContents
|
||||
* @param debug
|
||||
*/
|
||||
public static synchronized void replaceFile(String filename, byte[] fileContents, boolean debug) {
|
||||
public static synchronized void replaceFile(String filename,
|
||||
byte[] fileContents, boolean debug) {
|
||||
File f = new File(filename);
|
||||
if(f.exists())
|
||||
if (f.exists())
|
||||
f.delete();
|
||||
PrintWriter writer = null;
|
||||
String original = filename;
|
||||
int counter = 0;
|
||||
|
||||
|
||||
boolean saved = false;
|
||||
while(!saved) {
|
||||
while (!saved) {
|
||||
try {
|
||||
writer = new PrintWriter(new BufferedWriter(new FileWriter(filename, true)));
|
||||
writer = new PrintWriter(new BufferedWriter(new FileWriter(
|
||||
filename, true)));
|
||||
writer.println(fileContents);
|
||||
if(debug)
|
||||
if (debug)
|
||||
System.out.println("Saved " + filename + " to disk");
|
||||
saved = true;
|
||||
} catch(Exception e) {
|
||||
if(debug)
|
||||
System.out.println("Failed saving, trying to save as " + filename);
|
||||
if(original.contains(".")) {
|
||||
filename = insertFileName(original, ""+counter);
|
||||
} catch (Exception e) {
|
||||
if (debug)
|
||||
System.out.println("Failed saving, trying to save as "
|
||||
+ filename);
|
||||
if (original.contains(".")) {
|
||||
filename = insertFileName(original, "" + counter);
|
||||
} else
|
||||
filename = original + counter;
|
||||
counter++;
|
||||
|
@ -136,34 +155,40 @@ public class DiskWriter {
|
|||
}
|
||||
writer.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes the original file if it exists, then writes the lineToWrite to the file.
|
||||
* Deletes the original file if it exists, then writes the lineToWrite to
|
||||
* the file.
|
||||
*
|
||||
* @param filename
|
||||
* @param lineToWrite
|
||||
* @param debug
|
||||
*/
|
||||
public static synchronized void replaceFile(String filename, String lineToWrite, boolean debug) {
|
||||
public static synchronized void replaceFile(String filename,
|
||||
String lineToWrite, boolean debug) {
|
||||
File f = new File(filename);
|
||||
if(f.exists())
|
||||
if (f.exists())
|
||||
f.delete();
|
||||
PrintWriter writer = null;
|
||||
String original = filename;
|
||||
int counter = 0;
|
||||
|
||||
|
||||
boolean saved = false;
|
||||
while(!saved) {
|
||||
while (!saved) {
|
||||
try {
|
||||
writer = new PrintWriter(new BufferedWriter(new FileWriter(filename, true)));
|
||||
writer = new PrintWriter(new BufferedWriter(new FileWriter(
|
||||
filename, true)));
|
||||
writer.println(lineToWrite);
|
||||
if(debug)
|
||||
System.out.println("Saved " + filename+">"+lineToWrite + " to disk");
|
||||
if (debug)
|
||||
System.out.println("Saved " + filename + ">" + lineToWrite
|
||||
+ " to disk");
|
||||
saved = true;
|
||||
} catch(Exception e) {
|
||||
if(debug)
|
||||
System.out.println("Failed saving, trying to save as " + filename + "_");
|
||||
if(original.contains(".")) {
|
||||
filename = insertFileName(original, ""+counter);
|
||||
} catch (Exception e) {
|
||||
if (debug)
|
||||
System.out.println("Failed saving, trying to save as "
|
||||
+ filename + "_");
|
||||
if (original.contains(".")) {
|
||||
filename = insertFileName(original, "" + counter);
|
||||
} else
|
||||
filename = original + counter;
|
||||
counter++;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -6,9 +6,9 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
* Used to represent whenever a file has been opened
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public interface FileChangeNotifier {
|
||||
public void openClassFile(String name, ClassNode cn);
|
||||
public void openClassFile(String name, ClassNode cn);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,113 +23,126 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class JarUtils {
|
||||
|
||||
|
||||
private static JarInputStream jis;
|
||||
private static JarEntry entry;
|
||||
public static void put(final File jarFile, final HashMap<String, ClassNode> clazzList) throws IOException {
|
||||
jis = new JarInputStream(new FileInputStream(jarFile));
|
||||
while ((entry = jis.getNextJarEntry()) != null) {
|
||||
final String name = entry.getName();
|
||||
if (!name.endsWith(".class")) {
|
||||
BytecodeViewer.loadedResources.put(name, getBytes(jis));
|
||||
jis.closeEntry();
|
||||
continue;
|
||||
}
|
||||
|
||||
final ClassNode cn = getNode(getBytes(jis));
|
||||
clazzList.put(cn.name, cn);
|
||||
public static void put(final File jarFile,
|
||||
final HashMap<String, ClassNode> clazzList) throws IOException {
|
||||
jis = new JarInputStream(new FileInputStream(jarFile));
|
||||
while ((entry = jis.getNextJarEntry()) != null) {
|
||||
final String name = entry.getName();
|
||||
if (!name.endsWith(".class")) {
|
||||
BytecodeViewer.loadedResources.put(name, getBytes(jis));
|
||||
jis.closeEntry();
|
||||
continue;
|
||||
}
|
||||
|
||||
jis.closeEntry();
|
||||
}
|
||||
jis.close();
|
||||
final ClassNode cn = getNode(getBytes(jis));
|
||||
clazzList.put(cn.name, cn);
|
||||
|
||||
}
|
||||
jis.closeEntry();
|
||||
}
|
||||
jis.close();
|
||||
|
||||
private static ByteArrayOutputStream baos = null;
|
||||
private static byte[] buffer = null;
|
||||
private static int a = 0;
|
||||
public static byte[] getBytes(final InputStream is) throws IOException {
|
||||
baos = new ByteArrayOutputStream();
|
||||
buffer = new byte[1024];
|
||||
a = 0;
|
||||
while ((a = is.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, a);
|
||||
}
|
||||
baos.close();
|
||||
buffer = null;
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
private static ClassReader cr = null;
|
||||
private static ClassNode cn = null;
|
||||
public static ClassNode getNode(final byte[] bytez) {
|
||||
cr = new ClassReader(bytez);
|
||||
cn = new ClassNode();
|
||||
cr.accept(cn, ClassReader.EXPAND_FRAMES);
|
||||
cr = null;
|
||||
return cn;
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveAsJar(ArrayList<ClassNode> nodeList, String path, String manifest) {
|
||||
private static ByteArrayOutputStream baos = null;
|
||||
private static byte[] buffer = null;
|
||||
private static int a = 0;
|
||||
|
||||
public static byte[] getBytes(final InputStream is) throws IOException {
|
||||
baos = new ByteArrayOutputStream();
|
||||
buffer = new byte[1024];
|
||||
a = 0;
|
||||
while ((a = is.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, a);
|
||||
}
|
||||
baos.close();
|
||||
buffer = null;
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
private static ClassReader cr = null;
|
||||
private static ClassNode cn = null;
|
||||
|
||||
public static ClassNode getNode(final byte[] bytez) {
|
||||
cr = new ClassReader(bytez);
|
||||
cn = new ClassNode();
|
||||
try {
|
||||
JarOutputStream out = new JarOutputStream(new FileOutputStream(path));
|
||||
cr.accept(cn, ClassReader.EXPAND_FRAMES);
|
||||
} catch (Exception e) {
|
||||
cr.accept(cn, ClassReader.SKIP_FRAMES);
|
||||
}
|
||||
cr = null;
|
||||
return cn;
|
||||
}
|
||||
|
||||
public static void saveAsJar(ArrayList<ClassNode> nodeList, String path,
|
||||
String manifest) {
|
||||
try {
|
||||
JarOutputStream out = new JarOutputStream(
|
||||
new FileOutputStream(path));
|
||||
for (ClassNode cn : nodeList) {
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
cn.accept(cw);
|
||||
|
||||
|
||||
out.putNextEntry(new ZipEntry(cn.name + ".class"));
|
||||
out.write(cw.toByteArray());
|
||||
out.closeEntry();
|
||||
}
|
||||
|
||||
|
||||
out.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
|
||||
out.write((manifest.trim()+"\r\n\r\n").getBytes());
|
||||
out.write((manifest.trim() + "\r\n\r\n").getBytes());
|
||||
out.closeEntry();
|
||||
|
||||
for (Entry<String, byte[]> entry : BytecodeViewer.loadedResources.entrySet()) {
|
||||
for (Entry<String, byte[]> entry : BytecodeViewer.loadedResources
|
||||
.entrySet()) {
|
||||
String filename = entry.getKey();
|
||||
if(!filename.startsWith("META-INF")) {
|
||||
if (!filename.startsWith("META-INF")) {
|
||||
out.putNextEntry(new ZipEntry(filename));
|
||||
out.write(entry.getValue());
|
||||
out.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void saveAsJar(ArrayList<ClassNode> nodeList, String path) {
|
||||
try {
|
||||
JarOutputStream out = new JarOutputStream(new FileOutputStream(path));
|
||||
JarOutputStream out = new JarOutputStream(
|
||||
new FileOutputStream(path));
|
||||
for (ClassNode cn : nodeList) {
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
cn.accept(cw);
|
||||
|
||||
|
||||
out.putNextEntry(new ZipEntry(cn.name + ".class"));
|
||||
out.write(cw.toByteArray());
|
||||
out.closeEntry();
|
||||
}
|
||||
|
||||
for (Entry<String, byte[]> entry : BytecodeViewer.loadedResources.entrySet()) {
|
||||
for (Entry<String, byte[]> entry : BytecodeViewer.loadedResources
|
||||
.entrySet()) {
|
||||
String filename = entry.getKey();
|
||||
if(!filename.startsWith("META-INF")) {
|
||||
if (!filename.startsWith("META-INF")) {
|
||||
out.putNextEntry(new ZipEntry(filename));
|
||||
out.write(entry.getValue());
|
||||
out.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -5,130 +5,103 @@ import java.io.IOException;
|
|||
import the.bytecode.club.bytecodeviewer.plugins.EZInjection;
|
||||
|
||||
public class RuntimeOverride {
|
||||
private static RuntimeOverride currentRuntime = new RuntimeOverride();
|
||||
private static RuntimeOverride currentRuntime = new RuntimeOverride();
|
||||
|
||||
public static RuntimeOverride getRuntime() {
|
||||
return currentRuntime;
|
||||
}
|
||||
public static RuntimeOverride getRuntime() {
|
||||
return currentRuntime;
|
||||
}
|
||||
|
||||
public void exit(int status) {
|
||||
if(EZInjection.sandboxSystem) {
|
||||
EZInjection.exitR(status);
|
||||
} else {
|
||||
Runtime.getRuntime().exit(status);
|
||||
}
|
||||
}
|
||||
public void exit(int status) {
|
||||
if (EZInjection.sandboxSystem) {
|
||||
EZInjection.exitR(status);
|
||||
} else {
|
||||
Runtime.getRuntime().exit(status);
|
||||
}
|
||||
}
|
||||
|
||||
public void addShutdownHook(Thread hook) {
|
||||
Runtime.getRuntime().addShutdownHook(hook);
|
||||
}
|
||||
public void addShutdownHook(Thread hook) {
|
||||
Runtime.getRuntime().addShutdownHook(hook);
|
||||
}
|
||||
|
||||
public boolean removeShutdownHook(Thread hook) {
|
||||
return Runtime.getRuntime().removeShutdownHook(hook);
|
||||
}
|
||||
public boolean removeShutdownHook(Thread hook) {
|
||||
return Runtime.getRuntime().removeShutdownHook(hook);
|
||||
}
|
||||
|
||||
public void halt(int status) {
|
||||
Runtime.getRuntime().halt(status);
|
||||
}
|
||||
|
||||
public Process exec(String command) throws IOException {
|
||||
if(EZInjection.sandboxSystem) {
|
||||
EZInjection.announceSystem(command);
|
||||
return null;
|
||||
} else {
|
||||
return Runtime.getRuntime().exec(command);
|
||||
}
|
||||
}
|
||||
public void halt(int status) {
|
||||
Runtime.getRuntime().halt(status);
|
||||
}
|
||||
|
||||
/*public Process exec(String command, String[] envp) throws IOException {
|
||||
return exec(command, envp, null);
|
||||
}
|
||||
|
||||
public Process exec(String command, String[] envp, File dir)
|
||||
throws IOException {
|
||||
if (command.length() == 0)
|
||||
throw new IllegalArgumentException("Empty command");
|
||||
public Process exec(String command) throws IOException {
|
||||
if (EZInjection.sandboxSystem) {
|
||||
EZInjection.announceSystem(command);
|
||||
return null;
|
||||
} else {
|
||||
return Runtime.getRuntime().exec(command);
|
||||
}
|
||||
}
|
||||
|
||||
StringTokenizer st = new StringTokenizer(command);
|
||||
String[] cmdarray = new String[st.countTokens()];
|
||||
for (int i = 0; st.hasMoreTokens(); i++)
|
||||
cmdarray[i] = st.nextToken();
|
||||
return exec(cmdarray, envp, dir);
|
||||
}
|
||||
|
||||
public Process exec(String cmdarray[]) throws IOException {
|
||||
return exec(cmdarray, null, null);
|
||||
}
|
||||
|
||||
public Process exec(String[] cmdarray, String[] envp) throws IOException {
|
||||
return exec(cmdarray, envp, null);
|
||||
}
|
||||
|
||||
public Process exec(String[] cmdarray, String[] envp, File dir)
|
||||
throws IOException {
|
||||
return new ProcessBuilder(cmdarray)
|
||||
.environment(envp)
|
||||
.directory(dir)
|
||||
.start();
|
||||
}
|
||||
|
||||
public native int availableProcessors();
|
||||
|
||||
public native long freeMemory();
|
||||
|
||||
public native long totalMemory();
|
||||
|
||||
public native long maxMemory();
|
||||
|
||||
public void gc() {
|
||||
Runtime.getRuntime().gc();
|
||||
}
|
||||
|
||||
public void runFinalization() {
|
||||
Runtime.getRuntime().runFinalization();
|
||||
}
|
||||
|
||||
public native void traceInstructions(boolean on);
|
||||
|
||||
public native void traceMethodCalls(boolean on);
|
||||
|
||||
public void load(String filename) {
|
||||
load0(Reflection.getCallerClass(), filename);
|
||||
}
|
||||
|
||||
synchronized void load0(Class fromClass, String filename) {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkLink(filename);
|
||||
}
|
||||
if (!(new File(filename).isAbsolute())) {
|
||||
throw new UnsatisfiedLinkError(
|
||||
"Expecting an absolute path of the library: " + filename);
|
||||
}
|
||||
ClassLoader.loadLibrary(fromClass, filename, true);
|
||||
}
|
||||
|
||||
public void loadLibrary(String libname) {
|
||||
loadLibrary0(Reflection.getCallerClass(), libname);
|
||||
}
|
||||
|
||||
synchronized void loadLibrary0(Class fromClass, String libname) {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkLink(libname);
|
||||
}
|
||||
if (libname.indexOf((int)File.separatorChar) != -1) {
|
||||
throw new UnsatisfiedLinkError(
|
||||
"Directory separator should not appear in library name: " + libname);
|
||||
}
|
||||
ClassLoader.loadLibrary(fromClass, libname, false);
|
||||
}
|
||||
|
||||
public InputStream getLocalizedInputStream(InputStream in) {
|
||||
return in;
|
||||
}
|
||||
|
||||
public OutputStream getLocalizedOutputStream(OutputStream out) {
|
||||
return out;
|
||||
}*/
|
||||
/*
|
||||
* public Process exec(String command, String[] envp) throws IOException {
|
||||
* return exec(command, envp, null); }
|
||||
*
|
||||
* public Process exec(String command, String[] envp, File dir) throws
|
||||
* IOException { if (command.length() == 0) throw new
|
||||
* IllegalArgumentException("Empty command");
|
||||
*
|
||||
* StringTokenizer st = new StringTokenizer(command); String[] cmdarray =
|
||||
* new String[st.countTokens()]; for (int i = 0; st.hasMoreTokens(); i++)
|
||||
* cmdarray[i] = st.nextToken(); return exec(cmdarray, envp, dir); }
|
||||
*
|
||||
* public Process exec(String cmdarray[]) throws IOException { return
|
||||
* exec(cmdarray, null, null); }
|
||||
*
|
||||
* public Process exec(String[] cmdarray, String[] envp) throws IOException
|
||||
* { return exec(cmdarray, envp, null); }
|
||||
*
|
||||
* public Process exec(String[] cmdarray, String[] envp, File dir) throws
|
||||
* IOException { return new ProcessBuilder(cmdarray) .environment(envp)
|
||||
* .directory(dir) .start(); }
|
||||
*
|
||||
* public native int availableProcessors();
|
||||
*
|
||||
* public native long freeMemory();
|
||||
*
|
||||
* public native long totalMemory();
|
||||
*
|
||||
* public native long maxMemory();
|
||||
*
|
||||
* public void gc() { Runtime.getRuntime().gc(); }
|
||||
*
|
||||
* public void runFinalization() { Runtime.getRuntime().runFinalization(); }
|
||||
*
|
||||
* public native void traceInstructions(boolean on);
|
||||
*
|
||||
* public native void traceMethodCalls(boolean on);
|
||||
*
|
||||
* public void load(String filename) { load0(Reflection.getCallerClass(),
|
||||
* filename); }
|
||||
*
|
||||
* synchronized void load0(Class fromClass, String filename) {
|
||||
* SecurityManager security = System.getSecurityManager(); if (security !=
|
||||
* null) { security.checkLink(filename); } if (!(new
|
||||
* File(filename).isAbsolute())) { throw new UnsatisfiedLinkError(
|
||||
* "Expecting an absolute path of the library: " + filename); }
|
||||
* ClassLoader.loadLibrary(fromClass, filename, true); }
|
||||
*
|
||||
* public void loadLibrary(String libname) {
|
||||
* loadLibrary0(Reflection.getCallerClass(), libname); }
|
||||
*
|
||||
* synchronized void loadLibrary0(Class fromClass, String libname) {
|
||||
* SecurityManager security = System.getSecurityManager(); if (security !=
|
||||
* null) { security.checkLink(libname); } if
|
||||
* (libname.indexOf((int)File.separatorChar) != -1) { throw new
|
||||
* UnsatisfiedLinkError(
|
||||
* "Directory separator should not appear in library name: " + libname); }
|
||||
* ClassLoader.loadLibrary(fromClass, libname, false); }
|
||||
*
|
||||
* public InputStream getLocalizedInputStream(InputStream in) { return in; }
|
||||
*
|
||||
* public OutputStream getLocalizedOutputStream(OutputStream out) { return
|
||||
* out; }
|
||||
*/
|
||||
}
|
|
@ -14,175 +14,187 @@ import javax.swing.filechooser.FileFilter;
|
|||
*/
|
||||
public final class ZipUtils {
|
||||
|
||||
private static final String ZIP_FILE_EXTENSION = ".zip";
|
||||
private static final FileFilter ZIP_FILE_FILTER = new FileFilter() {
|
||||
private static final String ZIP_FILE_EXTENSION = ".zip";
|
||||
private static final FileFilter ZIP_FILE_FILTER = new FileFilter() {
|
||||
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.getName().endsWith(ZIP_FILE_EXTENSION);
|
||||
}
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.getName().endsWith(ZIP_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
private ZipUtils() {
|
||||
// Utility class, cannot be instantiated.
|
||||
}
|
||||
private ZipUtils() {
|
||||
// Utility class, cannot be instantiated.
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the given root and all its underlying folders and files to the target file, preserving files hierarchy.
|
||||
*
|
||||
* @param root
|
||||
* The root of the Zip archive
|
||||
* @param target
|
||||
* The target archive file (must be a valid Zip file name)
|
||||
* @throws IOException
|
||||
* If an error occurs during the process
|
||||
*/
|
||||
public static void zipDirectory(final File root, final File target) throws IOException {
|
||||
if (!ZIP_FILE_FILTER.accept(target)) {
|
||||
throw new IllegalArgumentException("Target file " + target.getName() + " is not a valid Zip file name");
|
||||
}
|
||||
/**
|
||||
* Compress the given root and all its underlying folders and files to the
|
||||
* target file, preserving files hierarchy.
|
||||
*
|
||||
* @param root
|
||||
* The root of the Zip archive
|
||||
* @param target
|
||||
* The target archive file (must be a valid Zip file name)
|
||||
* @throws IOException
|
||||
* If an error occurs during the process
|
||||
*/
|
||||
public static void zipDirectory(final File root, final File target)
|
||||
throws IOException {
|
||||
if (!ZIP_FILE_FILTER.accept(target)) {
|
||||
throw new IllegalArgumentException("Target file "
|
||||
+ target.getName() + " is not a valid Zip file name");
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
FileOutputStream fileOutputStream = null;
|
||||
ZipOutputStream zipOutputStream = null;
|
||||
byte[] buffer = new byte[1024];
|
||||
FileOutputStream fileOutputStream = null;
|
||||
ZipOutputStream zipOutputStream = null;
|
||||
|
||||
try {
|
||||
fileOutputStream = new FileOutputStream(target);
|
||||
zipOutputStream = new ZipOutputStream(fileOutputStream);
|
||||
try {
|
||||
fileOutputStream = new FileOutputStream(target);
|
||||
zipOutputStream = new ZipOutputStream(fileOutputStream);
|
||||
|
||||
FileInputStream fileInputStream = null;
|
||||
FileInputStream fileInputStream = null;
|
||||
|
||||
for (File file : ZipUtils.listFilesRecursive(root)) {
|
||||
ZipEntry entry = new ZipEntry(ZipUtils.stripRootInclusive(file, root).getPath());
|
||||
zipOutputStream.putNextEntry(entry);
|
||||
try {
|
||||
fileInputStream = new FileInputStream(file);
|
||||
int length;
|
||||
while ((length = fileInputStream.read(buffer)) > 0) {
|
||||
zipOutputStream.write(buffer, 0, length);
|
||||
}
|
||||
} finally {
|
||||
fileInputStream.close();
|
||||
}
|
||||
for (File file : ZipUtils.listFilesRecursive(root)) {
|
||||
ZipEntry entry = new ZipEntry(ZipUtils.stripRootInclusive(file,
|
||||
root).getPath());
|
||||
zipOutputStream.putNextEntry(entry);
|
||||
try {
|
||||
fileInputStream = new FileInputStream(file);
|
||||
int length;
|
||||
while ((length = fileInputStream.read(buffer)) > 0) {
|
||||
zipOutputStream.write(buffer, 0, length);
|
||||
}
|
||||
} finally {
|
||||
fileInputStream.close();
|
||||
}
|
||||
|
||||
zipOutputStream.closeEntry();
|
||||
}
|
||||
} finally {
|
||||
zipOutputStream.close();
|
||||
}
|
||||
}
|
||||
zipOutputStream.closeEntry();
|
||||
}
|
||||
} finally {
|
||||
zipOutputStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unzip the given archive Zip file to the target location. If target location is a file, the extraction will be
|
||||
* performed in the same directory of this target file.
|
||||
*
|
||||
* @param zipFile
|
||||
* The Zip archive file
|
||||
* @param target
|
||||
* The target location
|
||||
* @throws IOException
|
||||
* If an error occurs during the process
|
||||
*/
|
||||
public static void unzip(final File zipFile, File target) throws IOException {
|
||||
if (zipFile == null) {
|
||||
throw new IllegalArgumentException("Cannot unzip a null file!");
|
||||
} else if (!ZIP_FILE_FILTER.accept(zipFile)) {
|
||||
throw new IllegalArgumentException("Given archive is not a valid Zip file!");
|
||||
}
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException("Cannot unzip to a null target!");
|
||||
}
|
||||
/**
|
||||
* Unzip the given archive Zip file to the target location. If target
|
||||
* location is a file, the extraction will be performed in the same
|
||||
* directory of this target file.
|
||||
*
|
||||
* @param zipFile
|
||||
* The Zip archive file
|
||||
* @param target
|
||||
* The target location
|
||||
* @throws IOException
|
||||
* If an error occurs during the process
|
||||
*/
|
||||
public static void unzip(final File zipFile, File target)
|
||||
throws IOException {
|
||||
if (zipFile == null) {
|
||||
throw new IllegalArgumentException("Cannot unzip a null file!");
|
||||
} else if (!ZIP_FILE_FILTER.accept(zipFile)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Given archive is not a valid Zip file!");
|
||||
}
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException("Cannot unzip to a null target!");
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
if (!target.exists()) {
|
||||
target.mkdir();
|
||||
} else if (target.isFile()) {
|
||||
// Target is a file, will try to unzip in the same folder.
|
||||
target = target.getParentFile();
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException("Target is a file and has no parent!");
|
||||
}
|
||||
}
|
||||
if (!target.exists()) {
|
||||
target.mkdir();
|
||||
} else if (target.isFile()) {
|
||||
// Target is a file, will try to unzip in the same folder.
|
||||
target = target.getParentFile();
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Target is a file and has no parent!");
|
||||
}
|
||||
}
|
||||
|
||||
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile));
|
||||
try {
|
||||
for (ZipEntry entry = zipInputStream.getNextEntry(); entry != null; entry = zipInputStream.getNextEntry()) {
|
||||
File file = new File(target, entry.getName());
|
||||
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(
|
||||
zipFile));
|
||||
try {
|
||||
for (ZipEntry entry = zipInputStream.getNextEntry(); entry != null; entry = zipInputStream
|
||||
.getNextEntry()) {
|
||||
File file = new File(target, entry.getName());
|
||||
|
||||
// Create parent folders (folders are not in the Zip entries).
|
||||
new File(file.getParent()).mkdirs();
|
||||
// Create parent folders (folders are not in the Zip entries).
|
||||
new File(file.getParent()).mkdirs();
|
||||
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(file);
|
||||
try {
|
||||
int length;
|
||||
while ((length = zipInputStream.read(buffer)) > 0) {
|
||||
fileOutputStream.write(buffer, 0, length);
|
||||
}
|
||||
} finally {
|
||||
fileOutputStream.close();
|
||||
}
|
||||
zipInputStream.closeEntry();
|
||||
}
|
||||
} finally {
|
||||
zipInputStream.close();
|
||||
}
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(file);
|
||||
try {
|
||||
int length;
|
||||
while ((length = zipInputStream.read(buffer)) > 0) {
|
||||
fileOutputStream.write(buffer, 0, length);
|
||||
}
|
||||
} finally {
|
||||
fileOutputStream.close();
|
||||
}
|
||||
zipInputStream.closeEntry();
|
||||
}
|
||||
} finally {
|
||||
zipInputStream.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List all files and folders from the given root.
|
||||
*
|
||||
* @param root
|
||||
* The root of the listing
|
||||
* @return A list of the files under the given root
|
||||
*/
|
||||
public static List<File> listFilesRecursive(final File root) {
|
||||
List<File> packedFiles = new ArrayList<File>();
|
||||
/**
|
||||
* List all files and folders from the given root.
|
||||
*
|
||||
* @param root
|
||||
* The root of the listing
|
||||
* @return A list of the files under the given root
|
||||
*/
|
||||
public static List<File> listFilesRecursive(final File root) {
|
||||
List<File> packedFiles = new ArrayList<File>();
|
||||
|
||||
File[] subFiles = root.listFiles();
|
||||
if (subFiles == null) {
|
||||
return packedFiles;
|
||||
}
|
||||
File[] subFiles = root.listFiles();
|
||||
if (subFiles == null) {
|
||||
return packedFiles;
|
||||
}
|
||||
|
||||
for (File file : subFiles) {
|
||||
if (file.isFile()) {
|
||||
File packedFile = new File(root, file.getName());
|
||||
packedFiles.add(packedFile);
|
||||
} else if (file.isDirectory()) {
|
||||
packedFiles.addAll(ZipUtils.listFilesRecursive(file));
|
||||
}
|
||||
}
|
||||
for (File file : subFiles) {
|
||||
if (file.isFile()) {
|
||||
File packedFile = new File(root, file.getName());
|
||||
packedFiles.add(packedFile);
|
||||
} else if (file.isDirectory()) {
|
||||
packedFiles.addAll(ZipUtils.listFilesRecursive(file));
|
||||
}
|
||||
}
|
||||
|
||||
return packedFiles;
|
||||
}
|
||||
return packedFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip the given file from any parent path, preserving the root as the absolute parent.
|
||||
* <p>
|
||||
* Ex. with 'Folder' as the root: /home/johnj/Test/Folder/File.txt => /Folder/File.txt
|
||||
* </p>
|
||||
*
|
||||
* @param file
|
||||
* The file to strip
|
||||
* @param root
|
||||
* The root of the stripping
|
||||
* @return The stripped file
|
||||
*/
|
||||
private static File stripRootInclusive(final File file, final File root) {
|
||||
String parentPath = root.getParent();
|
||||
/**
|
||||
* Strip the given file from any parent path, preserving the root as the
|
||||
* absolute parent.
|
||||
* <p>
|
||||
* Ex. with 'Folder' as the root: /home/johnj/Test/Folder/File.txt =>
|
||||
* /Folder/File.txt
|
||||
* </p>
|
||||
*
|
||||
* @param file
|
||||
* The file to strip
|
||||
* @param root
|
||||
* The root of the stripping
|
||||
* @return The stripped file
|
||||
*/
|
||||
private static File stripRootInclusive(final File file, final File root) {
|
||||
String parentPath = root.getParent();
|
||||
|
||||
if (parentPath == null) {
|
||||
// Assuming no existing parent.
|
||||
return file;
|
||||
}
|
||||
if (parentPath == null) {
|
||||
// Assuming no existing parent.
|
||||
return file;
|
||||
}
|
||||
|
||||
return new File(file.getAbsolutePath().substring(parentPath.length()));
|
||||
}
|
||||
return new File(file.getAbsolutePath().substring(parentPath.length()));
|
||||
}
|
||||
}
|
|
@ -18,29 +18,28 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|||
* Used to rename/replace methods/classes/fields
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
public final class ASMUtil_OLD {
|
||||
|
||||
public static void renameFieldNode(String originalParentName, String originalFieldName,
|
||||
String originalFieldDesc, String newFieldParent, String newFieldName, String newFieldDesc)
|
||||
{
|
||||
for(ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
for(Object o : c.methods.toArray()) {
|
||||
MethodNode m = (MethodNode)o;
|
||||
for(AbstractInsnNode i : m.instructions.toArray()) {
|
||||
if(i instanceof FieldInsnNode) {
|
||||
FieldInsnNode field = (FieldInsnNode)i;
|
||||
|
||||
if(field.owner.equals(originalParentName) &&
|
||||
field.name.equals(originalFieldName) &&
|
||||
field.desc.equals(originalFieldDesc))
|
||||
{
|
||||
if(newFieldParent != null)
|
||||
|
||||
public static void renameFieldNode(String originalParentName,
|
||||
String originalFieldName, String originalFieldDesc,
|
||||
String newFieldParent, String newFieldName, String newFieldDesc) {
|
||||
for (ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
for (Object o : c.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
for (AbstractInsnNode i : m.instructions.toArray()) {
|
||||
if (i instanceof FieldInsnNode) {
|
||||
FieldInsnNode field = (FieldInsnNode) i;
|
||||
|
||||
if (field.owner.equals(originalParentName)
|
||||
&& field.name.equals(originalFieldName)
|
||||
&& field.desc.equals(originalFieldDesc)) {
|
||||
if (newFieldParent != null)
|
||||
field.owner = newFieldParent;
|
||||
if(newFieldName != null)
|
||||
if (newFieldName != null)
|
||||
field.name = newFieldName;
|
||||
if(newFieldDesc != null)
|
||||
if (newFieldDesc != null)
|
||||
field.desc = newFieldDesc;
|
||||
}
|
||||
}
|
||||
|
@ -48,134 +47,133 @@ public final class ASMUtil_OLD {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void renameMethodNode(String originalParentName, String originalMethodName,
|
||||
String originalMethodDesc, String newParent, String newName, String newDesc)
|
||||
{
|
||||
for(ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
for(Object o : c.methods.toArray()) {
|
||||
MethodNode m = (MethodNode)o;
|
||||
for(AbstractInsnNode i : m.instructions.toArray()) {
|
||||
if(i instanceof MethodInsnNode) {
|
||||
MethodInsnNode mi = (MethodInsnNode)i;
|
||||
if(mi.owner.equals(originalParentName) &&
|
||||
mi.name.equals(originalMethodName) &&
|
||||
mi.desc.equals(originalMethodDesc))
|
||||
{
|
||||
if(newParent != null)
|
||||
|
||||
public static void renameMethodNode(String originalParentName,
|
||||
String originalMethodName, String originalMethodDesc,
|
||||
String newParent, String newName, String newDesc) {
|
||||
for (ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
for (Object o : c.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
for (AbstractInsnNode i : m.instructions.toArray()) {
|
||||
if (i instanceof MethodInsnNode) {
|
||||
MethodInsnNode mi = (MethodInsnNode) i;
|
||||
if (mi.owner.equals(originalParentName)
|
||||
&& mi.name.equals(originalMethodName)
|
||||
&& mi.desc.equals(originalMethodDesc)) {
|
||||
if (newParent != null)
|
||||
mi.owner = newParent;
|
||||
if(newName != null)
|
||||
if (newName != null)
|
||||
mi.name = newName;
|
||||
if(newDesc != null)
|
||||
if (newDesc != null)
|
||||
mi.desc = newDesc;
|
||||
}
|
||||
} else {
|
||||
//System.out.println(i.getOpcode()+":"+c.name+":"+m.name);
|
||||
// System.out.println(i.getOpcode()+":"+c.name+":"+m.name);
|
||||
}
|
||||
}
|
||||
|
||||
if(m.signature != null) {
|
||||
if(newName != null)
|
||||
m.signature = m.signature.replace(originalMethodName, newName);
|
||||
if(newParent != null)
|
||||
m.signature = m.signature.replace(originalParentName, newParent);
|
||||
if (m.signature != null) {
|
||||
if (newName != null)
|
||||
m.signature = m.signature.replace(originalMethodName,
|
||||
newName);
|
||||
if (newParent != null)
|
||||
m.signature = m.signature.replace(originalParentName,
|
||||
newParent);
|
||||
}
|
||||
|
||||
if( m.name.equals(originalMethodName) &&
|
||||
m.desc.equals(originalMethodDesc) &&
|
||||
c.name.equals(originalParentName)) {
|
||||
if(newName != null)
|
||||
|
||||
if (m.name.equals(originalMethodName)
|
||||
&& m.desc.equals(originalMethodDesc)
|
||||
&& c.name.equals(originalParentName)) {
|
||||
if (newName != null)
|
||||
m.name = newName;
|
||||
if(newDesc != null)
|
||||
if (newDesc != null)
|
||||
m.desc = newDesc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void renameClassNode(final String oldName, final String newName) {
|
||||
for(ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
public static void renameClassNode(final String oldName,
|
||||
final String newName) {
|
||||
for (ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
for (Object oo : c.innerClasses) {
|
||||
InnerClassNode innerClassNode = (InnerClassNode) oo;
|
||||
if (innerClassNode.innerName != null &&
|
||||
innerClassNode.innerName.equals(oldName)) {
|
||||
if (innerClassNode.innerName != null
|
||||
&& innerClassNode.innerName.equals(oldName)) {
|
||||
innerClassNode.innerName = newName;
|
||||
}
|
||||
if (innerClassNode.name.equals(oldName)) {
|
||||
innerClassNode.name = newName;
|
||||
}
|
||||
if (innerClassNode.outerName != null &&
|
||||
innerClassNode.outerName.equals(oldName)) {
|
||||
if (innerClassNode.outerName != null
|
||||
&& innerClassNode.outerName.equals(oldName)) {
|
||||
innerClassNode.outerName = newName;
|
||||
}
|
||||
}
|
||||
|
||||
if(c.signature != null)
|
||||
|
||||
if (c.signature != null)
|
||||
c.signature = c.signature.replace(oldName, newName);
|
||||
|
||||
|
||||
if (c.superName.equals(oldName)) {
|
||||
c.superName = newName;
|
||||
}
|
||||
for(Object o : c.fields.toArray()) {
|
||||
FieldNode f = (FieldNode)o;
|
||||
for (Object o : c.fields.toArray()) {
|
||||
FieldNode f = (FieldNode) o;
|
||||
f.desc = f.desc.replace(oldName, newName);
|
||||
}
|
||||
for(Object o : c.interfaces.toArray()) {
|
||||
String truxerLipton = (String)o;
|
||||
truxerLipton = truxerLipton.replace(oldName, newName);
|
||||
for (Object o : c.interfaces.toArray()) {
|
||||
String truxerLipton = (String) o;
|
||||
truxerLipton = truxerLipton.replace(oldName, newName);
|
||||
}
|
||||
for(Object o : c.methods.toArray()) {
|
||||
MethodNode m = (MethodNode)o;
|
||||
|
||||
if(m.localVariables != null) {
|
||||
for(LocalVariableNode node : (List<LocalVariableNode>)m.localVariables) {
|
||||
for (Object o : c.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
|
||||
if (m.localVariables != null) {
|
||||
for (LocalVariableNode node : (List<LocalVariableNode>) m.localVariables) {
|
||||
node.desc = node.desc.replace(oldName, newName);
|
||||
}
|
||||
}
|
||||
|
||||
if(m.signature != null)
|
||||
if (m.signature != null)
|
||||
m.signature = m.signature.replace(oldName, newName);
|
||||
|
||||
for(int i = 0; i < m.exceptions.size(); i++) {
|
||||
if(m.exceptions.get(i).equals(oldName))
|
||||
|
||||
for (int i = 0; i < m.exceptions.size(); i++) {
|
||||
if (m.exceptions.get(i).equals(oldName))
|
||||
m.exceptions.set(i, newName);
|
||||
}
|
||||
|
||||
for(AbstractInsnNode i : m.instructions.toArray()) {
|
||||
|
||||
for (AbstractInsnNode i : m.instructions.toArray()) {
|
||||
if (i instanceof TypeInsnNode) {
|
||||
TypeInsnNode t = (TypeInsnNode)i;
|
||||
TypeInsnNode t = (TypeInsnNode) i;
|
||||
if (t.desc.equals(oldName)) {
|
||||
t.desc = newName;
|
||||
}
|
||||
}
|
||||
if(i instanceof MethodInsnNode) {
|
||||
MethodInsnNode mi = (MethodInsnNode)i;
|
||||
if(mi.owner.equals(oldName))
|
||||
if (i instanceof MethodInsnNode) {
|
||||
MethodInsnNode mi = (MethodInsnNode) i;
|
||||
if (mi.owner.equals(oldName))
|
||||
mi.owner = newName;
|
||||
mi.desc = mi.desc.replace(oldName, newName);
|
||||
mi.desc = mi.desc.replace(oldName, newName);
|
||||
}
|
||||
if(i instanceof FieldInsnNode) {
|
||||
FieldInsnNode fi = (FieldInsnNode)i;
|
||||
if(fi.owner.equals(oldName))
|
||||
if (i instanceof FieldInsnNode) {
|
||||
FieldInsnNode fi = (FieldInsnNode) i;
|
||||
if (fi.owner.equals(oldName))
|
||||
fi.owner = newName;
|
||||
fi.desc = fi.desc.replace(oldName, newName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*for(ClassNode oldClass : BytecodeViewer.getLoadedClasses()) {
|
||||
try {
|
||||
ClassReader cr = new ClassReader(oldClass.name);
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
cr.accept(new ClassVisitor(0) {
|
||||
@Override
|
||||
|
||||
}, ClassReader.EXPAND_FRAMES);
|
||||
byte[] b = cw.toByteArray();
|
||||
} catch(Exception e) {
|
||||
new ExceptionUI(e);
|
||||
}
|
||||
}*/
|
||||
/*
|
||||
* for(ClassNode oldClass : BytecodeViewer.getLoadedClasses()) { try {
|
||||
* ClassReader cr = new ClassReader(oldClass.name); ClassWriter cw = new
|
||||
* ClassWriter(0); cr.accept(new ClassVisitor(0) {
|
||||
*
|
||||
* @Override
|
||||
*
|
||||
* }, ClassReader.EXPAND_FRAMES); byte[] b = cw.toByteArray(); }
|
||||
* catch(Exception e) { new ExceptionUI(e); } }
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -1,19 +1,21 @@
|
|||
package the.bytecode.club.bytecodeviewer.api;
|
||||
|
||||
/**
|
||||
* Whenever a function is executed, this class will be executed with the function
|
||||
* callHook(String);
|
||||
* Whenever a function is executed, this class will be executed with the
|
||||
* function callHook(String);
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class BytecodeHook {
|
||||
|
||||
|
||||
/**
|
||||
* Called whenever a function is called (And EZ-Injection has been injected).
|
||||
* Called whenever a function is called (And EZ-Injection has been
|
||||
* injected).
|
||||
*
|
||||
* @param information the full name of the class, method and method description.
|
||||
* @param information
|
||||
* the full name of the class, method and method description.
|
||||
*/
|
||||
public abstract void callHook(String information);
|
||||
|
||||
|
|
|
@ -8,11 +8,11 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
import the.bytecode.club.bytecodeviewer.plugins.EZInjection;
|
||||
|
||||
/**
|
||||
* The official API for BCV, this was mainly designed for plugin authors
|
||||
* and people utilizing EZ-Injection.
|
||||
* The official API for BCV, this was mainly designed for plugin authors and
|
||||
* people utilizing EZ-Injection.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class BytecodeViewer {
|
||||
|
@ -21,15 +21,16 @@ public class BytecodeViewer {
|
|||
* This is used to define a global loader.
|
||||
*/
|
||||
private static ClassNodeLoader loader = new ClassNodeLoader();
|
||||
|
||||
|
||||
/**
|
||||
* Grab the loader instance
|
||||
* @return
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ClassNodeLoader getClassNodeLoader() {
|
||||
return loader;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of the ClassNode loader.
|
||||
*/
|
||||
|
@ -37,48 +38,58 @@ public class BytecodeViewer {
|
|||
loader.clear();
|
||||
loader = new ClassNodeLoader();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to start a plugin from file.
|
||||
* @param plugin the file of the plugin
|
||||
*
|
||||
* @param plugin
|
||||
* the file of the plugin
|
||||
*/
|
||||
public static void startPlugin(File plugin) {
|
||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.startPlugin(plugin);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to load classes/jars into BCV.
|
||||
* @param files an array of the files you want loaded.
|
||||
*
|
||||
* @param files
|
||||
* an array of the files you want loaded.
|
||||
*/
|
||||
public static void openFiles(File[] files) {
|
||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.openFiles(files);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to load a ClassNode.
|
||||
* @param name the full name of the ClassNode
|
||||
*
|
||||
* @param name
|
||||
* the full name of the ClassNode
|
||||
* @return the ClassNode
|
||||
*/
|
||||
public static ClassNode getClassNode(String name) {
|
||||
return the.bytecode.club.bytecodeviewer.BytecodeViewer.getClassNode(name);
|
||||
return the.bytecode.club.bytecodeviewer.BytecodeViewer
|
||||
.getClassNode(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to grab the loaded ClassNodes.
|
||||
*
|
||||
* @return the loaded classes
|
||||
*/
|
||||
public static ArrayList<ClassNode> getLoadedClasses() {
|
||||
return the.bytecode.club.bytecodeviewer.BytecodeViewer.getLoadedClasses();
|
||||
return the.bytecode.club.bytecodeviewer.BytecodeViewer
|
||||
.getLoadedClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to insert a Bytecode Hook using EZ-Injection.
|
||||
*
|
||||
* @param hook
|
||||
*/
|
||||
public static void insertHook(BytecodeHook hook) {
|
||||
EZInjection.hookArray.add(hook);
|
||||
}
|
||||
|
||||
public static void insertHook(BytecodeHook hook) {
|
||||
EZInjection.hookArray.add(hook);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will ask the user if they really want to reset the workspace, then
|
||||
* it'll reset the work space.
|
||||
|
@ -88,16 +99,21 @@ public class BytecodeViewer {
|
|||
}
|
||||
|
||||
/**
|
||||
* If true, it will display the busy icon, if false it will remove it if it's displayed.
|
||||
* @param busy if it should display the busy icon or not
|
||||
* If true, it will display the busy icon, if false it will remove it if
|
||||
* it's displayed.
|
||||
*
|
||||
* @param busy
|
||||
* if it should display the busy icon or not
|
||||
*/
|
||||
public static void setBusy(boolean busy) {
|
||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.viewer.setIcon(busy);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a small window popup with the defined message.
|
||||
* @param message the message you want to display
|
||||
*
|
||||
* @param message
|
||||
* the message you want to display
|
||||
*/
|
||||
public static void showMessage(String message) {
|
||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.showMessage(message);
|
||||
|
|
|
@ -15,24 +15,28 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
/**
|
||||
*
|
||||
* @author Demmonic
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public final class ClassNodeLoader extends ClassLoader {
|
||||
|
||||
|
||||
private HashMap<String, ClassNode> classes = new HashMap<String, ClassNode>();
|
||||
|
||||
|
||||
/**
|
||||
* Adds the provided class node to the class loader
|
||||
* @param name The class name
|
||||
* @param contents The contents of the class (or data)
|
||||
*
|
||||
* @param name
|
||||
* The class name
|
||||
* @param contents
|
||||
* The contents of the class (or data)
|
||||
*/
|
||||
public void addClass(ClassNode cn) {
|
||||
classes.put(cn.name.replace("/", "."), cn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name The name of the class
|
||||
* @param name
|
||||
* The name of the class
|
||||
* @return If this class loader contains the provided class node
|
||||
*/
|
||||
public boolean contains(String name) {
|
||||
|
@ -52,7 +56,7 @@ public final class ClassNodeLoader extends ClassLoader {
|
|||
public void clear() {
|
||||
classes.clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return All classes in this loader
|
||||
*/
|
||||
|
@ -65,24 +69,24 @@ public final class ClassNodeLoader extends ClassLoader {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* The name of the class
|
||||
* The name of the class
|
||||
* @return The class node with the provided name
|
||||
*/
|
||||
public ClassNode get(String name) {
|
||||
return classes.get(name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String className) throws ClassNotFoundException {
|
||||
return findClass(className);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
if (classes.containsKey(name)) {
|
||||
|
@ -94,7 +98,9 @@ public final class ClassNodeLoader extends ClassLoader {
|
|||
|
||||
/**
|
||||
* Converts a class node to a class
|
||||
* @param node The node to convert
|
||||
*
|
||||
* @param node
|
||||
* The node to convert
|
||||
* @return The converted class
|
||||
*/
|
||||
public Class<?> nodeToClass(ClassNode node) {
|
||||
|
@ -107,7 +113,8 @@ public final class ClassNodeLoader extends ClassLoader {
|
|||
e.printStackTrace();
|
||||
}
|
||||
byte[] b = cw.toByteArray();
|
||||
return defineClass(node.name.replaceAll("/", "."), b, 0, b.length, getDomain());
|
||||
return defineClass(node.name.replaceAll("/", "."), b, 0, b.length,
|
||||
getDomain());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,5 +133,5 @@ public final class ClassNodeLoader extends ClassLoader {
|
|||
permissions.add(new AllPermission());
|
||||
return permissions;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -18,41 +18,46 @@ import java.io.StringWriter;
|
|||
* A simple class designed to show exceptions in the UI.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class ExceptionUI extends JFrame {
|
||||
|
||||
/**
|
||||
* @param e The exception to be shown
|
||||
* @param e
|
||||
* The exception to be shown
|
||||
*/
|
||||
public ExceptionUI(Exception e) {
|
||||
setup(e,"@Konloch");
|
||||
setup(e, "@Konloch - konloch@gmail.com");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param e The exception to be shown
|
||||
* @param author the author of the plugin throwing this exception.
|
||||
* @param e
|
||||
* The exception to be shown
|
||||
* @param author
|
||||
* the author of the plugin throwing this exception.
|
||||
*/
|
||||
public ExceptionUI(Exception e, String author) {
|
||||
setup(e,author);
|
||||
setup(e, author);
|
||||
}
|
||||
|
||||
|
||||
private void setup(Exception e, String author) {
|
||||
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
setSize(new Dimension(600, 400));
|
||||
setTitle("Bytecode Viewer "+BytecodeViewer.version+" - Stack Trace - Send this to "+author);
|
||||
setTitle("Bytecode Viewer " + BytecodeViewer.version
|
||||
+ " - Stack Trace - Send this to " + author);
|
||||
getContentPane().setLayout(new CardLayout(0, 0));
|
||||
|
||||
|
||||
JTextArea txtrBytecodeViewerIs = new JTextArea();
|
||||
txtrBytecodeViewerIs.setDisabledTextColor(Color.BLACK);
|
||||
txtrBytecodeViewerIs.setWrapStyleWord(true);
|
||||
getContentPane().add(new JScrollPane(txtrBytecodeViewerIs), "name_140466576080695");
|
||||
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);
|
||||
|
|
|
@ -10,51 +10,56 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|||
* A simple plugin class, it will run the plugin in a background thread.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class Plugin extends Thread {
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
BytecodeViewer.viewer.setIcon(true);
|
||||
try {
|
||||
if(!BytecodeViewer.getLoadedClasses().isEmpty())
|
||||
if (!BytecodeViewer.getLoadedClasses().isEmpty())
|
||||
execute(BytecodeViewer.getLoadedClasses());
|
||||
else {
|
||||
System.out.println("Plugin not ran, put some classes in first.");
|
||||
BytecodeViewer.showMessage("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) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
} finally {
|
||||
finished = true;
|
||||
BytecodeViewer.viewer.setIcon(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean finished = false;
|
||||
|
||||
|
||||
/**
|
||||
* When the plugin is finally finished, this will return true
|
||||
*
|
||||
* @return true if the plugin is finished executing
|
||||
*/
|
||||
public boolean isFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If for some reason your plugin needs to keep the thread alive,
|
||||
* yet will still be considered finished (EZ-Injection), you can call this
|
||||
* function and it will set the finished boolean to true.
|
||||
* If for some reason your plugin needs to keep the thread alive, yet will
|
||||
* still be considered finished (EZ-Injection), you can call this function
|
||||
* and it will set the finished boolean to true.
|
||||
*/
|
||||
public void setFinished() {
|
||||
finished = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whenever the plugin is started, this method is called
|
||||
* @param classNodeList all of the loaded classes for easy access.
|
||||
*
|
||||
* @param classNodeList
|
||||
* all of the loaded classes for easy access.
|
||||
*/
|
||||
public abstract void execute(ArrayList<ClassNode> classNodeList);
|
||||
|
||||
|
|
|
@ -30,201 +30,220 @@ import javax.swing.text.JTextComponent;
|
|||
* A simple console GUI.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class PluginConsole extends JFrame {
|
||||
|
||||
|
||||
JTextArea textArea = new JTextArea();
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
JScrollPane scrollPane = new JScrollPane();
|
||||
public JCheckBox check = new JCheckBox("Exact");
|
||||
public JCheckBox check = new JCheckBox("Exact");
|
||||
|
||||
public PluginConsole(String pluginName) {
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
setTitle("Bytecode Viewer - Plugin Console - " + pluginName);
|
||||
setSize(new Dimension(542, 316));
|
||||
|
||||
getContentPane().add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
scrollPane.setViewportView(textArea);
|
||||
|
||||
|
||||
JButton searchNext = new JButton();
|
||||
JButton searchPrev = new JButton();
|
||||
JPanel buttonPane = new JPanel(new BorderLayout());
|
||||
buttonPane.add(searchNext, BorderLayout.WEST);
|
||||
buttonPane.add(searchPrev, BorderLayout.EAST);
|
||||
searchNext.setIcon(new ImageIcon(BytecodeViewer.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYqPBJSG/ZAAAASUlEQVR42mNgwAbS0oAEE4yHyWBmYAzjYDC694OJ4f9+BoY3H0BSbz6A2MxA6VciFyDqGAWQTWVkYEkCUrcOsDD8OwtkvMViMwAb8xEUHlHcFAAAAABJRU5ErkJggg==")));
|
||||
searchPrev.setIcon(new ImageIcon(BytecodeViewer.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYgKhxpRi1AAAATElEQVR42mNgwAZYHIAEExA7qUAYLApMDmCGEwODCojByM/A8FEAyPi/moFh9QewYjCAM1iA+D2KqYwMrIlA6tUGFoa/Z4GMt1hsBgCe1wuKber+SwAAAABJRU5ErkJggg==")));
|
||||
panel.add(buttonPane, BorderLayout.WEST);
|
||||
final JTextField field = new JTextField();
|
||||
panel.add(field, BorderLayout.CENTER);
|
||||
panel.add(check, BorderLayout.EAST);
|
||||
searchNext.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent arg0) {
|
||||
search(field.getText(), true);
|
||||
}
|
||||
});
|
||||
searchPrev.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent arg0) {
|
||||
search(field.getText(), false);
|
||||
}
|
||||
});
|
||||
field.addKeyListener(new KeyListener() {
|
||||
getContentPane().add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
scrollPane.setViewportView(textArea);
|
||||
|
||||
JButton searchNext = new JButton();
|
||||
JButton searchPrev = new JButton();
|
||||
JPanel buttonPane = new JPanel(new BorderLayout());
|
||||
buttonPane.add(searchNext, BorderLayout.WEST);
|
||||
buttonPane.add(searchPrev, BorderLayout.EAST);
|
||||
searchNext
|
||||
.setIcon(new ImageIcon(
|
||||
BytecodeViewer
|
||||
.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYqPBJSG/ZAAAASUlEQVR42mNgwAbS0oAEE4yHyWBmYAzjYDC694OJ4f9+BoY3H0BSbz6A2MxA6VciFyDqGAWQTWVkYEkCUrcOsDD8OwtkvMViMwAb8xEUHlHcFAAAAABJRU5ErkJggg==")));
|
||||
searchPrev
|
||||
.setIcon(new ImageIcon(
|
||||
BytecodeViewer
|
||||
.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYgKhxpRi1AAAATElEQVR42mNgwAZYHIAEExA7qUAYLApMDmCGEwODCojByM/A8FEAyPi/moFh9QewYjCAM1iA+D2KqYwMrIlA6tUGFoa/Z4GMt1hsBgCe1wuKber+SwAAAABJRU5ErkJggg==")));
|
||||
panel.add(buttonPane, BorderLayout.WEST);
|
||||
final JTextField field = new JTextField();
|
||||
panel.add(field, BorderLayout.CENTER);
|
||||
panel.add(check, BorderLayout.EAST);
|
||||
searchNext.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent arg0) {
|
||||
search(field.getText(), true);
|
||||
}
|
||||
});
|
||||
searchPrev.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent arg0) {
|
||||
search(field.getText(), false);
|
||||
}
|
||||
});
|
||||
field.addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent arg0) {
|
||||
if(arg0.getKeyCode() == KeyEvent.VK_ENTER)
|
||||
search(field.getText(), true);
|
||||
if (arg0.getKeyCode() == KeyEvent.VK_ENTER)
|
||||
search(field.getText(), true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent arg0) {}
|
||||
public void keyPressed(KeyEvent arg0) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent arg0) {}
|
||||
});
|
||||
|
||||
public void keyTyped(KeyEvent arg0) {
|
||||
}
|
||||
});
|
||||
|
||||
scrollPane.setColumnHeaderView(panel);
|
||||
this.setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This was really interesting to write.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*/
|
||||
public void search(String search, boolean next) {
|
||||
try {
|
||||
JTextArea area = textArea;
|
||||
if (search.isEmpty()) {
|
||||
highlight(area, "");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This was really interesting to write.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*/
|
||||
public void search(String search, boolean next) {
|
||||
try {
|
||||
JTextArea area = textArea;
|
||||
if(search.isEmpty()) {
|
||||
highlight(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(!check.isSelected())
|
||||
{
|
||||
s = s.toLowerCase();
|
||||
search = search.toLowerCase();
|
||||
}
|
||||
|
||||
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(!check.isSelected())
|
||||
{
|
||||
s = s.toLowerCase();
|
||||
search = search.toLowerCase();
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
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(lastGoodLine != -1 && area.getDocument().getDefaultRootElement().getElementIndex(area.getCaretPosition())+1 == startLine) {
|
||||
area.setCaretPosition(area.getDocument()
|
||||
.getDefaultRootElement().getElement(lastGoodLine-1)
|
||||
.getStartOffset());
|
||||
}
|
||||
}
|
||||
highlight(area, search);
|
||||
} catch(Exception e) {
|
||||
if (next) {
|
||||
for (String s : test) {
|
||||
if (!check.isSelected()) {
|
||||
s = s.toLowerCase();
|
||||
search = search.toLowerCase();
|
||||
}
|
||||
|
||||
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 (!check.isSelected()) {
|
||||
s = s.toLowerCase();
|
||||
search = search.toLowerCase();
|
||||
}
|
||||
|
||||
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(area, search);
|
||||
} catch (Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DefaultHighlighter.DefaultHighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter(new Color(255,62,150));
|
||||
|
||||
public void highlight(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;
|
||||
private DefaultHighlighter.DefaultHighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter(
|
||||
new Color(255, 62, 150));
|
||||
|
||||
if(!check.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) {
|
||||
public void highlight(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 (!check.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) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends \r\n to the end of your string, then it puts it on the top.
|
||||
* @param t the string you want to append
|
||||
*
|
||||
* @param t
|
||||
* the string you want to append
|
||||
*/
|
||||
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(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the text
|
||||
* @param t the text you want set
|
||||
*
|
||||
* @param t
|
||||
* the text you want set
|
||||
*/
|
||||
public void setText(String t) {
|
||||
textArea.setText(t);
|
||||
|
|
|
@ -15,27 +15,30 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author Bibl
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class ClassNodeDecompiler {
|
||||
|
||||
|
||||
public static String decompile(ClassNode cn) {
|
||||
return decompileClassNode(new PrefixedStringBuilder(), new ArrayList<String>(), cn).toString();
|
||||
return decompileClassNode(new PrefixedStringBuilder(),
|
||||
new ArrayList<String>(), cn).toString();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static PrefixedStringBuilder decompileClassNode(PrefixedStringBuilder sb, ArrayList<String> decompiledClasses, ClassNode cn) {
|
||||
protected static PrefixedStringBuilder decompileClassNode(
|
||||
PrefixedStringBuilder sb, ArrayList<String> decompiledClasses,
|
||||
ClassNode cn) {
|
||||
ArrayList<String> unableToDecompile = new ArrayList<String>();
|
||||
decompiledClasses.add(cn.name);
|
||||
sb.append(getAccessString(cn.access));
|
||||
sb.append(" ");
|
||||
sb.append(cn.name);
|
||||
if (cn.superName != null && !cn.superName.equals("java/lang/Object")) {
|
||||
sb.append(" extends ");
|
||||
sb.append(cn.superName);
|
||||
}
|
||||
|
||||
if (cn.superName != null && !cn.superName.equals("java/lang/Object")) {
|
||||
sb.append(" extends ");
|
||||
sb.append(cn.superName);
|
||||
}
|
||||
|
||||
int amountOfInterfaces = cn.interfaces.size();
|
||||
if (amountOfInterfaces > 0) {
|
||||
sb.append(" implements ");
|
||||
|
@ -50,7 +53,7 @@ public class ClassNodeDecompiler {
|
|||
}
|
||||
sb.append(" {");
|
||||
sb.append(BytecodeViewer.nl);
|
||||
for (FieldNode fn : (List<FieldNode>)cn.fields) {
|
||||
for (FieldNode fn : (List<FieldNode>) cn.fields) {
|
||||
sb.append(BytecodeViewer.nl);
|
||||
sb.append(" ");
|
||||
FieldNodeDecompiler.decompile(sb, fn);
|
||||
|
@ -58,20 +61,21 @@ public class ClassNodeDecompiler {
|
|||
if (cn.fields.size() > 0) {
|
||||
sb.append(BytecodeViewer.nl);
|
||||
}
|
||||
for (MethodNode mn : (List<MethodNode>)cn.methods) {
|
||||
for (MethodNode mn : (List<MethodNode>) cn.methods) {
|
||||
sb.append(BytecodeViewer.nl);
|
||||
MethodNodeDecompiler.decompile(sb, mn, cn);
|
||||
}
|
||||
|
||||
|
||||
for (Object o : cn.innerClasses) {
|
||||
InnerClassNode innerClassNode = (InnerClassNode) o;
|
||||
String innerClassName = innerClassNode.name;
|
||||
if ((innerClassName != null) && !decompiledClasses.contains(innerClassName)) {
|
||||
if ((innerClassName != null)
|
||||
&& !decompiledClasses.contains(innerClassName)) {
|
||||
decompiledClasses.add(innerClassName);
|
||||
ClassNode cn1 = BytecodeViewer.getClassNode(innerClassName);
|
||||
if (cn1 != null) {
|
||||
sb.appendPrefix(" ");
|
||||
sb.append(BytecodeViewer.nl+BytecodeViewer.nl);
|
||||
sb.append(BytecodeViewer.nl + BytecodeViewer.nl);
|
||||
sb = decompileClassNode(sb, decompiledClasses, cn1);
|
||||
sb.trimPrefix(5);
|
||||
sb.append(BytecodeViewer.nl);
|
||||
|
@ -80,21 +84,22 @@ public class ClassNodeDecompiler {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!unableToDecompile.isEmpty()) {
|
||||
|
||||
if (!unableToDecompile.isEmpty()) {
|
||||
sb.append("//the following inner classes couldn't be decompiled: ");
|
||||
for(String s : unableToDecompile) {
|
||||
for (String s : unableToDecompile) {
|
||||
sb.append(s);
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(BytecodeViewer.nl);
|
||||
}
|
||||
|
||||
|
||||
sb.append("}");
|
||||
// System.out.println("Wrote end for " + cn.name + " with prefix length: " + sb.prefix.length());
|
||||
// System.out.println("Wrote end for " + cn.name +
|
||||
// " with prefix length: " + sb.prefix.length());
|
||||
return sb;
|
||||
}
|
||||
|
||||
|
||||
public static String getAccessString(int access) {
|
||||
List<String> tokens = new ArrayList<String>();
|
||||
if ((access & Opcodes.ACC_PUBLIC) != 0)
|
||||
|
@ -117,11 +122,12 @@ public class ClassNodeDecompiler {
|
|||
tokens.add("enum");
|
||||
if ((access & Opcodes.ACC_ANNOTATION) != 0)
|
||||
tokens.add("annotation");
|
||||
if (!tokens.contains("interface") && !tokens.contains("enum") && !tokens.contains("annotation"))
|
||||
if (!tokens.contains("interface") && !tokens.contains("enum")
|
||||
&& !tokens.contains("annotation"))
|
||||
tokens.add("class");
|
||||
if (tokens.size() == 0)
|
||||
return "[Error parsing]";
|
||||
|
||||
|
||||
// hackery delimeters
|
||||
StringBuilder sb = new StringBuilder(tokens.get(0));
|
||||
for (int i = 1; i < tokens.size(); i++) {
|
||||
|
|
|
@ -11,12 +11,13 @@ import org.objectweb.asm.tree.FieldNode;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author Bibl
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class FieldNodeDecompiler {
|
||||
|
||||
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, FieldNode f) {
|
||||
|
||||
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb,
|
||||
FieldNode f) {
|
||||
String s = getAccessString(f.access);
|
||||
sb.append(s);
|
||||
if (s.length() > 0)
|
||||
|
@ -40,7 +41,7 @@ public class FieldNodeDecompiler {
|
|||
sb.append(";");
|
||||
return sb;
|
||||
}
|
||||
|
||||
|
||||
private static String getAccessString(int access) {
|
||||
List<String> tokens = new ArrayList<String>();
|
||||
if ((access & Opcodes.ACC_PUBLIC) != 0)
|
||||
|
|
|
@ -29,57 +29,67 @@ import eu.bibl.banalysis.filter.insn.VarInstructionFilter;
|
|||
|
||||
/**
|
||||
* Pattern filter holder and stepper.
|
||||
*
|
||||
* @author Bibl
|
||||
*
|
||||
*/
|
||||
public class InstructionPattern implements Opcodes {
|
||||
|
||||
|
||||
/** Last instruction-match position pointer **/
|
||||
protected int pointer;
|
||||
/** Filters/patterns/search criteria. **/
|
||||
protected InstructionFilter[] filters;
|
||||
/** Last match found cache. **/
|
||||
protected AbstractInsnNode[] lastMatch;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new pattern from the specified instructions.
|
||||
* @param insns {@link AbstractInsnNode} pattern array.
|
||||
*
|
||||
* @param insns
|
||||
* {@link AbstractInsnNode} pattern array.
|
||||
*/
|
||||
public InstructionPattern(AbstractInsnNode[] insns) {
|
||||
filters = translate(insns);
|
||||
lastMatch = new AbstractInsnNode[insns.length];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new pattern from the specified opcode.
|
||||
* @param opcodes Opcodes to convert to {@link OpcodeFilter}s.
|
||||
*
|
||||
* @param opcodes
|
||||
* Opcodes to convert to {@link OpcodeFilter}s.
|
||||
*/
|
||||
public InstructionPattern(int[] opcodes) {
|
||||
filters = new InstructionFilter[opcodes.length];
|
||||
lastMatch = new AbstractInsnNode[opcodes.length];
|
||||
for(int i = 0; i < opcodes.length; i++) {
|
||||
for (int i = 0; i < opcodes.length; i++) {
|
||||
filters[i] = new OpcodeFilter(opcodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct an absolute pattern from user-defined filters.
|
||||
* @param filters User-defined {@link InstructionFilter}s.
|
||||
*
|
||||
* @param filters
|
||||
* User-defined {@link InstructionFilter}s.
|
||||
*/
|
||||
public InstructionPattern(InstructionFilter[] filters) {
|
||||
this.filters = filters;
|
||||
lastMatch = new AbstractInsnNode[filters.length];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Steps through the instruction list checking if the current instruction ended a successful pattern-match sequence.
|
||||
* @param ain {@link AbstractInsnNode} to check.
|
||||
* Steps through the instruction list checking if the current instruction
|
||||
* ended a successful pattern-match sequence.
|
||||
*
|
||||
* @param ain
|
||||
* {@link AbstractInsnNode} to check.
|
||||
* @return True if this instruction successfully completed the pattern.
|
||||
*/
|
||||
public boolean accept(AbstractInsnNode ain) {
|
||||
if (pointer >= filters.length)
|
||||
reset();
|
||||
|
||||
|
||||
InstructionFilter filter = filters[pointer];
|
||||
if (filter.accept(ain)) {
|
||||
lastMatch[pointer] = ain;
|
||||
|
@ -92,14 +102,15 @@ public class InstructionPattern implements Opcodes {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Last pattern sequence match equivilent from the inputted {@link AbstractInsnNode}s.
|
||||
* @return Last pattern sequence match equivilent from the inputted
|
||||
* {@link AbstractInsnNode}s.
|
||||
*/
|
||||
public AbstractInsnNode[] getLastMatch() {
|
||||
return lastMatch;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resets the instruction pointer and clears the last match cache data.
|
||||
*/
|
||||
|
@ -108,67 +119,83 @@ public class InstructionPattern implements Opcodes {
|
|||
AbstractInsnNode[] match = lastMatch;
|
||||
lastMatch = new AbstractInsnNode[match.length];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the current instruction pointer to 0 (start of pattern).
|
||||
*/
|
||||
public void reset() {
|
||||
pointer = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an array of {@link AbstractInsnNode}s to their {@link InstructionFilter} counterparts.
|
||||
* @param ains {@link AbstractInsnNode}s to convert.
|
||||
* Converts an array of {@link AbstractInsnNode}s to their
|
||||
* {@link InstructionFilter} counterparts.
|
||||
*
|
||||
* @param ains
|
||||
* {@link AbstractInsnNode}s to convert.
|
||||
* @return Array of {@link InstructionFilter}s.
|
||||
*/
|
||||
public static InstructionFilter[] translate(AbstractInsnNode[] ains) {
|
||||
InstructionFilter[] filters = new InstructionFilter[ains.length];
|
||||
for(int i = 0; i < ains.length; i++) {
|
||||
for (int i = 0; i < ains.length; i++) {
|
||||
filters[i] = translate(ains[i]);
|
||||
}
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translate a single {@link AbstractInsnNode} to an {@link InstructionFilter}.
|
||||
* @param ain Instruction to convert.
|
||||
* Translate a single {@link AbstractInsnNode} to an
|
||||
* {@link InstructionFilter}.
|
||||
*
|
||||
* @param ain
|
||||
* Instruction to convert.
|
||||
* @return A filter an an equivilent to the inputted instruction.
|
||||
*/
|
||||
public static InstructionFilter translate(AbstractInsnNode ain) {
|
||||
if (ain instanceof LdcInsnNode) {
|
||||
return new LdcInstructionFilter(((LdcInsnNode) ain).cst);
|
||||
} else if (ain instanceof TypeInsnNode) {
|
||||
return new TypeInstructionFilter(ain.getOpcode(), ((TypeInsnNode) ain).desc);
|
||||
return new TypeInstructionFilter(ain.getOpcode(),
|
||||
((TypeInsnNode) ain).desc);
|
||||
} else if (ain instanceof FieldInsnNode) {
|
||||
return new FieldInstructionFilter(ain.getOpcode(), ((FieldInsnNode) ain).owner, ((FieldInsnNode) ain).name, ((FieldInsnNode) ain).desc);
|
||||
return new FieldInstructionFilter(ain.getOpcode(),
|
||||
((FieldInsnNode) ain).owner, ((FieldInsnNode) ain).name,
|
||||
((FieldInsnNode) ain).desc);
|
||||
} else if (ain instanceof MethodInsnNode) {
|
||||
return new MethodInstructionFilter(ain.getOpcode(), ((MethodInsnNode) ain).owner, ((MethodInsnNode) ain).name, ((MethodInsnNode) ain).desc);
|
||||
return new MethodInstructionFilter(ain.getOpcode(),
|
||||
((MethodInsnNode) ain).owner, ((MethodInsnNode) ain).name,
|
||||
((MethodInsnNode) ain).desc);
|
||||
} else if (ain instanceof VarInsnNode) {
|
||||
return new VarInstructionFilter(ain.getOpcode(), ((VarInsnNode) ain).var);
|
||||
return new VarInstructionFilter(ain.getOpcode(),
|
||||
((VarInsnNode) ain).var);
|
||||
} else if (ain instanceof InsnNode) {
|
||||
return new InsnInstructionFilter(ain.getOpcode());
|
||||
} else if (ain instanceof IincInsnNode) {
|
||||
return new IincInstructionFilter(((IincInsnNode) ain).incr, ((IincInsnNode) ain).var);
|
||||
return new IincInstructionFilter(((IincInsnNode) ain).incr,
|
||||
((IincInsnNode) ain).var);
|
||||
} else if (ain instanceof JumpInsnNode) {
|
||||
return new JumpInstructionFilter(ain.getOpcode());
|
||||
} else if (ain instanceof LabelNode) {
|
||||
return InstructionFilter.ACCEPT_ALL; // TODO: Cache labels and check. // TODO: That's a fucking stupid idea.
|
||||
return InstructionFilter.ACCEPT_ALL; // TODO: Cache labels and
|
||||
// check. // TODO: That's a
|
||||
// fucking stupid idea.
|
||||
} else if (ain instanceof MultiANewArrayInsnNode) {
|
||||
return new MultiANewArrayInstructionFilter(((MultiANewArrayInsnNode) ain).desc, ((MultiANewArrayInsnNode) ain).dims);
|
||||
return new MultiANewArrayInstructionFilter(
|
||||
((MultiANewArrayInsnNode) ain).desc,
|
||||
((MultiANewArrayInsnNode) ain).dims);
|
||||
} else {
|
||||
return InstructionFilter.ACCEPT_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
AbstractInsnNode[] ains = new AbstractInsnNode[] {
|
||||
new LdcInsnNode("ldc"),
|
||||
new VarInsnNode(ASTORE, 0),
|
||||
new LdcInsnNode("ldc"), new VarInsnNode(ASTORE, 0),
|
||||
new LdcInsnNode("ldc") };
|
||||
InstructionPattern pattern = new InstructionPattern(new AbstractInsnNode[] {
|
||||
new LdcInsnNode("ldc"),
|
||||
new VarInsnNode(-1, -1) });
|
||||
for(AbstractInsnNode ain : ains) {
|
||||
InstructionPattern pattern = new InstructionPattern(
|
||||
new AbstractInsnNode[] { new LdcInsnNode("ldc"),
|
||||
new VarInsnNode(-1, -1) });
|
||||
for (AbstractInsnNode ain : ains) {
|
||||
if (pattern.accept(ain)) {
|
||||
System.out.println(Arrays.toString(pattern.getLastMatch()));
|
||||
}
|
||||
|
|
|
@ -41,43 +41,46 @@ import eu.bibl.banalysis.asm.desc.OpcodeInfo;
|
|||
*
|
||||
*/
|
||||
public class InstructionPrinter {
|
||||
|
||||
|
||||
/** The MethodNode to print **/
|
||||
protected MethodNode mNode;
|
||||
private TypeAndName[] args;
|
||||
|
||||
|
||||
protected int[] pattern;
|
||||
protected boolean match;
|
||||
protected InstructionSearcher searcher;
|
||||
|
||||
|
||||
protected List<AbstractInsnNode> matchedInsns;
|
||||
protected Map<LabelNode, Integer> labels;
|
||||
|
||||
|
||||
public InstructionPrinter(MethodNode m, TypeAndName[] args) {
|
||||
this.args = args;
|
||||
mNode = m;
|
||||
labels = new HashMap<LabelNode, Integer>();
|
||||
// matchedInsns = new ArrayList<AbstractInsnNode>(); // ingnored because match = false
|
||||
// matchedInsns = new ArrayList<AbstractInsnNode>(); // ingnored because
|
||||
// match = false
|
||||
match = false;
|
||||
}
|
||||
|
||||
public InstructionPrinter(MethodNode m, InstructionPattern pattern, TypeAndName[] args) {
|
||||
|
||||
public InstructionPrinter(MethodNode m, InstructionPattern pattern,
|
||||
TypeAndName[] args) {
|
||||
this.args = args;
|
||||
mNode = m;
|
||||
labels = new HashMap<LabelNode, Integer>();
|
||||
searcher = new InstructionSearcher(m.instructions, pattern);
|
||||
match = searcher.search();
|
||||
if (match) {
|
||||
for(AbstractInsnNode[] ains : searcher.getMatches()) {
|
||||
for(AbstractInsnNode ain : ains) {
|
||||
for (AbstractInsnNode[] ains : searcher.getMatches()) {
|
||||
for (AbstractInsnNode ain : ains) {
|
||||
matchedInsns.add(ain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates the print
|
||||
*
|
||||
* @return The print as an ArrayList
|
||||
*/
|
||||
public ArrayList<String> createPrint() {
|
||||
|
@ -104,13 +107,15 @@ public class InstructionPrinter {
|
|||
} else if (ain instanceof LineNumberNode) {
|
||||
line = printLineNumberNode((LineNumberNode) ain, it);
|
||||
} else if (ain instanceof LabelNode) {
|
||||
if(firstLabel && BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected())
|
||||
if (firstLabel
|
||||
&& BytecodeViewer.viewer.chckbxmntmAppendBrackets
|
||||
.isSelected())
|
||||
info.add("}");
|
||||
|
||||
|
||||
line = printLabelnode((LabelNode) ain);
|
||||
|
||||
if(BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected()) {
|
||||
if(!firstLabel)
|
||||
|
||||
if (BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected()) {
|
||||
if (!firstLabel)
|
||||
firstLabel = true;
|
||||
line += " {";
|
||||
}
|
||||
|
@ -125,108 +130,110 @@ public class InstructionPrinter {
|
|||
} else if (ain instanceof LookupSwitchInsnNode) {
|
||||
line = printLookupSwitchInsnNode((LookupSwitchInsnNode) ain);
|
||||
} else {
|
||||
line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " " + ain.toString();
|
||||
line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " "
|
||||
+ ain.toString();
|
||||
}
|
||||
if (!line.equals("")) {
|
||||
if (match)
|
||||
if (matchedInsns.contains(ain))
|
||||
line = " -> " + line;
|
||||
|
||||
|
||||
info.add(line);
|
||||
}
|
||||
}
|
||||
if(firstLabel && BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected())
|
||||
if (firstLabel
|
||||
&& BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected())
|
||||
info.add("}");
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
protected String printVarInsnNode(VarInsnNode vin, ListIterator<?> it) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(nameOpcode(vin.getOpcode()));
|
||||
sb.append(vin.var);
|
||||
if (BytecodeViewer.viewer.debugHelpers.isSelected()) {
|
||||
if (vin.var == 0 && !Modifier.isStatic(mNode.access)) {
|
||||
sb.append(" // reference to self");
|
||||
} else {
|
||||
final int refIndex = vin.var - (Modifier.isStatic(mNode.access) ? 0 : 1);
|
||||
if (refIndex >= 0 && refIndex < args.length-1) {
|
||||
sb.append(" // reference to " + args[refIndex].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
if (BytecodeViewer.viewer.debugHelpers.isSelected()) {
|
||||
if (vin.var == 0 && !Modifier.isStatic(mNode.access)) {
|
||||
sb.append(" // reference to self");
|
||||
} else {
|
||||
final int refIndex = vin.var
|
||||
- (Modifier.isStatic(mNode.access) ? 0 : 1);
|
||||
if (refIndex >= 0 && refIndex < args.length - 1) {
|
||||
sb.append(" // reference to " + args[refIndex].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
protected String printIntInsnNode(IntInsnNode iin, ListIterator<?> it) {
|
||||
return nameOpcode(iin.getOpcode()) + " " + iin.operand;
|
||||
}
|
||||
|
||||
|
||||
protected String printFieldInsnNode(FieldInsnNode fin, ListIterator<?> it) {
|
||||
String desc = Type.getType(fin.desc).getClassName();
|
||||
if(desc == null || desc.equals("null"))
|
||||
if (desc == null || desc.equals("null"))
|
||||
desc = fin.desc;
|
||||
return nameOpcode(fin.getOpcode()) + " " + fin.owner + "." + fin.name + ":" + desc;
|
||||
return nameOpcode(fin.getOpcode()) + " " + fin.owner + "." + fin.name
|
||||
+ ":" + desc;
|
||||
}
|
||||
|
||||
|
||||
protected String printMethodInsnNode(MethodInsnNode min, ListIterator<?> it) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(nameOpcode(min.getOpcode()) + " " + min.owner + " " + min.name + "(");
|
||||
|
||||
sb.append(nameOpcode(min.getOpcode()) + " " + min.owner + " "
|
||||
+ min.name + "(");
|
||||
|
||||
String desc = Type.getType(min.desc).getClassName();
|
||||
if(desc == null || desc.equals("null"))
|
||||
if (desc == null || desc.equals("null"))
|
||||
desc = min.desc;
|
||||
sb.append(desc);
|
||||
|
||||
|
||||
sb.append(");");
|
||||
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected String printLdcInsnNode(LdcInsnNode ldc, ListIterator<?> it) {
|
||||
if(BytecodeViewer.viewer.chckbxmntmNewCheckItem.isSelected()) { //ascii only
|
||||
if (ldc.cst instanceof String)
|
||||
return nameOpcode(ldc.getOpcode()) + " \"" + StringEscapeUtils.escapeJava(ldc.cst.toString()) + "\" (" + ldc.cst.getClass().getCanonicalName() + ")";
|
||||
|
||||
return nameOpcode(ldc.getOpcode()) + " " + StringEscapeUtils.escapeJava(ldc.cst.toString()) + " (" + ldc.cst.getClass().getCanonicalName() + ")";
|
||||
if (ldc.cst instanceof String)
|
||||
return nameOpcode(ldc.getOpcode()) + " \""
|
||||
+ StringEscapeUtils.escapeJava(ldc.cst.toString()) + "\" ("
|
||||
+ ldc.cst.getClass().getCanonicalName() + ")";
|
||||
|
||||
} else {
|
||||
if (ldc.cst instanceof String)
|
||||
return nameOpcode(ldc.getOpcode()) + " \"" + ((String)ldc.cst).replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r").replaceAll("\\\"", "\\\\\"") + "\" (" + ldc.cst.getClass().getCanonicalName() + ")";
|
||||
|
||||
return nameOpcode(ldc.getOpcode()) + " " + ldc.cst + " (" + ldc.cst.getClass().getCanonicalName() + ")";
|
||||
}
|
||||
return nameOpcode(ldc.getOpcode()) + " "
|
||||
+ StringEscapeUtils.escapeJava(ldc.cst.toString()) + " ("
|
||||
+ ldc.cst.getClass().getCanonicalName() + ")";
|
||||
}
|
||||
|
||||
|
||||
protected String printInsnNode(InsnNode in, ListIterator<?> it) {
|
||||
return nameOpcode(in.getOpcode());
|
||||
}
|
||||
|
||||
|
||||
protected String printJumpInsnNode(JumpInsnNode jin, ListIterator<?> it) {
|
||||
String line = nameOpcode(jin.getOpcode()) + " L" + resolveLabel(jin.label);
|
||||
String line = nameOpcode(jin.getOpcode()) + " L"
|
||||
+ resolveLabel(jin.label);
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
protected String printLineNumberNode(LineNumberNode lin, ListIterator<?> it) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
protected String printLabelnode(LabelNode label) {
|
||||
return "L" + resolveLabel(label);
|
||||
}
|
||||
|
||||
|
||||
protected String printTypeInsnNode(TypeInsnNode tin) {
|
||||
try {
|
||||
String desc = Type.getType(tin.desc).getClassName();
|
||||
if(desc == null || desc.equals("null"))
|
||||
if (desc == null || desc.equals("null"))
|
||||
desc = tin.desc;
|
||||
return nameOpcode(tin.getOpcode()) + " " + desc;
|
||||
} catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
return "//error";
|
||||
}
|
||||
|
||||
|
||||
protected String printIincInsnNode(IincInsnNode iin) {
|
||||
return nameOpcode(iin.getOpcode()) + " " + iin.var + " " + iin.incr;
|
||||
}
|
||||
|
@ -236,9 +243,11 @@ public class InstructionPrinter {
|
|||
List<?> labels = tin.labels;
|
||||
int count = 0;
|
||||
for (int i = tin.min; i < tin.max; i++) {
|
||||
line += " val: " + i + " -> " + "L" + resolveLabel((LabelNode) labels.get(count++)) + "\n";
|
||||
line += " val: " + i + " -> " + "L"
|
||||
+ resolveLabel((LabelNode) labels.get(count++)) + "\n";
|
||||
}
|
||||
line += " default" + " -> L" + resolveLabel(tin.dflt) + "";
|
||||
line += " default" + " -> L" + resolveLabel(tin.dflt)
|
||||
+ "";
|
||||
return line;
|
||||
}
|
||||
|
||||
|
@ -246,21 +255,22 @@ public class InstructionPrinter {
|
|||
String line = nameOpcode(lin.getOpcode()) + ": \n";
|
||||
List<?> keys = lin.keys;
|
||||
List<?> labels = lin.labels;
|
||||
|
||||
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
int key = (Integer) keys.get(i);
|
||||
LabelNode label = (LabelNode) labels.get(i);
|
||||
line += " val: " + key + " -> " + "L" + resolveLabel(label) + "\n";
|
||||
line += " val: " + key + " -> " + "L"
|
||||
+ resolveLabel(label) + "\n";
|
||||
}
|
||||
line += " default" + " -> L" + resolveLabel(lin.dflt) + "";
|
||||
line += " default" + " -> L" + resolveLabel(lin.dflt)
|
||||
+ "";
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected String nameOpcode(int opcode) {
|
||||
return " " + OpcodeInfo.OPCODES.get(opcode).toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
protected int resolveLabel(LabelNode label) {
|
||||
if (labels.containsKey(label)) {
|
||||
return labels.get(label);
|
||||
|
@ -270,11 +280,11 @@ public class InstructionPrinter {
|
|||
return newLabelIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void saveTo(File file, InstructionPrinter printer) {
|
||||
try {
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
|
||||
for(String s : printer.createPrint()) {
|
||||
for (String s : printer.createPrint()) {
|
||||
bw.write(s);
|
||||
bw.newLine();
|
||||
}
|
||||
|
|
|
@ -12,32 +12,32 @@ import org.objectweb.asm.tree.LineNumberNode;
|
|||
/**
|
||||
*
|
||||
* @author Bibl
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class InstructionSearcher implements Opcodes {
|
||||
|
||||
|
||||
protected InsnList insns;
|
||||
protected InstructionPattern pattern;
|
||||
|
||||
|
||||
protected List<AbstractInsnNode[]> matches;
|
||||
|
||||
|
||||
public InstructionSearcher(InsnList insns, int[] opcodes) {
|
||||
this(insns, new InstructionPattern(opcodes));
|
||||
}
|
||||
|
||||
|
||||
public InstructionSearcher(InsnList insns, AbstractInsnNode[] ains) {
|
||||
this(insns, new InstructionPattern(ains));
|
||||
}
|
||||
|
||||
|
||||
public InstructionSearcher(InsnList insns, InstructionPattern pattern) {
|
||||
this.insns = insns;
|
||||
this.pattern = pattern;
|
||||
matches = new ArrayList<AbstractInsnNode[]>();
|
||||
}
|
||||
|
||||
|
||||
public boolean search() {
|
||||
for(AbstractInsnNode ain : insns.toArray()) {
|
||||
for (AbstractInsnNode ain : insns.toArray()) {
|
||||
if (ain instanceof LineNumberNode || ain instanceof FrameNode)
|
||||
continue;
|
||||
if (pattern.accept(ain)) {
|
||||
|
@ -47,11 +47,11 @@ public class InstructionSearcher implements Opcodes {
|
|||
}
|
||||
return size() != 0;
|
||||
}
|
||||
|
||||
|
||||
public List<AbstractInsnNode[]> getMatches() {
|
||||
return matches;
|
||||
}
|
||||
|
||||
|
||||
public int size() {
|
||||
return matches.size();
|
||||
}
|
||||
|
|
|
@ -19,61 +19,63 @@ import the.bytecode.club.bytecodeviewer.decompilers.bytecode.TypeAndName;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author Bibl
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class MethodNodeDecompiler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, MethodNode m, ClassNode cn) {
|
||||
@SuppressWarnings("unused")
|
||||
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb,
|
||||
MethodNode m, ClassNode cn) {
|
||||
String package_ = null;
|
||||
String class_ = null;
|
||||
if (cn.name.contains("/")) {
|
||||
package_ = cn.name.substring(0, cn.name.lastIndexOf("/"));
|
||||
class_ = cn.name.substring(cn.name.lastIndexOf("/")+1);
|
||||
} else {
|
||||
class_ = cn.name;
|
||||
}
|
||||
|
||||
String class_ = null;
|
||||
if (cn.name.contains("/")) {
|
||||
package_ = cn.name.substring(0, cn.name.lastIndexOf("/"));
|
||||
class_ = cn.name.substring(cn.name.lastIndexOf("/") + 1);
|
||||
} else {
|
||||
class_ = cn.name;
|
||||
}
|
||||
|
||||
String s = getAccessString(m.access);
|
||||
sb.append(" ");
|
||||
sb.append(s);
|
||||
if (s.length() > 0)
|
||||
sb.append(" ");
|
||||
|
||||
|
||||
System.out.println(m.name);
|
||||
if (m.name.equals("<init>")) {
|
||||
sb.append(class_);
|
||||
} else if (m.name.equals("<clinit>")) {
|
||||
} else {
|
||||
sb.append(m.name);
|
||||
}
|
||||
|
||||
TypeAndName[] args = new TypeAndName[0];
|
||||
|
||||
if (!m.name.equals("<clinit>")) {
|
||||
sb.append("(");
|
||||
|
||||
final Type[] argTypes = Type.getArgumentTypes(m.desc);
|
||||
args = new TypeAndName[argTypes.length];
|
||||
|
||||
for (int i = 0;i < argTypes.length; i++) {
|
||||
final Type type = argTypes[i];
|
||||
|
||||
final TypeAndName tan = new TypeAndName();
|
||||
final String argName = "arg" + i;
|
||||
|
||||
tan.name = argName;
|
||||
tan.type = type;
|
||||
|
||||
args[i] = tan;
|
||||
|
||||
sb.append(type.getClassName() + " " + argName + (i < argTypes.length-1 ? ", " : ""));
|
||||
}
|
||||
|
||||
sb.append(")");
|
||||
}
|
||||
|
||||
if (m.name.equals("<init>")) {
|
||||
sb.append(class_);
|
||||
} else if (m.name.equals("<clinit>")) {
|
||||
} else {
|
||||
sb.append(m.name);
|
||||
}
|
||||
|
||||
TypeAndName[] args = new TypeAndName[0];
|
||||
|
||||
if (!m.name.equals("<clinit>")) {
|
||||
sb.append("(");
|
||||
|
||||
final Type[] argTypes = Type.getArgumentTypes(m.desc);
|
||||
args = new TypeAndName[argTypes.length];
|
||||
|
||||
for (int i = 0; i < argTypes.length; i++) {
|
||||
final Type type = argTypes[i];
|
||||
|
||||
final TypeAndName tan = new TypeAndName();
|
||||
final String argName = "arg" + i;
|
||||
|
||||
tan.name = argName;
|
||||
tan.type = type;
|
||||
|
||||
args[i] = tan;
|
||||
|
||||
sb.append(type.getClassName() + " " + argName
|
||||
+ (i < argTypes.length - 1 ? ", " : ""));
|
||||
}
|
||||
|
||||
sb.append(")");
|
||||
}
|
||||
|
||||
int amountOfThrows = m.exceptions.size();
|
||||
if (amountOfThrows > 0) {
|
||||
sb.append(" throws ");
|
||||
|
@ -83,43 +85,47 @@ public class MethodNodeDecompiler {
|
|||
sb.append(m.exceptions.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (s.contains("abstract")) {
|
||||
sb.append(" {}");
|
||||
sb.append(" //");
|
||||
sb.append(m.desc);
|
||||
sb.append(" //");
|
||||
sb.append(m.desc);
|
||||
sb.append(BytecodeViewer.nl);
|
||||
} else {
|
||||
|
||||
sb.append(" {");
|
||||
|
||||
|
||||
if (BytecodeViewer.viewer.debugHelpers.isSelected()) {
|
||||
if(m.name.equals("<clinit>"))
|
||||
if (m.name.equals("<clinit>"))
|
||||
sb.append(" // <clinit>");
|
||||
else if(m.name.equals("<init>"))
|
||||
else if (m.name.equals("<init>"))
|
||||
sb.append(" // <init>");
|
||||
}
|
||||
|
||||
sb.append(" //");
|
||||
sb.append(m.desc);
|
||||
|
||||
sb.append(" //");
|
||||
sb.append(m.desc);
|
||||
|
||||
sb.append(BytecodeViewer.nl);
|
||||
|
||||
if (m.signature != null) {
|
||||
sb.append(" <sig:").append(m.signature).append(">");
|
||||
}
|
||||
|
||||
|
||||
InstructionPrinter insnPrinter = new InstructionPrinter(m, args);
|
||||
|
||||
|
||||
addAttrList(m.attrs, "attr", sb, insnPrinter);
|
||||
addAttrList(m.invisibleAnnotations, "invisAnno", sb, insnPrinter);
|
||||
addAttrList(m.invisibleAnnotations, "invisLocalVarAnno", sb, insnPrinter);
|
||||
addAttrList(m.invisibleTypeAnnotations, "invisTypeAnno", sb, insnPrinter);
|
||||
addAttrList(m.invisibleAnnotations, "invisLocalVarAnno", sb,
|
||||
insnPrinter);
|
||||
addAttrList(m.invisibleTypeAnnotations, "invisTypeAnno", sb,
|
||||
insnPrinter);
|
||||
addAttrList(m.localVariables, "localVar", sb, insnPrinter);
|
||||
addAttrList(m.visibleAnnotations, "visAnno", sb, insnPrinter);
|
||||
addAttrList(m.visibleLocalVariableAnnotations, "visLocalVarAnno", sb, insnPrinter);
|
||||
addAttrList(m.visibleTypeAnnotations, "visTypeAnno", sb, insnPrinter);
|
||||
|
||||
addAttrList(m.visibleLocalVariableAnnotations, "visLocalVarAnno",
|
||||
sb, insnPrinter);
|
||||
addAttrList(m.visibleTypeAnnotations, "visTypeAnno", sb,
|
||||
insnPrinter);
|
||||
|
||||
for (Object o : m.tryCatchBlocks) {
|
||||
TryCatchBlockNode tcbn = (TryCatchBlockNode) o;
|
||||
sb.append(" ");
|
||||
|
@ -130,7 +136,7 @@ public class MethodNodeDecompiler {
|
|||
sb.append(" handled by L");
|
||||
sb.append(insnPrinter.resolveLabel(tcbn.handler));
|
||||
sb.append(": ");
|
||||
if(tcbn.type != null)
|
||||
if (tcbn.type != null)
|
||||
sb.append(tcbn.type);
|
||||
else
|
||||
sb.append("Type is null.");
|
||||
|
@ -141,12 +147,13 @@ public class MethodNodeDecompiler {
|
|||
sb.append(insn);
|
||||
sb.append(BytecodeViewer.nl);
|
||||
}
|
||||
sb.append(" }"+BytecodeViewer.nl);
|
||||
sb.append(" }" + BytecodeViewer.nl);
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
private static void addAttrList(List<?> list, String name, PrefixedStringBuilder sb, InstructionPrinter insnPrinter) {
|
||||
|
||||
private static void addAttrList(List<?> list, String name,
|
||||
PrefixedStringBuilder sb, InstructionPrinter insnPrinter) {
|
||||
if (list == null)
|
||||
return;
|
||||
if (list.size() > 0) {
|
||||
|
@ -161,11 +168,14 @@ public class MethodNodeDecompiler {
|
|||
sb.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String printAttr(Object o, InstructionPrinter insnPrinter) {
|
||||
if (o instanceof LocalVariableNode) {
|
||||
LocalVariableNode lvn = (LocalVariableNode) o;
|
||||
return "index=" + lvn.index + " , name=" + lvn.name + " , desc=" + lvn.desc + ", sig=" + lvn.signature + ", start=L" + insnPrinter.resolveLabel(lvn.start) + ", end=L" + insnPrinter.resolveLabel(lvn.end);
|
||||
return "index=" + lvn.index + " , name=" + lvn.name + " , desc="
|
||||
+ lvn.desc + ", sig=" + lvn.signature + ", start=L"
|
||||
+ insnPrinter.resolveLabel(lvn.start) + ", end=L"
|
||||
+ insnPrinter.resolveLabel(lvn.end);
|
||||
} else if (o instanceof AnnotationNode) {
|
||||
AnnotationNode an = (AnnotationNode) o;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -183,7 +193,7 @@ public class MethodNodeDecompiler {
|
|||
return "";
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String getAccessString(int access) {
|
||||
// public, protected, private, abstract, static,
|
||||
// final, synchronized, native & strictfp are permitted
|
||||
|
|
|
@ -3,33 +3,40 @@ package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
|
|||
/**
|
||||
*
|
||||
* @author Bibl
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class PrefixedStringBuilder {
|
||||
|
||||
|
||||
protected StringBuilder sb;
|
||||
protected String prefix;
|
||||
|
||||
|
||||
public PrefixedStringBuilder() {
|
||||
sb = new StringBuilder();
|
||||
}
|
||||
|
||||
|
||||
public PrefixedStringBuilder append(String s) {
|
||||
sb.append(s);
|
||||
if (s.contains("\n") && (prefix != null) && (prefix.length() > 0))// insert the prefix at every new line, overridable
|
||||
if (s.contains("\n") && (prefix != null) && (prefix.length() > 0))// insert
|
||||
// the
|
||||
// prefix
|
||||
// at
|
||||
// every
|
||||
// new
|
||||
// line,
|
||||
// overridable
|
||||
sb.append(prefix);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public PrefixedStringBuilder append(Object o) {
|
||||
return append(o.toString());
|
||||
}
|
||||
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
|
||||
public void trimPrefix(int amount) {
|
||||
if (prefix == null)
|
||||
return;
|
||||
|
@ -37,17 +44,17 @@ public class PrefixedStringBuilder {
|
|||
return;
|
||||
prefix = prefix.substring(0, prefix.length() - amount);
|
||||
}
|
||||
|
||||
|
||||
public void appendPrefix(String s) {
|
||||
if (prefix == null)
|
||||
prefix = "";
|
||||
prefix += s;
|
||||
}
|
||||
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return sb.toString();
|
||||
|
|
|
@ -3,12 +3,13 @@ package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
|
|||
import org.objectweb.asm.Type;
|
||||
|
||||
/**
|
||||
* Container class for type and name. Used to pass arguments and local variables around
|
||||
* Container class for type and name. Used to pass arguments and local variables
|
||||
* around
|
||||
*
|
||||
* @author Waterwolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class TypeAndName {
|
||||
public Type type = null;
|
||||
public String name = null;
|
||||
public Type type = null;
|
||||
public String name = null;
|
||||
}
|
|
@ -24,63 +24,65 @@ import the.bytecode.club.bytecodeviewer.JarUtils;
|
|||
/**
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class CFRDecompiler extends JavaDecompiler {
|
||||
|
||||
@Override
|
||||
public String decompileClassNode(ClassNode cn) {
|
||||
final ClassWriter cw = new ClassWriter(0);
|
||||
cn.accept(cw);
|
||||
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp";
|
||||
int fileNumber = getClassNumber(fileStart, ".class");
|
||||
|
||||
final File tempClass = new File(fileStart+fileNumber+".class");
|
||||
|
||||
try {
|
||||
final FileOutputStream fos = new FileOutputStream(tempClass);
|
||||
|
||||
fos.write(cw.toByteArray());
|
||||
|
||||
fos.close();
|
||||
} catch (final IOException e) {
|
||||
final ClassWriter cw = new ClassWriter(0);
|
||||
cn.accept(cw);
|
||||
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
|
||||
+ "temp";
|
||||
int fileNumber = getClassNumber(fileStart, ".class");
|
||||
|
||||
final File tempClass = new File(fileStart + fileNumber + ".class");
|
||||
|
||||
try {
|
||||
final FileOutputStream fos = new FileOutputStream(tempClass);
|
||||
|
||||
fos.write(cw.toByteArray());
|
||||
|
||||
fos.close();
|
||||
} catch (final IOException e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
|
||||
String fuckery = fuckery(fileStart);
|
||||
org.benf.cfr.reader.Main.main(generateMainMethod(tempClass.getAbsolutePath(), fuckery));
|
||||
|
||||
tempClass.delete();
|
||||
|
||||
String fuckery = fuckery(fileStart);
|
||||
org.benf.cfr.reader.Main.main(generateMainMethod(
|
||||
tempClass.getAbsolutePath(), fuckery));
|
||||
|
||||
return findFile(new File(fuckery).listFiles());
|
||||
tempClass.delete();
|
||||
|
||||
return findFile(new File(fuckery).listFiles());
|
||||
|
||||
}
|
||||
|
||||
|
||||
Random r = new Random();
|
||||
File f;
|
||||
|
||||
public String fuckery(String start) {
|
||||
boolean b = false;
|
||||
while(!b) {
|
||||
f = new File(start+r.nextInt(Integer.MAX_VALUE));
|
||||
if(!f.exists())
|
||||
while (!b) {
|
||||
f = new File(start + r.nextInt(Integer.MAX_VALUE));
|
||||
if (!f.exists())
|
||||
return f.toString();
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public String findFile(File[] fA) {
|
||||
for(File f : fA) {
|
||||
if(f.isDirectory())
|
||||
for (File f : fA) {
|
||||
if (f.isDirectory())
|
||||
return findFile(f.listFiles());
|
||||
else {
|
||||
String s = "";
|
||||
try {
|
||||
s = DiskReader.loadAsString(f.getAbsolutePath());
|
||||
} catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com";
|
||||
}
|
||||
|
@ -89,177 +91,203 @@ public class CFRDecompiler extends JavaDecompiler {
|
|||
}
|
||||
return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com";
|
||||
}
|
||||
|
||||
|
||||
public String[] generateMainMethod(String filePath, String outputPath) {
|
||||
return new String[] {
|
||||
filePath,
|
||||
"--outputdir",
|
||||
outputPath,
|
||||
"--decodeenumswitch",
|
||||
String.valueOf(BytecodeViewer.viewer.decodeenumswitch.isSelected()),
|
||||
"--sugarenums",
|
||||
String.valueOf(BytecodeViewer.viewer.sugarenums.isSelected()),
|
||||
"--decodestringswitch",
|
||||
String.valueOf(BytecodeViewer.viewer.decodestringswitch.isSelected()),
|
||||
"--arrayiter",
|
||||
String.valueOf(BytecodeViewer.viewer.arrayiter.isSelected()),
|
||||
"--collectioniter",
|
||||
String.valueOf(BytecodeViewer.viewer.collectioniter.isSelected()),
|
||||
"--innerclasses",
|
||||
String.valueOf(BytecodeViewer.viewer.innerclasses.isSelected()),
|
||||
"--removeboilerplate",
|
||||
String.valueOf(BytecodeViewer.viewer.removeboilerplate.isSelected()),
|
||||
"--removeinnerclasssynthetics",
|
||||
String.valueOf(BytecodeViewer.viewer.removeinnerclasssynthetics.isSelected()),
|
||||
"--decodelambdas",
|
||||
String.valueOf(BytecodeViewer.viewer.decodelambdas.isSelected()),
|
||||
"--hidebridgemethods",
|
||||
String.valueOf(BytecodeViewer.viewer.hidebridgemethods.isSelected()),
|
||||
"--liftconstructorinit",
|
||||
String.valueOf(BytecodeViewer.viewer.liftconstructorinit.isSelected()),
|
||||
"--removedeadmethods",
|
||||
String.valueOf(BytecodeViewer.viewer.removedeadmethods.isSelected()),
|
||||
"--removebadgenerics",
|
||||
String.valueOf(BytecodeViewer.viewer.removebadgenerics.isSelected()),
|
||||
"--sugarasserts",
|
||||
String.valueOf(BytecodeViewer.viewer.sugarasserts.isSelected()),
|
||||
"--sugarboxing",
|
||||
String.valueOf(BytecodeViewer.viewer.sugarboxing.isSelected()),
|
||||
"--showversion",
|
||||
String.valueOf(BytecodeViewer.viewer.showversion.isSelected()),
|
||||
"--decodefinally",
|
||||
String.valueOf(BytecodeViewer.viewer.decodefinally.isSelected()),
|
||||
"--tidymonitors",
|
||||
String.valueOf(BytecodeViewer.viewer.tidymonitors.isSelected()),
|
||||
"--lenient",
|
||||
String.valueOf(BytecodeViewer.viewer.lenient.isSelected()),
|
||||
"--dumpclasspath",
|
||||
String.valueOf(BytecodeViewer.viewer.dumpclasspath.isSelected()),
|
||||
"--comments",
|
||||
String.valueOf(BytecodeViewer.viewer.comments.isSelected()),
|
||||
"--forcetopsort",
|
||||
String.valueOf(BytecodeViewer.viewer.forcetopsort.isSelected()),
|
||||
"--forcetopsortaggress",
|
||||
String.valueOf(BytecodeViewer.viewer.forcetopsortaggress.isSelected()),
|
||||
"--stringbuffer",
|
||||
String.valueOf(BytecodeViewer.viewer.stringbuffer.isSelected()),
|
||||
"--stringbuilder",
|
||||
String.valueOf(BytecodeViewer.viewer.stringbuilder.isSelected()),
|
||||
"--silent",
|
||||
String.valueOf(BytecodeViewer.viewer.silent.isSelected()),
|
||||
"--recover",
|
||||
String.valueOf(BytecodeViewer.viewer.recover.isSelected()),
|
||||
"--eclipse",
|
||||
String.valueOf(BytecodeViewer.viewer.eclipse.isSelected()),
|
||||
"--override",
|
||||
String.valueOf(BytecodeViewer.viewer.override.isSelected()),
|
||||
"--showinferrable",
|
||||
String.valueOf(BytecodeViewer.viewer.showinferrable.isSelected()),
|
||||
"--aexagg",
|
||||
String.valueOf(BytecodeViewer.viewer.aexagg.isSelected()),
|
||||
"--forcecondpropagate",
|
||||
String.valueOf(BytecodeViewer.viewer.forcecondpropagate.isSelected()),
|
||||
"--hideutf",
|
||||
String.valueOf(BytecodeViewer.viewer.hideutf.isSelected()),
|
||||
"--hidelongstrings",
|
||||
String.valueOf(BytecodeViewer.viewer.hidelongstrings.isSelected()),
|
||||
"--commentmonitors",
|
||||
String.valueOf(BytecodeViewer.viewer.commentmonitor.isSelected()),
|
||||
"--allowcorrecting",
|
||||
String.valueOf(BytecodeViewer.viewer.allowcorrecting.isSelected()),
|
||||
"--labelledblocks",
|
||||
String.valueOf(BytecodeViewer.viewer.labelledblocks.isSelected()),
|
||||
"--j14classobj",
|
||||
String.valueOf(BytecodeViewer.viewer.j14classobj.isSelected()),
|
||||
"--hidelangimports",
|
||||
String.valueOf(BytecodeViewer.viewer.hidelangimports.isSelected()),
|
||||
"--recovertypeclash",
|
||||
String.valueOf(BytecodeViewer.viewer.recoverytypeclash.isSelected()),
|
||||
"--recovertypehints",
|
||||
String.valueOf(BytecodeViewer.viewer.recoverytypehints.isSelected()),
|
||||
"--forcereturningifs",
|
||||
String.valueOf(BytecodeViewer.viewer.forceturningifs.isSelected()),
|
||||
"--forloopaggcapture",
|
||||
String.valueOf(BytecodeViewer.viewer.forloopaggcapture.isSelected()),
|
||||
};
|
||||
filePath,
|
||||
"--outputdir",
|
||||
outputPath,
|
||||
"--decodeenumswitch",
|
||||
String.valueOf(BytecodeViewer.viewer.decodeenumswitch
|
||||
.isSelected()),
|
||||
"--sugarenums",
|
||||
String.valueOf(BytecodeViewer.viewer.sugarenums.isSelected()),
|
||||
"--decodestringswitch",
|
||||
String.valueOf(BytecodeViewer.viewer.decodestringswitch
|
||||
.isSelected()),
|
||||
"--arrayiter",
|
||||
String.valueOf(BytecodeViewer.viewer.arrayiter.isSelected()),
|
||||
"--collectioniter",
|
||||
String.valueOf(BytecodeViewer.viewer.collectioniter
|
||||
.isSelected()),
|
||||
"--innerclasses",
|
||||
String.valueOf(BytecodeViewer.viewer.innerclasses.isSelected()),
|
||||
"--removeboilerplate",
|
||||
String.valueOf(BytecodeViewer.viewer.removeboilerplate
|
||||
.isSelected()),
|
||||
"--removeinnerclasssynthetics",
|
||||
String.valueOf(BytecodeViewer.viewer.removeinnerclasssynthetics
|
||||
.isSelected()),
|
||||
"--decodelambdas",
|
||||
String.valueOf(BytecodeViewer.viewer.decodelambdas.isSelected()),
|
||||
"--hidebridgemethods",
|
||||
String.valueOf(BytecodeViewer.viewer.hidebridgemethods
|
||||
.isSelected()),
|
||||
"--liftconstructorinit",
|
||||
String.valueOf(BytecodeViewer.viewer.liftconstructorinit
|
||||
.isSelected()),
|
||||
"--removedeadmethods",
|
||||
String.valueOf(BytecodeViewer.viewer.removedeadmethods
|
||||
.isSelected()),
|
||||
"--removebadgenerics",
|
||||
String.valueOf(BytecodeViewer.viewer.removebadgenerics
|
||||
.isSelected()),
|
||||
"--sugarasserts",
|
||||
String.valueOf(BytecodeViewer.viewer.sugarasserts.isSelected()),
|
||||
"--sugarboxing",
|
||||
String.valueOf(BytecodeViewer.viewer.sugarboxing.isSelected()),
|
||||
"--showversion",
|
||||
String.valueOf(BytecodeViewer.viewer.showversion.isSelected()),
|
||||
"--decodefinally",
|
||||
String.valueOf(BytecodeViewer.viewer.decodefinally.isSelected()),
|
||||
"--tidymonitors",
|
||||
String.valueOf(BytecodeViewer.viewer.tidymonitors.isSelected()),
|
||||
"--lenient",
|
||||
String.valueOf(BytecodeViewer.viewer.lenient.isSelected()),
|
||||
"--dumpclasspath",
|
||||
String.valueOf(BytecodeViewer.viewer.dumpclasspath.isSelected()),
|
||||
"--comments",
|
||||
String.valueOf(BytecodeViewer.viewer.comments.isSelected()),
|
||||
"--forcetopsort",
|
||||
String.valueOf(BytecodeViewer.viewer.forcetopsort.isSelected()),
|
||||
"--forcetopsortaggress",
|
||||
String.valueOf(BytecodeViewer.viewer.forcetopsortaggress
|
||||
.isSelected()),
|
||||
"--stringbuffer",
|
||||
String.valueOf(BytecodeViewer.viewer.stringbuffer.isSelected()),
|
||||
"--stringbuilder",
|
||||
String.valueOf(BytecodeViewer.viewer.stringbuilder.isSelected()),
|
||||
"--silent",
|
||||
String.valueOf(BytecodeViewer.viewer.silent.isSelected()),
|
||||
"--recover",
|
||||
String.valueOf(BytecodeViewer.viewer.recover.isSelected()),
|
||||
"--eclipse",
|
||||
String.valueOf(BytecodeViewer.viewer.eclipse.isSelected()),
|
||||
"--override",
|
||||
String.valueOf(BytecodeViewer.viewer.override.isSelected()),
|
||||
"--showinferrable",
|
||||
String.valueOf(BytecodeViewer.viewer.showinferrable
|
||||
.isSelected()),
|
||||
"--aexagg",
|
||||
String.valueOf(BytecodeViewer.viewer.aexagg.isSelected()),
|
||||
"--forcecondpropagate",
|
||||
String.valueOf(BytecodeViewer.viewer.forcecondpropagate
|
||||
.isSelected()),
|
||||
"--hideutf",
|
||||
String.valueOf(BytecodeViewer.viewer.hideutf.isSelected()),
|
||||
"--hidelongstrings",
|
||||
String.valueOf(BytecodeViewer.viewer.hidelongstrings
|
||||
.isSelected()),
|
||||
"--commentmonitors",
|
||||
String.valueOf(BytecodeViewer.viewer.commentmonitor
|
||||
.isSelected()),
|
||||
"--allowcorrecting",
|
||||
String.valueOf(BytecodeViewer.viewer.allowcorrecting
|
||||
.isSelected()),
|
||||
"--labelledblocks",
|
||||
String.valueOf(BytecodeViewer.viewer.labelledblocks
|
||||
.isSelected()),
|
||||
"--j14classobj",
|
||||
String.valueOf(BytecodeViewer.viewer.j14classobj.isSelected()),
|
||||
"--hidelangimports",
|
||||
String.valueOf(BytecodeViewer.viewer.hidelangimports
|
||||
.isSelected()),
|
||||
"--recovertypeclash",
|
||||
String.valueOf(BytecodeViewer.viewer.recoverytypeclash
|
||||
.isSelected()),
|
||||
"--recovertypehints",
|
||||
String.valueOf(BytecodeViewer.viewer.recoverytypehints
|
||||
.isSelected()),
|
||||
"--forcereturningifs",
|
||||
String.valueOf(BytecodeViewer.viewer.forceturningifs
|
||||
.isSelected()),
|
||||
"--forloopaggcapture",
|
||||
String.valueOf(BytecodeViewer.viewer.forloopaggcapture
|
||||
.isSelected()), };
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
@Override
|
||||
public void decompileToZip(String zipName) {
|
||||
File tempZip = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
|
||||
if(tempZip.exists())
|
||||
File tempZip = new File(BytecodeViewer.tempDirectory
|
||||
+ BytecodeViewer.fs + "temp.jar");
|
||||
if (tempZip.exists())
|
||||
tempZip.delete();
|
||||
|
||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath());
|
||||
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp";
|
||||
|
||||
String fuckery = fuckery(fileStart);
|
||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
|
||||
tempZip.getAbsolutePath());
|
||||
|
||||
org.benf.cfr.reader.Main.main(generateMainMethod(tempZip.getAbsolutePath(), fuckery));
|
||||
|
||||
tempZip.delete();
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
|
||||
+ "temp";
|
||||
|
||||
String fuckery = fuckery(fileStart);
|
||||
|
||||
org.benf.cfr.reader.Main.main(generateMainMethod(
|
||||
tempZip.getAbsolutePath(), fuckery));
|
||||
|
||||
tempZip.delete();
|
||||
File fuck = new File(fuckery);
|
||||
|
||||
|
||||
try {
|
||||
zip(fuck, new File(zipName));
|
||||
} catch (IOException e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
|
||||
|
||||
fuck.delete();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
public void zip(File directory, File zipfile) throws IOException {
|
||||
java.net.URI base = directory.toURI();
|
||||
Deque<File> queue = new LinkedList<File>();
|
||||
queue.push(directory);
|
||||
OutputStream out = new FileOutputStream(zipfile);
|
||||
Closeable res = out;
|
||||
try {
|
||||
ZipOutputStream zout = new ZipOutputStream(out);
|
||||
res = zout;
|
||||
while (!queue.isEmpty()) {
|
||||
directory = queue.pop();
|
||||
for (File kid : directory.listFiles()) {
|
||||
String name = base.relativize(kid.toURI()).getPath();
|
||||
if (kid.isDirectory()) {
|
||||
queue.push(kid);
|
||||
name = name.endsWith("/") ? name : name + "/";
|
||||
zout.putNextEntry(new ZipEntry(name));
|
||||
} else {
|
||||
zout.putNextEntry(new ZipEntry(name));
|
||||
copy(kid, zout);
|
||||
zout.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
res.close();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
java.net.URI base = directory.toURI();
|
||||
Deque<File> queue = new LinkedList<File>();
|
||||
queue.push(directory);
|
||||
OutputStream out = new FileOutputStream(zipfile);
|
||||
Closeable res = out;
|
||||
try {
|
||||
ZipOutputStream zout = new ZipOutputStream(out);
|
||||
res = zout;
|
||||
while (!queue.isEmpty()) {
|
||||
directory = queue.pop();
|
||||
for (File kid : directory.listFiles()) {
|
||||
String name = base.relativize(kid.toURI()).getPath();
|
||||
if (kid.isDirectory()) {
|
||||
queue.push(kid);
|
||||
name = name.endsWith("/") ? name : name + "/";
|
||||
zout.putNextEntry(new ZipEntry(name));
|
||||
} else {
|
||||
zout.putNextEntry(new ZipEntry(name));
|
||||
copy(kid, zout);
|
||||
zout.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
res.close();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void copy(InputStream in, OutputStream out) throws IOException {
|
||||
byte[] buffer = new byte[1024];
|
||||
while (true) {
|
||||
int readCount = in.read(buffer);
|
||||
if (readCount < 0) {
|
||||
break;
|
||||
}
|
||||
out.write(buffer, 0, readCount);
|
||||
}
|
||||
}
|
||||
private static void copy(InputStream in, OutputStream out)
|
||||
throws IOException {
|
||||
byte[] buffer = new byte[1024];
|
||||
while (true) {
|
||||
int readCount = in.read(buffer);
|
||||
if (readCount < 0) {
|
||||
break;
|
||||
}
|
||||
out.write(buffer, 0, readCount);
|
||||
}
|
||||
}
|
||||
|
||||
private static void copy(File file, OutputStream out) throws IOException {
|
||||
InputStream in = new FileInputStream(file);
|
||||
try {
|
||||
copy(in, out);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void copy(File file, OutputStream out) throws IOException {
|
||||
InputStream in = new FileInputStream(file);
|
||||
try {
|
||||
copy(in, out);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,101 +17,109 @@ import the.bytecode.club.bytecodeviewer.JarUtils;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class FernFlowerDecompiler extends JavaDecompiler {
|
||||
|
||||
|
||||
@Override
|
||||
public void decompileToZip(String zipName) {
|
||||
File tempZip = new File(BytecodeViewer.tempDirectory + "temp.zip");
|
||||
if(tempZip.exists())
|
||||
if (tempZip.exists())
|
||||
tempZip.delete();
|
||||
|
||||
File f = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs +"temp" + BytecodeViewer.fs);
|
||||
f.mkdir();
|
||||
|
||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath());
|
||||
|
||||
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempZip.getAbsolutePath(), BytecodeViewer.tempDirectory + "./temp/"));
|
||||
File tempZip2 = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp" + BytecodeViewer.fs +tempZip.getName());
|
||||
if(tempZip2.exists())
|
||||
tempZip2.renameTo(new File(zipName));
|
||||
|
||||
tempZip.delete();
|
||||
new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp").delete();
|
||||
File f = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs
|
||||
+ "temp" + BytecodeViewer.fs);
|
||||
f.mkdir();
|
||||
|
||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
|
||||
tempZip.getAbsolutePath());
|
||||
|
||||
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler
|
||||
.main(generateMainMethod(tempZip.getAbsolutePath(),
|
||||
BytecodeViewer.tempDirectory + "./temp/"));
|
||||
File tempZip2 = new File(BytecodeViewer.tempDirectory
|
||||
+ BytecodeViewer.fs + "temp" + BytecodeViewer.fs
|
||||
+ tempZip.getName());
|
||||
if (tempZip2.exists())
|
||||
tempZip2.renameTo(new File(zipName));
|
||||
|
||||
tempZip.delete();
|
||||
new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp")
|
||||
.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String decompileClassNode(final ClassNode cn) {
|
||||
final ClassWriter cw = new ClassWriter(0);
|
||||
cn.accept(cw);
|
||||
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp";
|
||||
int fileNumber = getClassNumber(fileStart, ".class");
|
||||
|
||||
final File tempClass = new File(fileStart+fileNumber+".class");
|
||||
|
||||
try {
|
||||
final FileOutputStream fos = new FileOutputStream(tempClass);
|
||||
|
||||
fos.write(cw.toByteArray());
|
||||
|
||||
fos.close();
|
||||
} catch (final IOException e) {
|
||||
public String decompileClassNode(final ClassNode cn) {
|
||||
final ClassWriter cw = new ClassWriter(0);
|
||||
cn.accept(cw);
|
||||
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
|
||||
+ "temp";
|
||||
int fileNumber = getClassNumber(fileStart, ".class");
|
||||
|
||||
final File tempClass = new File(fileStart + fileNumber + ".class");
|
||||
|
||||
try {
|
||||
final FileOutputStream fos = new FileOutputStream(tempClass);
|
||||
|
||||
fos.write(cw.toByteArray());
|
||||
|
||||
fos.close();
|
||||
} catch (final IOException e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
|
||||
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempClass.getAbsolutePath(), "."));
|
||||
|
||||
tempClass.delete();
|
||||
|
||||
final File outputJava = new File("temp"+fileNumber+".java");
|
||||
if (outputJava.exists()) {
|
||||
String s;
|
||||
}
|
||||
|
||||
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler
|
||||
.main(generateMainMethod(tempClass.getAbsolutePath(), "."));
|
||||
|
||||
tempClass.delete();
|
||||
|
||||
final File outputJava = new File("temp" + fileNumber + ".java");
|
||||
if (outputJava.exists()) {
|
||||
String s;
|
||||
try {
|
||||
s = DiskReader.loadAsString(outputJava.getAbsolutePath());
|
||||
|
||||
outputJava.delete();
|
||||
|
||||
return s;
|
||||
|
||||
outputJava.delete();
|
||||
|
||||
return s;
|
||||
} catch (Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(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";
|
||||
}
|
||||
|
||||
private String[] generateMainMethod(String className, String folder) {
|
||||
return new String[] {
|
||||
"-rbr="+r(BytecodeViewer.viewer.rbr.isSelected()),
|
||||
"-rsy="+r(BytecodeViewer.viewer.rsy.isSelected()),
|
||||
"-din="+r(BytecodeViewer.viewer.din.isSelected()),
|
||||
"-dc4="+r(BytecodeViewer.viewer.dc4.isSelected()),
|
||||
"-das="+r(BytecodeViewer.viewer.das.isSelected()),
|
||||
"-hes="+r(BytecodeViewer.viewer.hes.isSelected()),
|
||||
"-hdc="+r(BytecodeViewer.viewer.hdc.isSelected()),
|
||||
"-dgs="+r(BytecodeViewer.viewer.dgs.isSelected()),
|
||||
"-ner="+r(BytecodeViewer.viewer.ner.isSelected()),
|
||||
"-den="+r(BytecodeViewer.viewer.den.isSelected()),
|
||||
"-rgn="+r(BytecodeViewer.viewer.rgn.isSelected()),
|
||||
"-bto="+r(BytecodeViewer.viewer.bto.isSelected()),
|
||||
"-nns="+r(BytecodeViewer.viewer.nns.isSelected()),
|
||||
"-uto="+r(BytecodeViewer.viewer.uto.isSelected()),
|
||||
"-udv="+r(BytecodeViewer.viewer.udv.isSelected()),
|
||||
"-rer="+r(BytecodeViewer.viewer.rer.isSelected()),
|
||||
"-fdi="+r(BytecodeViewer.viewer.fdi.isSelected()),
|
||||
"-asc="+r(BytecodeViewer.viewer.asc.isSelected()),
|
||||
className,
|
||||
folder};
|
||||
}
|
||||
|
||||
private String r(boolean b) {
|
||||
if(b) {
|
||||
return "1";
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
private String[] generateMainMethod(String className, String folder) {
|
||||
return new String[] {
|
||||
"-rbr=" + r(BytecodeViewer.viewer.rbr.isSelected()),
|
||||
"-rsy=" + r(BytecodeViewer.viewer.rsy.isSelected()),
|
||||
"-din=" + r(BytecodeViewer.viewer.din.isSelected()),
|
||||
"-dc4=" + r(BytecodeViewer.viewer.dc4.isSelected()),
|
||||
"-das=" + r(BytecodeViewer.viewer.das.isSelected()),
|
||||
"-hes=" + r(BytecodeViewer.viewer.hes.isSelected()),
|
||||
"-hdc=" + r(BytecodeViewer.viewer.hdc.isSelected()),
|
||||
"-dgs=" + r(BytecodeViewer.viewer.dgs.isSelected()),
|
||||
"-ner=" + r(BytecodeViewer.viewer.ner.isSelected()),
|
||||
"-den=" + r(BytecodeViewer.viewer.den.isSelected()),
|
||||
"-rgn=" + r(BytecodeViewer.viewer.rgn.isSelected()),
|
||||
"-bto=" + r(BytecodeViewer.viewer.bto.isSelected()),
|
||||
"-nns=" + r(BytecodeViewer.viewer.nns.isSelected()),
|
||||
"-uto=" + r(BytecodeViewer.viewer.uto.isSelected()),
|
||||
"-udv=" + r(BytecodeViewer.viewer.udv.isSelected()),
|
||||
"-rer=" + r(BytecodeViewer.viewer.rer.isSelected()),
|
||||
"-fdi=" + r(BytecodeViewer.viewer.fdi.isSelected()),
|
||||
"-asc=" + r(BytecodeViewer.viewer.asc.isSelected()), className,
|
||||
folder };
|
||||
}
|
||||
|
||||
private String r(boolean b) {
|
||||
if (b) {
|
||||
return "1";
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,25 +7,27 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
/**
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class JavaDecompiler {
|
||||
|
||||
public abstract String decompileClassNode(ClassNode cn);
|
||||
|
||||
public abstract void decompileToZip(String zipName);
|
||||
|
||||
File tempF = null;
|
||||
public int getClassNumber(String start, String ext) {
|
||||
boolean b = true;
|
||||
int i = 0;
|
||||
while(b) {
|
||||
tempF = new File(start + i + ext);
|
||||
if(!tempF.exists())
|
||||
b = false;
|
||||
else
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
File tempF = null;
|
||||
|
||||
public int getClassNumber(String start, String ext) {
|
||||
boolean b = true;
|
||||
int i = 0;
|
||||
while (b) {
|
||||
tempF = new File(start + i + ext);
|
||||
if (!tempF.exists())
|
||||
b = false;
|
||||
else
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,100 +41,118 @@ import the.bytecode.club.bytecodeviewer.JarUtils;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author DeathMarine
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class ProcyonDecompiler extends JavaDecompiler {
|
||||
|
||||
public DecompilerSettings getDecompilerSettings() {
|
||||
DecompilerSettings settings = new DecompilerSettings();
|
||||
settings.setAlwaysGenerateExceptionVariableForCatchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_6.isSelected());
|
||||
settings.setExcludeNestedTypes(BytecodeViewer.viewer.chckbxmntmNewCheckItem_11.isSelected());
|
||||
settings.setShowDebugLineNumbers(BytecodeViewer.viewer.chckbxmntmShowDebugLine.isSelected());
|
||||
settings.setIncludeLineNumbersInBytecode(BytecodeViewer.viewer.chckbxmntmNewCheckItem_3.isSelected());
|
||||
settings.setIncludeErrorDiagnostics(BytecodeViewer.viewer.chckbxmntmNewCheckItem_4.isSelected());
|
||||
settings.setShowSyntheticMembers(BytecodeViewer.viewer.chckbxmntmNewCheckItem_7.isSelected());
|
||||
settings.setSimplifyMemberReferences(BytecodeViewer.viewer.chckbxmntmSimplifyMemberReferences.isSelected());
|
||||
settings.setMergeVariables(BytecodeViewer.viewer.mnMergeVariables.isSelected());
|
||||
settings.setForceExplicitTypeArguments(BytecodeViewer.viewer.chckbxmntmNewCheckItem_8.isSelected());
|
||||
settings.setForceExplicitImports(BytecodeViewer.viewer.chckbxmntmNewCheckItem_9.isSelected());
|
||||
settings.setFlattenSwitchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_10.isSelected());
|
||||
settings.setRetainPointlessSwitches(BytecodeViewer.viewer.chckbxmntmNewCheckItem_2.isSelected());
|
||||
settings.setRetainRedundantCasts(BytecodeViewer.viewer.chckbxmntmNewCheckItem_5.isSelected());
|
||||
settings.setUnicodeOutputEnabled(BytecodeViewer.viewer.chckbxmntmNewCheckItem_1.isSelected());
|
||||
settings.setAlwaysGenerateExceptionVariableForCatchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_6
|
||||
.isSelected());
|
||||
settings.setExcludeNestedTypes(BytecodeViewer.viewer.chckbxmntmNewCheckItem_11
|
||||
.isSelected());
|
||||
settings.setShowDebugLineNumbers(BytecodeViewer.viewer.chckbxmntmShowDebugLine
|
||||
.isSelected());
|
||||
settings.setIncludeLineNumbersInBytecode(BytecodeViewer.viewer.chckbxmntmNewCheckItem_3
|
||||
.isSelected());
|
||||
settings.setIncludeErrorDiagnostics(BytecodeViewer.viewer.chckbxmntmNewCheckItem_4
|
||||
.isSelected());
|
||||
settings.setShowSyntheticMembers(BytecodeViewer.viewer.chckbxmntmNewCheckItem_7
|
||||
.isSelected());
|
||||
settings.setSimplifyMemberReferences(BytecodeViewer.viewer.chckbxmntmSimplifyMemberReferences
|
||||
.isSelected());
|
||||
settings.setMergeVariables(BytecodeViewer.viewer.mnMergeVariables
|
||||
.isSelected());
|
||||
settings.setForceExplicitTypeArguments(BytecodeViewer.viewer.chckbxmntmNewCheckItem_8
|
||||
.isSelected());
|
||||
settings.setForceExplicitImports(BytecodeViewer.viewer.chckbxmntmNewCheckItem_9
|
||||
.isSelected());
|
||||
settings.setFlattenSwitchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_10
|
||||
.isSelected());
|
||||
settings.setRetainPointlessSwitches(BytecodeViewer.viewer.chckbxmntmNewCheckItem_2
|
||||
.isSelected());
|
||||
settings.setRetainRedundantCasts(BytecodeViewer.viewer.chckbxmntmNewCheckItem_5
|
||||
.isSelected());
|
||||
settings.setUnicodeOutputEnabled(BytecodeViewer.viewer.chckbxmntmNewCheckItem_1
|
||||
.isSelected());
|
||||
settings.setFormattingOptions(JavaFormattingOptions.createDefault());
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String decompileClassNode(ClassNode cn) {
|
||||
try {
|
||||
final ClassWriter cw = new ClassWriter(0);
|
||||
cn.accept(cw);
|
||||
final ClassWriter cw = new ClassWriter(0);
|
||||
cn.accept(cw);
|
||||
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp";
|
||||
int fileNumber = getClassNumber(fileStart, ".class");
|
||||
|
||||
final File tempClass = new File(fileStart+fileNumber+".class");
|
||||
|
||||
try {
|
||||
final FileOutputStream fos = new FileOutputStream(tempClass);
|
||||
|
||||
fos.write(cw.toByteArray());
|
||||
|
||||
fos.close();
|
||||
} catch (final IOException e) {
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
|
||||
+ "temp";
|
||||
int fileNumber = getClassNumber(fileStart, ".class");
|
||||
|
||||
final File tempClass = new File(fileStart + fileNumber + ".class");
|
||||
|
||||
try {
|
||||
final FileOutputStream fos = new FileOutputStream(tempClass);
|
||||
|
||||
fos.write(cw.toByteArray());
|
||||
|
||||
fos.close();
|
||||
} catch (final IOException e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DecompilerSettings settings = getDecompilerSettings();
|
||||
|
||||
|
||||
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
|
||||
MetadataSystem metadataSystem = new MetadataSystem(typeLoader);
|
||||
TypeReference type = metadataSystem.lookupType(tempClass.getCanonicalPath());
|
||||
TypeReference type = metadataSystem.lookupType(tempClass
|
||||
.getCanonicalPath());
|
||||
|
||||
DecompilationOptions decompilationOptions = new DecompilationOptions();
|
||||
decompilationOptions.setSettings(DecompilerSettings.javaDefaults());
|
||||
decompilationOptions.setFullDecompilation(true);
|
||||
|
||||
|
||||
TypeDefinition resolvedType = null;
|
||||
if (type == null || ((resolvedType = type.resolve()) == null)) {
|
||||
throw new Exception("Unable to resolve type.");
|
||||
}
|
||||
StringWriter stringwriter = new StringWriter();
|
||||
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(stringwriter), decompilationOptions);
|
||||
settings.getLanguage().decompileType(resolvedType,
|
||||
new PlainTextOutput(stringwriter), decompilationOptions);
|
||||
String decompiledSource = stringwriter.toString();
|
||||
|
||||
|
||||
return decompiledSource;
|
||||
} catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(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";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decompileToZip(String zipName) {
|
||||
File tempZip = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
|
||||
if(tempZip.exists())
|
||||
File tempZip = new File(BytecodeViewer.tempDirectory
|
||||
+ BytecodeViewer.fs + "temp.jar");
|
||||
if (tempZip.exists())
|
||||
tempZip.delete();
|
||||
|
||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath());
|
||||
|
||||
try {
|
||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
|
||||
tempZip.getAbsolutePath());
|
||||
|
||||
try {
|
||||
doSaveJarDecompiled(tempZip, new File(zipName));
|
||||
} catch (Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @author DeathMarine
|
||||
*
|
||||
*
|
||||
*/
|
||||
private void doSaveJarDecompiled(File inFile, File outFile) throws Exception {
|
||||
private void doSaveJarDecompiled(File inFile, File outFile)
|
||||
throws Exception {
|
||||
try (JarFile jfile = new JarFile(inFile);
|
||||
FileOutputStream dest = new FileOutputStream(outFile);
|
||||
BufferedOutputStream buffDest = new BufferedOutputStream(dest);
|
||||
|
@ -155,19 +173,24 @@ public class ProcyonDecompiler extends JavaDecompiler {
|
|||
while (ent.hasMoreElements()) {
|
||||
JarEntry entry = ent.nextElement();
|
||||
if (entry.getName().endsWith(".class")) {
|
||||
JarEntry etn = new JarEntry(entry.getName().replace(".class", ".java"));
|
||||
if(history.add(etn)){
|
||||
JarEntry etn = new JarEntry(entry.getName().replace(
|
||||
".class", ".java"));
|
||||
if (history.add(etn)) {
|
||||
out.putNextEntry(etn);
|
||||
try {
|
||||
String internalName = StringUtilities.removeRight(entry.getName(), ".class");
|
||||
TypeReference type = metadataSystem.lookupType(internalName);
|
||||
String internalName = StringUtilities.removeRight(
|
||||
entry.getName(), ".class");
|
||||
TypeReference type = metadataSystem
|
||||
.lookupType(internalName);
|
||||
TypeDefinition resolvedType = null;
|
||||
if ((type == null) || ((resolvedType = type.resolve()) == null)) {
|
||||
if ((type == null)
|
||||
|| ((resolvedType = type.resolve()) == null)) {
|
||||
throw new Exception("Unable to resolve type.");
|
||||
}
|
||||
Writer writer = new OutputStreamWriter(out);
|
||||
settings.getLanguage().decompileType(resolvedType,
|
||||
new PlainTextOutput(writer), decompilationOptions);
|
||||
new PlainTextOutput(writer),
|
||||
decompilationOptions);
|
||||
writer.flush();
|
||||
} finally {
|
||||
out.closeEntry();
|
||||
|
@ -176,7 +199,7 @@ public class ProcyonDecompiler extends JavaDecompiler {
|
|||
} else {
|
||||
try {
|
||||
JarEntry etn = new JarEntry(entry.getName());
|
||||
if(history.add(etn))
|
||||
if (history.add(etn))
|
||||
continue;
|
||||
history.add(etn);
|
||||
out.putNextEntry(etn);
|
||||
|
@ -196,7 +219,8 @@ public class ProcyonDecompiler extends JavaDecompiler {
|
|||
out.closeEntry();
|
||||
}
|
||||
} catch (ZipException ze) {
|
||||
// some jar-s contain duplicate pom.xml entries: ignore it
|
||||
// some jar-s contain duplicate pom.xml entries: ignore
|
||||
// it
|
||||
if (!ze.getMessage().contains("duplicate")) {
|
||||
throw ze;
|
||||
}
|
||||
|
@ -205,37 +229,37 @@ public class ProcyonDecompiler extends JavaDecompiler {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author DeathMarine
|
||||
*
|
||||
*
|
||||
*/
|
||||
public final class LuytenTypeLoader implements ITypeLoader {
|
||||
private final List<ITypeLoader> _typeLoaders;
|
||||
private final List<ITypeLoader> _typeLoaders;
|
||||
|
||||
public LuytenTypeLoader() {
|
||||
_typeLoaders = new ArrayList<ITypeLoader>();
|
||||
_typeLoaders.add(new InputTypeLoader());
|
||||
}
|
||||
public LuytenTypeLoader() {
|
||||
_typeLoaders = new ArrayList<ITypeLoader>();
|
||||
_typeLoaders.add(new InputTypeLoader());
|
||||
}
|
||||
|
||||
public final List<ITypeLoader> getTypeLoaders() {
|
||||
return _typeLoaders;
|
||||
}
|
||||
public final List<ITypeLoader> getTypeLoaders() {
|
||||
return _typeLoaders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryLoadType(final String internalName, final Buffer buffer) {
|
||||
for (final ITypeLoader typeLoader : _typeLoaders) {
|
||||
if (typeLoader.tryLoadType(internalName, buffer)) {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean tryLoadType(final String internalName,
|
||||
final Buffer buffer) {
|
||||
for (final ITypeLoader typeLoader : _typeLoaders) {
|
||||
if (typeLoader.tryLoadType(internalName, buffer)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
buffer.reset();
|
||||
}
|
||||
buffer.reset();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,17 +13,20 @@ import java.awt.Color;
|
|||
|
||||
public class AboutWindow extends JFrame {
|
||||
public AboutWindow() {
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
setSize(new Dimension(446, 374));
|
||||
setType(Type.UTILITY);
|
||||
setTitle("Bytecode Viewer - About");
|
||||
getContentPane().setLayout(new CardLayout(0, 0));
|
||||
|
||||
|
||||
JTextArea txtrBytecodeViewerIs = new JTextArea();
|
||||
txtrBytecodeViewerIs.setDisabledTextColor(Color.BLACK);
|
||||
txtrBytecodeViewerIs.setWrapStyleWord(true);
|
||||
getContentPane().add(txtrBytecodeViewerIs, "name_140466526081695");
|
||||
txtrBytecodeViewerIs.setText("Bytecode Viewer " + BytecodeViewer.version+ " is an open source program\r\ndeveloped by Konloch (konloch@gmail.com)\r\nDir: "+BytecodeViewer.getBCVDirectory()+"\r\n\r\nIt uses code from the following:\r\n J-RET by WaterWolf\r\n JHexPane by Sam Koivu\r\n RSyntaxTextArea by Bobbylight\r\n Commons IO by Apache\r\n ASM by OW2\r\n CFIDE by Bibl\r\n FernFlower by Stiver\r\n Procyon by Mstrobel\r\n CFR by Lee Benfield\r\n\r\nIf you're interested in Java Reverse\r\nEngineering, join The Bytecode Club\r\nhttp://the.bytecode.club");
|
||||
txtrBytecodeViewerIs
|
||||
.setText("Bytecode Viewer 2.3.0 is an open source program\r\ndeveloped by Konloch (konloch@gmail.com)\r\nDir: "
|
||||
+ BytecodeViewer.getBCVDirectory()
|
||||
+ "\r\n\r\nIt uses code from the following:\r\n J-RET by WaterWolf\r\n JHexPane by Sam Koivu\r\n RSyntaxTextArea by Bobbylight\r\n Commons IO by Apache\r\n ASM by OW2\r\n CFIDE by Bibl\r\n FernFlower by Stiver\r\n Procyon by Mstrobel\r\n CFR by Lee Benfield\r\n\r\nIf you're interested in Java Reverse\r\nEngineering, join The Bytecode Club\r\nhttps://the.bytecode.club");
|
||||
txtrBytecodeViewerIs.setEnabled(false);
|
||||
this.setResizable(false);
|
||||
this.setLocationRelativeTo(null);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -22,112 +22,128 @@ import javax.swing.JLabel;
|
|||
|
||||
public class EZInjectionOptions extends JFrame {
|
||||
public EZInjectionOptions() {
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
setSize(new Dimension(250, 454));
|
||||
setResizable(false);
|
||||
setTitle("EZ Injection Options");
|
||||
getContentPane().setLayout(null);
|
||||
|
||||
final JCheckBox accessModifiers = new JCheckBox("Set All Access Modifiers Public");
|
||||
|
||||
final JCheckBox accessModifiers = new JCheckBox(
|
||||
"Set All Access Modifiers Public");
|
||||
accessModifiers.setSelected(true);
|
||||
accessModifiers.setBounds(6, 7, 232, 23);
|
||||
getContentPane().add(accessModifiers);
|
||||
|
||||
|
||||
final JCheckBox invokeMethod = new JCheckBox("Invoke Main Method:");
|
||||
invokeMethod.setSelected(true);
|
||||
invokeMethod.setBounds(6, 251, 232, 23);
|
||||
getContentPane().add(invokeMethod);
|
||||
|
||||
|
||||
final JCheckBox injectHooks = new JCheckBox("Inject Hooks");
|
||||
injectHooks.setSelected(true);
|
||||
injectHooks.setBounds(6, 33, 232, 23);
|
||||
getContentPane().add(injectHooks);
|
||||
|
||||
|
||||
debugMethodCalls = new JCheckBox("Debug Method Calls");
|
||||
debugMethodCalls.setSelected(true);
|
||||
debugMethodCalls.setBounds(6, 59, 232, 23);
|
||||
getContentPane().add(debugMethodCalls);
|
||||
|
||||
|
||||
final JCheckBox runtime = new JCheckBox("Sandbox Runtime.exec");
|
||||
runtime.setEnabled(false);
|
||||
runtime.setBounds(6, 138, 232, 23);
|
||||
getContentPane().add(runtime);
|
||||
|
||||
|
||||
final JCheckBox system = new JCheckBox("Sandbox System.exit");
|
||||
system.setEnabled(false);
|
||||
system.setBounds(6, 164, 232, 23);
|
||||
getContentPane().add(system);
|
||||
|
||||
txtThebytecodeclubexamplemainlstring = new JTextField();
|
||||
|
||||
|
||||
JButton btnNewButton = new JButton("Execute");
|
||||
btnNewButton.setBounds(6, 393, 232, 23);
|
||||
getContentPane().add(btnNewButton);
|
||||
|
||||
|
||||
boolean b = false;
|
||||
for(ClassNode classNode : BytecodeViewer.getLoadedClasses()) {
|
||||
for(Object o : classNode.methods.toArray()) {
|
||||
for (ClassNode classNode : BytecodeViewer.getLoadedClasses()) {
|
||||
for (Object o : classNode.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
|
||||
if(m.name.equals("main") && m.desc.equals("([Ljava/lang/String;)V")) {
|
||||
if(!b) {
|
||||
|
||||
if (m.name.equals("main")
|
||||
&& m.desc.equals("([Ljava/lang/String;)V")) {
|
||||
if (!b) {
|
||||
b = true;
|
||||
txtThebytecodeclubexamplemainlstring.setText(classNode.name+"."+m.name);
|
||||
txtThebytecodeclubexamplemainlstring
|
||||
.setText(classNode.name + "." + m.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!b)
|
||||
txtThebytecodeclubexamplemainlstring.setText("the/bytecode/club/Example.main");
|
||||
|
||||
|
||||
if (!b)
|
||||
txtThebytecodeclubexamplemainlstring
|
||||
.setText("the/bytecode/club/Example.main");
|
||||
|
||||
txtThebytecodeclubexamplemainlstring.setBounds(6, 281, 232, 20);
|
||||
getContentPane().add(txtThebytecodeclubexamplemainlstring);
|
||||
txtThebytecodeclubexamplemainlstring.setColumns(10);
|
||||
|
||||
|
||||
JLabel lblNewLabel = new JLabel("Debug Classes (Seperate with , ):");
|
||||
lblNewLabel.setBounds(10, 89, 228, 14);
|
||||
getContentPane().add(lblNewLabel);
|
||||
|
||||
|
||||
textField = new JTextField();
|
||||
textField.setText("*");
|
||||
textField.setBounds(6, 111, 232, 20);
|
||||
getContentPane().add(textField);
|
||||
textField.setColumns(10);
|
||||
|
||||
|
||||
textField_1 = new JTextField();
|
||||
textField_1.setText("127.0.0.1:9050");
|
||||
textField_1.setColumns(10);
|
||||
textField_1.setBounds(6, 220, 232, 20);
|
||||
getContentPane().add(textField_1);
|
||||
|
||||
final JCheckBox forceProxy = new JCheckBox("Force Proxy (socks5, host:port):");
|
||||
|
||||
final JCheckBox forceProxy = new JCheckBox(
|
||||
"Force Proxy (socks5, host:port):");
|
||||
forceProxy.setBounds(6, 190, 232, 23);
|
||||
getContentPane().add(forceProxy);
|
||||
|
||||
final JCheckBox launchReflectionKit = new JCheckBox("Launch Reflection Kit On Successful Invoke");
|
||||
|
||||
final JCheckBox launchReflectionKit = new JCheckBox(
|
||||
"Launch Reflection Kit On Successful Invoke");
|
||||
launchReflectionKit.setEnabled(false);
|
||||
launchReflectionKit.setBounds(6, 308, 232, 23);
|
||||
getContentPane().add(launchReflectionKit);
|
||||
|
||||
|
||||
final JCheckBox console = new JCheckBox("Launch Console");
|
||||
console.setBounds(6, 334, 232, 23);
|
||||
console.setSelected(true);
|
||||
getContentPane().add(console);
|
||||
|
||||
final JCheckBox chckbxPrintToTerminal = new JCheckBox("Print To Command Line");
|
||||
|
||||
final JCheckBox chckbxPrintToTerminal = new JCheckBox(
|
||||
"Print To Command Line");
|
||||
chckbxPrintToTerminal.setSelected(true);
|
||||
chckbxPrintToTerminal.setBounds(6, 363, 232, 23);
|
||||
getContentPane().add(chckbxPrintToTerminal);
|
||||
this.setLocationRelativeTo(null);
|
||||
btnNewButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
PluginManager.runPlugin(new EZInjection(accessModifiers.isSelected(), injectHooks.isSelected(), debugMethodCalls.isSelected(), invokeMethod.isSelected(), txtThebytecodeclubexamplemainlstring.getText(), runtime.isSelected(), system.isSelected(), textField.getText(), textField_1.getText(), forceProxy.isSelected(), launchReflectionKit.isSelected(), console.isSelected(), chckbxPrintToTerminal.isSelected()));
|
||||
PluginManager.runPlugin(new EZInjection(accessModifiers
|
||||
.isSelected(), injectHooks.isSelected(),
|
||||
debugMethodCalls.isSelected(), invokeMethod
|
||||
.isSelected(),
|
||||
txtThebytecodeclubexamplemainlstring.getText(), runtime
|
||||
.isSelected(), system.isSelected(), textField
|
||||
.getText(), textField_1.getText(), forceProxy
|
||||
.isSelected(),
|
||||
launchReflectionKit.isSelected(), console.isSelected(),
|
||||
chckbxPrintToTerminal.isSelected()));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static final long serialVersionUID = -2662514582647810868L;
|
||||
private JTextField txtThebytecodeclubexamplemainlstring;
|
||||
private JCheckBox debugMethodCalls;
|
||||
|
|
|
@ -20,19 +20,20 @@ public class ExportJar extends JFrame {
|
|||
setSize(new Dimension(250, 277));
|
||||
setResizable(false);
|
||||
setTitle("Save As Jar..");
|
||||
|
||||
|
||||
JButton btnNewButton = new JButton("Save As Jar..");
|
||||
btnNewButton.setMaximumSize(new Dimension(999, 23));
|
||||
btnNewButton.setMinimumSize(new Dimension(999, 23));
|
||||
btnNewButton.setSize(new Dimension(999, 0));
|
||||
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
|
||||
|
||||
getContentPane().setLayout(
|
||||
new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane();
|
||||
getContentPane().add(scrollPane);
|
||||
|
||||
|
||||
JLabel lblMetainfmanifestmf = new JLabel("META-INF/MANIFEST.MF:");
|
||||
scrollPane.setColumnHeaderView(lblMetainfmanifestmf);
|
||||
|
||||
|
||||
final JTextArea mani = new JTextArea();
|
||||
mani.setText("Manifest-Version: 1.0\r\nClass-Path: .\r\nMain-Class: ");
|
||||
scrollPane.setViewportView(mani);
|
||||
|
@ -41,14 +42,15 @@ public class ExportJar extends JFrame {
|
|||
btnNewButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
BytecodeViewer.viewer.setC(true);
|
||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), jarPath, mani.getText());
|
||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), jarPath,
|
||||
mani.getText());
|
||||
BytecodeViewer.viewer.setC(false);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
|
||||
private static final long serialVersionUID = -2662514582647810868L;
|
||||
}
|
||||
|
|
|
@ -35,332 +35,365 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
import the.bytecode.club.bytecodeviewer.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class FileNavigationPane extends VisibleComponent implements FileDrop.Listener {
|
||||
|
||||
FileChangeNotifier fcn;
|
||||
JCheckBox exact = new JCheckBox("Exact");
|
||||
|
||||
MyTreeNode treeRoot = new MyTreeNode("Root");
|
||||
MyTree tree;
|
||||
|
||||
public FileNavigationPane(final FileChangeNotifier fcn) {
|
||||
super("ClassNavigation");
|
||||
setTitle("Files");
|
||||
|
||||
this.fcn = fcn;
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
|
||||
this.tree = new MyTree(treeRoot);
|
||||
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
|
||||
|
||||
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(final TreeSelectionEvent arg0) {
|
||||
final TreePath path = arg0.getPath();
|
||||
if (((TreeNode)path.getLastPathComponent()).getChildCount() > 0)
|
||||
return;
|
||||
final StringBuffer nameBuffer = new StringBuffer();
|
||||
for (int i = 1;i < path.getPathCount(); i++) {
|
||||
nameBuffer.append(path.getPathComponent(i));
|
||||
if (i < path.getPathCount()-1) {
|
||||
nameBuffer.append("/");
|
||||
}
|
||||
}
|
||||
final ClassNode cn = BytecodeViewer.getClassNode(nameBuffer.toString());
|
||||
if (cn != null) {
|
||||
openClassFileToWorkSpace(nameBuffer.toString(), cn);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final String quickSearchText = "Quick class search";
|
||||
|
||||
final JTextField quickSearch = new JTextField(quickSearchText);
|
||||
quickSearch.setForeground(Color.gray);
|
||||
quickSearch.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(final KeyEvent ke) {
|
||||
if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
|
||||
final String qt = quickSearch.getText();
|
||||
quickSearch.setText("");
|
||||
|
||||
String[] path = null;
|
||||
|
||||
if (qt.contains(".")) {
|
||||
path = qt.split("\\.");
|
||||
}
|
||||
else {
|
||||
path = new String[] {qt};
|
||||
}
|
||||
|
||||
MyTreeNode curNode = treeRoot;
|
||||
pathLoop:
|
||||
for (int i = 0;i < path.length; i++) {
|
||||
final String pathName = path[i];
|
||||
final boolean isLast = i == path.length-1;
|
||||
|
||||
for (int c = 0; c < curNode.getChildCount(); c++) {
|
||||
final MyTreeNode child = (MyTreeNode) curNode.getChildAt(c);
|
||||
|
||||
if(!exact.isSelected()) {
|
||||
if (((String)child.getUserObject()).toLowerCase().contains(pathName.toLowerCase())) {
|
||||
curNode = child;
|
||||
if (isLast) {
|
||||
final TreePath pathn = new TreePath(curNode.getPath());
|
||||
tree.setSelectionPath(pathn);
|
||||
tree.makeVisible(pathn);
|
||||
tree.scrollPathToVisible(pathn);
|
||||
System.out.println("Found! " + curNode);
|
||||
break pathLoop;
|
||||
}
|
||||
continue pathLoop;
|
||||
}
|
||||
} else {
|
||||
if (((String)child.getUserObject()).equals(pathName)) {
|
||||
curNode = child;
|
||||
if (isLast) {
|
||||
final TreePath pathn = new TreePath(curNode.getPath());
|
||||
tree.setSelectionPath(pathn);
|
||||
tree.makeVisible(pathn);
|
||||
tree.scrollPathToVisible(pathn);
|
||||
System.out.println("Found! " + curNode);
|
||||
break pathLoop;
|
||||
}
|
||||
continue pathLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Could not find " + pathName);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
quickSearch.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(final FocusEvent arg0) {
|
||||
if (quickSearch.getText().equals(quickSearchText)) {
|
||||
quickSearch.setText("");
|
||||
quickSearch.setForeground(Color.black);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void focusLost(final FocusEvent arg0) {
|
||||
if (quickSearch.getText().isEmpty()) {
|
||||
quickSearch.setText(quickSearchText);
|
||||
quickSearch.setForeground(Color.gray);
|
||||
}
|
||||
}
|
||||
});
|
||||
public class FileNavigationPane extends VisibleComponent implements
|
||||
FileDrop.Listener {
|
||||
|
||||
JPanel p2 = new JPanel();
|
||||
p2.setLayout(new BorderLayout());
|
||||
p2.add(quickSearch, BorderLayout.NORTH);
|
||||
p2.add(exact, BorderLayout.SOUTH);
|
||||
FileChangeNotifier fcn;
|
||||
JCheckBox exact = new JCheckBox("Exact");
|
||||
|
||||
getContentPane().add(p2, BorderLayout.SOUTH);
|
||||
|
||||
this.setVisible(true);
|
||||
new FileDrop(this, this);
|
||||
}
|
||||
|
||||
public void openClassFileToWorkSpace(final String name, final ClassNode node) {
|
||||
fcn.openClassFile(name, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filesDropped(final File[] files) {
|
||||
if (files.length < 1)
|
||||
return;
|
||||
BytecodeViewer.openFiles(files);
|
||||
}
|
||||
|
||||
public void updateTree() {
|
||||
treeRoot.removeAllChildren();
|
||||
for (final Entry<String, ClassNode> entry : BytecodeViewer.loadedClasses.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
final String[] spl = name.split("\\/");
|
||||
if (spl.length < 2) {
|
||||
treeRoot.add(new MyTreeNode(name));
|
||||
}
|
||||
else {
|
||||
MyTreeNode parent = treeRoot;
|
||||
for (final String s : spl) {
|
||||
MyTreeNode child = null;
|
||||
for (int i = 0;i < parent.getChildCount(); i++) {
|
||||
if (((MyTreeNode) parent.getChildAt(i)).getUserObject().equals(s)) {
|
||||
child = (MyTreeNode) parent.getChildAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (child == null) {
|
||||
child = new MyTreeNode(s);
|
||||
parent.add(child);
|
||||
}
|
||||
parent = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
treeRoot.sort();
|
||||
tree.expandPath(new TreePath(tree.getModel().getRoot()));
|
||||
tree.updateUI();
|
||||
//expandAll(tree, true);
|
||||
}
|
||||
|
||||
// If expand is true, expands all nodes in the tree.
|
||||
// Otherwise, collapses all nodes in the tree.
|
||||
public void expandAll(final JTree tree, final boolean expand) {
|
||||
final TreeNode root = (TreeNode) tree.getModel().getRoot();
|
||||
MyTreeNode treeRoot = new MyTreeNode("Root");
|
||||
MyTree tree;
|
||||
|
||||
// Traverse tree from root
|
||||
expandAll(tree, new TreePath(root), expand);
|
||||
}
|
||||
public FileNavigationPane(final FileChangeNotifier fcn) {
|
||||
super("ClassNavigation");
|
||||
setTitle("Files");
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
this.fcn = fcn;
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
|
||||
this.tree = new MyTree(treeRoot);
|
||||
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
|
||||
|
||||
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(final TreeSelectionEvent arg0) {
|
||||
final TreePath path = arg0.getPath();
|
||||
if (((TreeNode) path.getLastPathComponent()).getChildCount() > 0)
|
||||
return;
|
||||
final StringBuffer nameBuffer = new StringBuffer();
|
||||
for (int i = 1; i < path.getPathCount(); i++) {
|
||||
nameBuffer.append(path.getPathComponent(i));
|
||||
if (i < path.getPathCount() - 1) {
|
||||
nameBuffer.append("/");
|
||||
}
|
||||
}
|
||||
final ClassNode cn = BytecodeViewer.getClassNode(nameBuffer
|
||||
.toString());
|
||||
if (cn != null) {
|
||||
openClassFileToWorkSpace(nameBuffer.toString(), cn);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final String quickSearchText = "Quick class search";
|
||||
|
||||
final JTextField quickSearch = new JTextField(quickSearchText);
|
||||
quickSearch.setForeground(Color.gray);
|
||||
quickSearch.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(final KeyEvent ke) {
|
||||
if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
|
||||
final String qt = quickSearch.getText();
|
||||
quickSearch.setText("");
|
||||
|
||||
String[] path = null;
|
||||
|
||||
if (qt.contains(".")) {
|
||||
path = qt.split("\\.");
|
||||
} else {
|
||||
path = new String[] { qt };
|
||||
}
|
||||
|
||||
MyTreeNode curNode = treeRoot;
|
||||
if (exact.isSelected()) {
|
||||
pathLoop: for (int i = 0; i < path.length; i++) {
|
||||
final String pathName = path[i];
|
||||
final boolean isLast = i == path.length - 1;
|
||||
|
||||
for (int c = 0; c < curNode.getChildCount(); c++) {
|
||||
final MyTreeNode child = (MyTreeNode) curNode
|
||||
.getChildAt(c);
|
||||
|
||||
if (((String) child.getUserObject())
|
||||
.toLowerCase().contains(
|
||||
pathName.toLowerCase())) {
|
||||
curNode = child;
|
||||
if (isLast) {
|
||||
final TreePath pathn = new TreePath(
|
||||
curNode.getPath());
|
||||
tree.setSelectionPath(pathn);
|
||||
tree.makeVisible(pathn);
|
||||
tree.scrollPathToVisible(pathn);
|
||||
System.out.println("Found! " + curNode);
|
||||
break pathLoop;
|
||||
}
|
||||
continue pathLoop;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Could not find " + pathName);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Enumeration<MyTreeNode> enums = curNode
|
||||
.depthFirstEnumeration();
|
||||
while (enums != null && enums.hasMoreElements()) {
|
||||
|
||||
MyTreeNode node = enums.nextElement();
|
||||
// System.out.println("enum " +
|
||||
// node.getUserObject());
|
||||
if (node.isLeaf()) {
|
||||
if (((String) (node.getUserObject()))
|
||||
.equalsIgnoreCase(path[path.length - 1])) {
|
||||
TreeNode pathArray[] = node.getPath();
|
||||
int k = 0;
|
||||
StringBuffer fullPath = new StringBuffer();
|
||||
while (pathArray != null
|
||||
&& k < pathArray.length) {
|
||||
MyTreeNode n = (MyTreeNode) pathArray[k];
|
||||
fullPath.append((String) (n
|
||||
.getUserObject()));
|
||||
if (k++ != pathArray.length - 1) {
|
||||
fullPath.append(".");
|
||||
}
|
||||
}
|
||||
String fullPathString = fullPath.toString();
|
||||
if (fullPathString != null
|
||||
&& fullPathString.toLowerCase()
|
||||
.contains(qt.toLowerCase())) {
|
||||
System.out.println("Found! " + node);
|
||||
final TreePath pathn = new TreePath(
|
||||
node.getPath());
|
||||
tree.setSelectionPath(pathn);
|
||||
tree.makeVisible(pathn);
|
||||
tree.scrollPathToVisible(pathn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
quickSearch.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(final FocusEvent arg0) {
|
||||
if (quickSearch.getText().equals(quickSearchText)) {
|
||||
quickSearch.setText("");
|
||||
quickSearch.setForeground(Color.black);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(final FocusEvent arg0) {
|
||||
if (quickSearch.getText().isEmpty()) {
|
||||
quickSearch.setText(quickSearchText);
|
||||
quickSearch.setForeground(Color.gray);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
JPanel p2 = new JPanel();
|
||||
p2.setLayout(new BorderLayout());
|
||||
p2.add(quickSearch, BorderLayout.NORTH);
|
||||
p2.add(exact, BorderLayout.SOUTH);
|
||||
|
||||
getContentPane().add(p2, BorderLayout.SOUTH);
|
||||
|
||||
this.setVisible(true);
|
||||
new FileDrop(this, this);
|
||||
}
|
||||
|
||||
public void openClassFileToWorkSpace(final String name, final ClassNode node) {
|
||||
fcn.openClassFile(name, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filesDropped(final File[] files) {
|
||||
if (files.length < 1)
|
||||
return;
|
||||
BytecodeViewer.openFiles(files);
|
||||
}
|
||||
|
||||
public void updateTree() {
|
||||
treeRoot.removeAllChildren();
|
||||
for (final Entry<String, ClassNode> entry : BytecodeViewer.loadedClasses
|
||||
.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
final String[] spl = name.split("\\/");
|
||||
if (spl.length < 2) {
|
||||
treeRoot.add(new MyTreeNode(name));
|
||||
} else {
|
||||
MyTreeNode parent = treeRoot;
|
||||
for (final String s : spl) {
|
||||
MyTreeNode child = null;
|
||||
for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
if (((MyTreeNode) parent.getChildAt(i)).getUserObject()
|
||||
.equals(s)) {
|
||||
child = (MyTreeNode) parent.getChildAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (child == null) {
|
||||
child = new MyTreeNode(s);
|
||||
parent.add(child);
|
||||
}
|
||||
parent = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
treeRoot.sort();
|
||||
tree.expandPath(new TreePath(tree.getModel().getRoot()));
|
||||
tree.updateUI();
|
||||
// expandAll(tree, true);
|
||||
}
|
||||
|
||||
// If expand is true, expands all nodes in the tree.
|
||||
// Otherwise, collapses all nodes in the tree.
|
||||
public void expandAll(final JTree tree, final boolean expand) {
|
||||
final TreeNode root = (TreeNode) tree.getModel().getRoot();
|
||||
|
||||
// Traverse tree from root
|
||||
expandAll(tree, new TreePath(root), expand);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private void expandAll(final JTree tree, final TreePath parent,
|
||||
final boolean expand) {
|
||||
// Traverse children
|
||||
final TreeNode node = (TreeNode) parent.getLastPathComponent();
|
||||
if (node.getChildCount() >= 0) {
|
||||
for (final Enumeration e = node.children(); e.hasMoreElements();) {
|
||||
final TreeNode n = (TreeNode) e.nextElement();
|
||||
final TreePath path = parent.pathByAddingChild(n);
|
||||
expandAll(tree, path, expand);
|
||||
}
|
||||
}
|
||||
final boolean expand) {
|
||||
// Traverse children
|
||||
final TreeNode node = (TreeNode) parent.getLastPathComponent();
|
||||
if (node.getChildCount() >= 0) {
|
||||
for (final Enumeration e = node.children(); e.hasMoreElements();) {
|
||||
final TreeNode n = (TreeNode) e.nextElement();
|
||||
final TreePath path = parent.pathByAddingChild(n);
|
||||
expandAll(tree, path, expand);
|
||||
}
|
||||
}
|
||||
|
||||
// Expansion or collapse must be done bottom-up
|
||||
if (expand) {
|
||||
tree.expandPath(parent);
|
||||
} else {
|
||||
tree.collapsePath(parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class MyTree extends JTree {
|
||||
// Expansion or collapse must be done bottom-up
|
||||
if (expand) {
|
||||
tree.expandPath(parent);
|
||||
} else {
|
||||
tree.collapsePath(parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class MyTree extends JTree {
|
||||
|
||||
private static final long serialVersionUID = -2355167326094772096L;
|
||||
DefaultMutableTreeNode treeRoot;
|
||||
|
||||
public MyTree(final DefaultMutableTreeNode treeRoot) {
|
||||
super(treeRoot);
|
||||
this.treeRoot = treeRoot;
|
||||
}
|
||||
|
||||
StringMetrics m = null;
|
||||
|
||||
@Override
|
||||
public void paint(final Graphics g) {
|
||||
super.paint(g);
|
||||
if(m == null) {
|
||||
m = new StringMetrics((Graphics2D)g);
|
||||
}
|
||||
if (treeRoot.getChildCount() < 1) {
|
||||
g.setColor(new Color(0, 0, 0, 100));
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
g.setColor(Color.white);
|
||||
String s = "Drag class/jar here";
|
||||
g.drawString(s, ((int)((getWidth()/2)-(m.getWidth(s)/2))), getHeight()/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MyTreeNode extends DefaultMutableTreeNode {
|
||||
|
||||
|
||||
public MyTree(final DefaultMutableTreeNode treeRoot) {
|
||||
super(treeRoot);
|
||||
this.treeRoot = treeRoot;
|
||||
}
|
||||
|
||||
StringMetrics m = null;
|
||||
|
||||
@Override
|
||||
public void paint(final Graphics g) {
|
||||
super.paint(g);
|
||||
if (m == null) {
|
||||
m = new StringMetrics((Graphics2D) g);
|
||||
}
|
||||
if (treeRoot.getChildCount() < 1) {
|
||||
g.setColor(new Color(0, 0, 0, 100));
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
g.setColor(Color.white);
|
||||
String s = "Drag class/jar here";
|
||||
g.drawString(s,
|
||||
((int) ((getWidth() / 2) - (m.getWidth(s) / 2))),
|
||||
getHeight() / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MyTreeNode extends DefaultMutableTreeNode {
|
||||
|
||||
private static final long serialVersionUID = -8817777566176729571L;
|
||||
|
||||
public MyTreeNode(final Object o) {
|
||||
super(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(final MutableTreeNode newChild, final int childIndex) {
|
||||
super.insert(newChild, childIndex);
|
||||
}
|
||||
|
||||
public void sort() {
|
||||
recursiveSort(this);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
super(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(final MutableTreeNode newChild, final int childIndex) {
|
||||
super.insert(newChild, childIndex);
|
||||
}
|
||||
|
||||
public void sort() {
|
||||
recursiveSort(this);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void recursiveSort(final MyTreeNode node) {
|
||||
Collections.sort(node.children, nodeComparator);
|
||||
final Iterator<MyTreeNode> it = node.children.iterator();
|
||||
while (it.hasNext()) {
|
||||
final MyTreeNode nextNode = it.next();
|
||||
if (nextNode.getChildCount() > 0) {
|
||||
recursiveSort(nextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Comparator<MyTreeNode> nodeComparator = new Comparator<MyTreeNode> () {
|
||||
@Override
|
||||
public int compare(final MyTreeNode o1, final MyTreeNode o2) {
|
||||
// To make sure nodes with children are always on top
|
||||
final int firstOffset = o1.getChildCount() > 0 ? -1000 : 0;
|
||||
final int secondOffset = o2.getChildCount() > 0 ? 1000 : 0;
|
||||
return o1.toString().compareToIgnoreCase(o2.toString()) + firstOffset + secondOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int hash = 7;
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @author http://stackoverflow.com/a/18450804
|
||||
*
|
||||
*/
|
||||
class StringMetrics {
|
||||
Collections.sort(node.children, nodeComparator);
|
||||
final Iterator<MyTreeNode> it = node.children.iterator();
|
||||
while (it.hasNext()) {
|
||||
final MyTreeNode nextNode = it.next();
|
||||
if (nextNode.getChildCount() > 0) {
|
||||
recursiveSort(nextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Font font;
|
||||
FontRenderContext context;
|
||||
protected Comparator<MyTreeNode> nodeComparator = new Comparator<MyTreeNode>() {
|
||||
@Override
|
||||
public int compare(final MyTreeNode o1, final MyTreeNode o2) {
|
||||
// To make sure nodes with children are always on top
|
||||
final int firstOffset = o1.getChildCount() > 0 ? -1000 : 0;
|
||||
final int secondOffset = o2.getChildCount() > 0 ? 1000 : 0;
|
||||
return o1.toString().compareToIgnoreCase(o2.toString())
|
||||
+ firstOffset + secondOffset;
|
||||
}
|
||||
|
||||
public StringMetrics(Graphics2D g2) {
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
font = g2.getFont();
|
||||
context = g2.getFontRenderContext();
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int hash = 7;
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Rectangle2D getBounds(String message) {
|
||||
/**
|
||||
*
|
||||
* @author http://stackoverflow.com/a/18450804
|
||||
*
|
||||
*/
|
||||
class StringMetrics {
|
||||
|
||||
return font.getStringBounds(message, context);
|
||||
}
|
||||
Font font;
|
||||
FontRenderContext context;
|
||||
|
||||
double getWidth(String message) {
|
||||
public StringMetrics(Graphics2D g2) {
|
||||
|
||||
Rectangle2D bounds = getBounds(message);
|
||||
return bounds.getWidth();
|
||||
}
|
||||
font = g2.getFont();
|
||||
context = g2.getFontRenderContext();
|
||||
}
|
||||
|
||||
double getHeight(String message) {
|
||||
Rectangle2D getBounds(String message) {
|
||||
|
||||
Rectangle2D bounds = getBounds(message);
|
||||
return bounds.getHeight();
|
||||
}
|
||||
return font.getStringBounds(message, context);
|
||||
}
|
||||
|
||||
}
|
||||
double getWidth(String message) {
|
||||
|
||||
Rectangle2D bounds = getBounds(message);
|
||||
return bounds.getWidth();
|
||||
}
|
||||
|
||||
double getHeight(String message) {
|
||||
|
||||
Rectangle2D bounds = getBounds(message);
|
||||
return bounds.getHeight();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void resetWorkspace() {
|
||||
treeRoot.removeAllChildren();
|
||||
tree.repaint();
|
||||
tree.updateUI();
|
||||
tree.updateUI();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -14,19 +14,19 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|||
|
||||
public class GraphicialReflectionKit extends JFrame {
|
||||
public GraphicialReflectionKit() {
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
setSize(new Dimension(382, 356));
|
||||
setTitle("Graphicial Reflection Kit");
|
||||
|
||||
|
||||
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
|
||||
getContentPane().add(tabbedPane, BorderLayout.CENTER);
|
||||
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
tabbedPane.addTab("Invoke Method", null, panel, null);
|
||||
|
||||
|
||||
JPanel panel_1 = new JPanel();
|
||||
tabbedPane.addTab("Get Field Value", null, panel_1, null);
|
||||
|
||||
|
||||
JPanel panel_2 = new JPanel();
|
||||
tabbedPane.addTab("Cast Field", null, panel_2, null);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,58 +16,68 @@ import java.awt.event.ActionEvent;
|
|||
|
||||
public class MaliciousCodeScannerOptions extends JFrame {
|
||||
public MaliciousCodeScannerOptions() {
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
setSize(new Dimension(250, 277));
|
||||
setResizable(false);
|
||||
setTitle("Malicious Code Scanner Options");
|
||||
getContentPane().setLayout(null);
|
||||
|
||||
final JCheckBox chckbxJavalangreflection = new JCheckBox("java/lang/reflection");
|
||||
|
||||
final JCheckBox chckbxJavalangreflection = new JCheckBox(
|
||||
"java/lang/reflection");
|
||||
chckbxJavalangreflection.setSelected(true);
|
||||
chckbxJavalangreflection.setBounds(6, 7, 232, 23);
|
||||
getContentPane().add(chckbxJavalangreflection);
|
||||
|
||||
|
||||
final JCheckBox chckbxJavanet = new JCheckBox("java/net");
|
||||
chckbxJavanet.setSelected(true);
|
||||
chckbxJavanet.setBounds(6, 59, 232, 23);
|
||||
getContentPane().add(chckbxJavanet);
|
||||
|
||||
|
||||
final JCheckBox chckbxJavaio = new JCheckBox("java/io");
|
||||
chckbxJavaio.setBounds(6, 85, 232, 23);
|
||||
getContentPane().add(chckbxJavaio);
|
||||
|
||||
final JCheckBox chckbxJavalangruntime = new JCheckBox("java/lang/Runtime");
|
||||
|
||||
final JCheckBox chckbxJavalangruntime = new JCheckBox(
|
||||
"java/lang/Runtime");
|
||||
chckbxJavalangruntime.setSelected(true);
|
||||
chckbxJavalangruntime.setBounds(6, 33, 232, 23);
|
||||
getContentPane().add(chckbxJavalangruntime);
|
||||
|
||||
final JCheckBox chckbxLdcContainswww = new JCheckBox("LDC contains 'www.'");
|
||||
|
||||
final JCheckBox chckbxLdcContainswww = new JCheckBox(
|
||||
"LDC contains 'www.'");
|
||||
chckbxLdcContainswww.setSelected(true);
|
||||
chckbxLdcContainswww.setBounds(6, 111, 232, 23);
|
||||
getContentPane().add(chckbxLdcContainswww);
|
||||
|
||||
final JCheckBox chckbxLdcContainshttp = new JCheckBox("LDC contains 'http://'");
|
||||
|
||||
final JCheckBox chckbxLdcContainshttp = new JCheckBox(
|
||||
"LDC contains 'http://'");
|
||||
chckbxLdcContainshttp.setSelected(true);
|
||||
chckbxLdcContainshttp.setBounds(6, 137, 232, 23);
|
||||
getContentPane().add(chckbxLdcContainshttp);
|
||||
|
||||
final JCheckBox chckbxLdcContainshttps = new JCheckBox("LDC contains 'https://'");
|
||||
|
||||
final JCheckBox chckbxLdcContainshttps = new JCheckBox(
|
||||
"LDC contains 'https://'");
|
||||
chckbxLdcContainshttps.setSelected(true);
|
||||
chckbxLdcContainshttps.setBounds(6, 163, 232, 23);
|
||||
getContentPane().add(chckbxLdcContainshttps);
|
||||
|
||||
final JCheckBox chckbxLdcMatchesIp = new JCheckBox("LDC matches IP regex");
|
||||
|
||||
final JCheckBox chckbxLdcMatchesIp = new JCheckBox(
|
||||
"LDC matches IP regex");
|
||||
chckbxLdcMatchesIp.setSelected(true);
|
||||
chckbxLdcMatchesIp.setBounds(6, 189, 232, 23);
|
||||
getContentPane().add(chckbxLdcMatchesIp);
|
||||
|
||||
|
||||
JButton btnNewButton = new JButton("Start Scanning");
|
||||
btnNewButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
PluginManager.runPlugin(new MaliciousCodeScanner(chckbxJavalangreflection.isSelected(),
|
||||
chckbxJavalangruntime.isSelected(), chckbxJavanet.isSelected(), chckbxJavaio.isSelected(),
|
||||
chckbxLdcContainswww.isSelected(), chckbxLdcContainshttp.isSelected(), chckbxLdcContainshttps.isSelected(),
|
||||
chckbxLdcMatchesIp.isSelected()));
|
||||
PluginManager.runPlugin(new MaliciousCodeScanner(
|
||||
chckbxJavalangreflection.isSelected(),
|
||||
chckbxJavalangruntime.isSelected(), chckbxJavanet
|
||||
.isSelected(), chckbxJavaio.isSelected(),
|
||||
chckbxLdcContainswww.isSelected(),
|
||||
chckbxLdcContainshttp.isSelected(),
|
||||
chckbxLdcContainshttps.isSelected(), chckbxLdcMatchesIp
|
||||
.isSelected()));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
|
@ -75,6 +85,6 @@ public class MaliciousCodeScannerOptions extends JFrame {
|
|||
getContentPane().add(btnNewButton);
|
||||
this.setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
|
||||
private static final long serialVersionUID = -2662514582647810868L;
|
||||
}
|
||||
|
|
|
@ -4,16 +4,16 @@ package the.bytecode.club.bytecodeviewer.gui;
|
|||
* Allows us to run a background thread
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class PaneUpdaterThread extends Thread {
|
||||
|
||||
|
||||
public abstract void doShit();
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
doShit();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -18,58 +18,62 @@ import javax.swing.JCheckBox;
|
|||
|
||||
public class ReplaceStringsOptions extends JFrame {
|
||||
public ReplaceStringsOptions() {
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
setSize(new Dimension(250, 176));
|
||||
setResizable(false);
|
||||
setTitle("Replace Strings");
|
||||
getContentPane().setLayout(null);
|
||||
|
||||
|
||||
JButton btnNewButton = new JButton("Start Replacing");
|
||||
btnNewButton.setBounds(6, 115, 232, 23);
|
||||
getContentPane().add(btnNewButton);
|
||||
|
||||
|
||||
JLabel lblNewLabel = new JLabel("Original LDC:");
|
||||
lblNewLabel.setBounds(6, 40, 67, 14);
|
||||
getContentPane().add(lblNewLabel);
|
||||
|
||||
|
||||
textField = new JTextField();
|
||||
textField.setBounds(80, 37, 158, 20);
|
||||
getContentPane().add(textField);
|
||||
textField.setColumns(10);
|
||||
|
||||
|
||||
JLabel lblNewLabel_1 = new JLabel("New LDC:");
|
||||
lblNewLabel_1.setBounds(6, 65, 77, 14);
|
||||
getContentPane().add(lblNewLabel_1);
|
||||
|
||||
|
||||
textField_1 = new JTextField();
|
||||
textField_1.setColumns(10);
|
||||
textField_1.setBounds(80, 62, 158, 20);
|
||||
getContentPane().add(textField_1);
|
||||
|
||||
|
||||
JLabel lblNewLabel_2 = new JLabel("Class:");
|
||||
lblNewLabel_2.setBounds(6, 90, 46, 14);
|
||||
getContentPane().add(lblNewLabel_2);
|
||||
|
||||
|
||||
textField_2 = new JTextField();
|
||||
textField_2.setToolTipText("* will search all classes");
|
||||
textField_2.setText("*");
|
||||
textField_2.setBounds(80, 87, 158, 20);
|
||||
getContentPane().add(textField_2);
|
||||
textField_2.setColumns(10);
|
||||
|
||||
final JCheckBox chckbxNewCheckBox = new JCheckBox("Replace All Contains");
|
||||
chckbxNewCheckBox.setToolTipText("If it's unticked, it will check if the string equals, if its ticked it will check if it contains, then replace the original LDC part of the string.");
|
||||
|
||||
final JCheckBox chckbxNewCheckBox = new JCheckBox(
|
||||
"Replace All Contains");
|
||||
chckbxNewCheckBox
|
||||
.setToolTipText("If it's unticked, it will check if the string equals, if its ticked it will check if it contains, then replace the original LDC part of the string.");
|
||||
chckbxNewCheckBox.setBounds(6, 7, 232, 23);
|
||||
getContentPane().add(chckbxNewCheckBox);
|
||||
btnNewButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
PluginManager.runPlugin(new ReplaceStrings(textField.getText(), textField_1.getText(), textField_2.getText(), chckbxNewCheckBox.isSelected()));
|
||||
PluginManager.runPlugin(new ReplaceStrings(textField.getText(),
|
||||
textField_1.getText(), textField_2.getText(),
|
||||
chckbxNewCheckBox.isSelected()));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
this.setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
|
||||
private static final long serialVersionUID = -2662514582647810868L;
|
||||
private JTextField textField;
|
||||
private JTextField textField_1;
|
||||
|
|
|
@ -30,185 +30,193 @@ import the.bytecode.club.bytecodeviewer.searching.*;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class SearchingPane extends VisibleComponent {
|
||||
|
||||
|
||||
private static final long serialVersionUID = -1098524689236993932L;
|
||||
|
||||
FileChangeNotifier fcn;
|
||||
|
||||
JCheckBox exact = new JCheckBox("Exact");
|
||||
DefaultMutableTreeNode treeRoot = new DefaultMutableTreeNode("Root");
|
||||
JTree tree;
|
||||
|
||||
SearchType searchType = null;
|
||||
|
||||
FileChangeNotifier fcn;
|
||||
|
||||
JCheckBox exact = new JCheckBox("Exact");
|
||||
DefaultMutableTreeNode treeRoot = new DefaultMutableTreeNode("Root");
|
||||
JTree tree;
|
||||
|
||||
SearchType searchType = null;
|
||||
JComboBox searchRadiusBox;
|
||||
|
||||
public JButton search = new JButton("Search");
|
||||
|
||||
public JButton search = new JButton("Search");
|
||||
BackgroundSearchThread t = new BackgroundSearchThread(true) {
|
||||
@Override
|
||||
public void doSearch() {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public SearchingPane(final FileChangeNotifier fcn) {
|
||||
super("Search");
|
||||
|
||||
this.fcn = fcn;
|
||||
|
||||
final JPanel optionPanel = new JPanel(new BorderLayout());
|
||||
|
||||
final JPanel searchRadiusOpt = new JPanel(new BorderLayout());
|
||||
|
||||
final JPanel searchOpts = new JPanel(new GridLayout(2, 1));
|
||||
|
||||
searchRadiusOpt.add(new JLabel("Search from "), BorderLayout.WEST);
|
||||
|
||||
DefaultComboBoxModel model = new DefaultComboBoxModel();
|
||||
for (final SearchRadius st : SearchRadius.values()) {
|
||||
model.addElement(st);
|
||||
}
|
||||
|
||||
searchRadiusBox = new JComboBox(model);
|
||||
|
||||
searchRadiusOpt.add(searchRadiusBox, BorderLayout.CENTER);
|
||||
|
||||
searchOpts.add(searchRadiusOpt);
|
||||
|
||||
model = new DefaultComboBoxModel();
|
||||
for (final SearchType st : SearchType.values()) {
|
||||
model.addElement(st);
|
||||
}
|
||||
|
||||
final JComboBox typeBox = new JComboBox(model);
|
||||
final JPanel searchOptPanel = new JPanel();
|
||||
|
||||
final ItemListener il = new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(final ItemEvent arg0) {
|
||||
searchOptPanel.removeAll();
|
||||
searchType = (SearchType) typeBox.getSelectedItem();
|
||||
searchOptPanel.add(searchType.details.getPanel());
|
||||
super("Search");
|
||||
|
||||
searchOptPanel.revalidate();
|
||||
searchOptPanel.repaint();
|
||||
}
|
||||
};
|
||||
|
||||
typeBox.addItemListener(il);
|
||||
|
||||
typeBox.setSelectedItem(SearchType.LDC);
|
||||
il.itemStateChanged(null);
|
||||
|
||||
searchOpts.add(typeBox);
|
||||
|
||||
optionPanel.add(searchOpts, BorderLayout.NORTH);
|
||||
|
||||
JPanel p2 = new JPanel();
|
||||
p2.setLayout(new BorderLayout());
|
||||
p2.add(searchOptPanel, BorderLayout.NORTH);
|
||||
p2.add(exact, BorderLayout.SOUTH);
|
||||
|
||||
optionPanel.add(p2, BorderLayout.CENTER);
|
||||
|
||||
search.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent arg0) {
|
||||
treeRoot.removeAllChildren();
|
||||
searchType = (SearchType) typeBox.getSelectedItem();
|
||||
final SearchRadius radius = (SearchRadius) searchRadiusBox.getSelectedItem();
|
||||
final SearchResultNotifier srn = new SearchResultNotifier() {
|
||||
@Override
|
||||
public void notifyOfResult(String debug) {
|
||||
treeRoot.add(new DefaultMutableTreeNode(debug));
|
||||
}
|
||||
};
|
||||
if (radius == SearchRadius.All_Classes) {
|
||||
if(t.finished) {
|
||||
t = new BackgroundSearchThread() {
|
||||
this.fcn = fcn;
|
||||
|
||||
final JPanel optionPanel = new JPanel(new BorderLayout());
|
||||
|
||||
final JPanel searchRadiusOpt = new JPanel(new BorderLayout());
|
||||
|
||||
final JPanel searchOpts = new JPanel(new GridLayout(2, 1));
|
||||
|
||||
searchRadiusOpt.add(new JLabel("Search from "), BorderLayout.WEST);
|
||||
|
||||
DefaultComboBoxModel model = new DefaultComboBoxModel();
|
||||
for (final SearchRadius st : SearchRadius.values()) {
|
||||
model.addElement(st);
|
||||
}
|
||||
|
||||
searchRadiusBox = new JComboBox(model);
|
||||
|
||||
searchRadiusOpt.add(searchRadiusBox, BorderLayout.CENTER);
|
||||
|
||||
searchOpts.add(searchRadiusOpt);
|
||||
|
||||
model = new DefaultComboBoxModel();
|
||||
for (final SearchType st : SearchType.values()) {
|
||||
model.addElement(st);
|
||||
}
|
||||
|
||||
final JComboBox typeBox = new JComboBox(model);
|
||||
final JPanel searchOptPanel = new JPanel();
|
||||
|
||||
final ItemListener il = new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(final ItemEvent arg0) {
|
||||
searchOptPanel.removeAll();
|
||||
searchType = (SearchType) typeBox.getSelectedItem();
|
||||
searchOptPanel.add(searchType.details.getPanel());
|
||||
|
||||
searchOptPanel.revalidate();
|
||||
searchOptPanel.repaint();
|
||||
}
|
||||
};
|
||||
|
||||
typeBox.addItemListener(il);
|
||||
|
||||
typeBox.setSelectedItem(SearchType.LDC);
|
||||
il.itemStateChanged(null);
|
||||
|
||||
searchOpts.add(typeBox);
|
||||
|
||||
optionPanel.add(searchOpts, BorderLayout.NORTH);
|
||||
|
||||
JPanel p2 = new JPanel();
|
||||
p2.setLayout(new BorderLayout());
|
||||
p2.add(searchOptPanel, BorderLayout.NORTH);
|
||||
p2.add(exact, BorderLayout.SOUTH);
|
||||
|
||||
optionPanel.add(p2, BorderLayout.CENTER);
|
||||
|
||||
search.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent arg0) {
|
||||
treeRoot.removeAllChildren();
|
||||
searchType = (SearchType) typeBox.getSelectedItem();
|
||||
final SearchRadius radius = (SearchRadius) searchRadiusBox
|
||||
.getSelectedItem();
|
||||
final SearchResultNotifier srn = new SearchResultNotifier() {
|
||||
@Override
|
||||
public void notifyOfResult(String debug) {
|
||||
treeRoot.add(new DefaultMutableTreeNode(debug));
|
||||
}
|
||||
};
|
||||
if (radius == SearchRadius.All_Classes) {
|
||||
if (t.finished) {
|
||||
t = new BackgroundSearchThread() {
|
||||
@Override
|
||||
public void doSearch() {
|
||||
for (ClassNode cln : BytecodeViewer.getLoadedClasses())
|
||||
searchType.details.search(cln, srn, exact.isSelected());
|
||||
|
||||
MainViewerGUI.getComponent(SearchingPane.class).search.setEnabled(true);
|
||||
MainViewerGUI.getComponent(SearchingPane.class).search.setText("Search");
|
||||
tree.expandPath(new TreePath(tree.getModel().getRoot()));
|
||||
tree.updateUI();
|
||||
for (ClassNode cln : BytecodeViewer
|
||||
.getLoadedClasses())
|
||||
searchType.details.search(cln, srn,
|
||||
exact.isSelected());
|
||||
|
||||
MainViewerGUI.getComponent(SearchingPane.class).search
|
||||
.setEnabled(true);
|
||||
MainViewerGUI.getComponent(SearchingPane.class).search
|
||||
.setText("Search");
|
||||
tree.expandPath(new TreePath(tree.getModel()
|
||||
.getRoot()));
|
||||
tree.updateUI();
|
||||
}
|
||||
|
||||
};
|
||||
MainViewerGUI.getComponent(SearchingPane.class).search.setEnabled(false);
|
||||
MainViewerGUI.getComponent(SearchingPane.class).search.setText("Searching, please wait..");
|
||||
t.start();
|
||||
} else { //this should really never be called.
|
||||
BytecodeViewer.showMessage("You currently have a search performing in the background, please wait for that to finish.");
|
||||
}
|
||||
}
|
||||
else if (radius == SearchRadius.Current_Class) {
|
||||
final ClassViewer cv = MainViewerGUI.getComponent(WorkPane.class).getCurrentClass();
|
||||
if (cv != null) {
|
||||
searchType.details.search(cv.cn, srn, exact.isSelected());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
optionPanel.add(search, BorderLayout.SOUTH);
|
||||
|
||||
this.tree = new JTree(treeRoot);
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
|
||||
getContentPane().add(optionPanel, BorderLayout.NORTH);
|
||||
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
|
||||
|
||||
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(final TreeSelectionEvent arg0) {
|
||||
String path = arg0.getPath().toString();
|
||||
|
||||
String className = path.split(", ")[1].split("\\.")[0];
|
||||
final ClassNode fN = BytecodeViewer.getClassNode(className);
|
||||
if (fN != null) {
|
||||
MainViewerGUI.getComponent(FileNavigationPane.class).openClassFileToWorkSpace(className, fN);
|
||||
}
|
||||
|
||||
System.out.println(className);
|
||||
}
|
||||
});
|
||||
|
||||
this.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
public enum SearchType {
|
||||
LDC (new LDCSearch()),
|
||||
Regex (new RegexSearch()),
|
||||
MethodCall (new MethodCallSearch()),
|
||||
FieldCall (new FieldCallSearch());
|
||||
|
||||
public final SearchTypeDetails details;
|
||||
|
||||
SearchType(final SearchTypeDetails details) {
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
public enum SearchRadius {
|
||||
All_Classes,
|
||||
Current_Class;
|
||||
}
|
||||
|
||||
};
|
||||
MainViewerGUI.getComponent(SearchingPane.class).search
|
||||
.setEnabled(false);
|
||||
MainViewerGUI.getComponent(SearchingPane.class).search
|
||||
.setText("Searching, please wait..");
|
||||
t.start();
|
||||
} else { // this should really never be called.
|
||||
BytecodeViewer
|
||||
.showMessage("You currently have a search performing in the background, please wait for that to finish.");
|
||||
}
|
||||
} else if (radius == SearchRadius.Current_Class) {
|
||||
final ClassViewer cv = MainViewerGUI.getComponent(
|
||||
WorkPane.class).getCurrentClass();
|
||||
if (cv != null) {
|
||||
searchType.details.search(cv.cn, srn,
|
||||
exact.isSelected());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
optionPanel.add(search, BorderLayout.SOUTH);
|
||||
|
||||
this.tree = new JTree(treeRoot);
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
|
||||
getContentPane().add(optionPanel, BorderLayout.NORTH);
|
||||
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
|
||||
|
||||
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(final TreeSelectionEvent arg0) {
|
||||
String path = arg0.getPath().toString();
|
||||
|
||||
String className = path.split(", ")[1].split("\\.")[0];
|
||||
final ClassNode fN = BytecodeViewer.getClassNode(className);
|
||||
if (fN != null) {
|
||||
MainViewerGUI.getComponent(FileNavigationPane.class)
|
||||
.openClassFileToWorkSpace(className, fN);
|
||||
}
|
||||
|
||||
System.out.println(className);
|
||||
}
|
||||
});
|
||||
|
||||
this.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
public enum SearchType {
|
||||
LDC(new LDCSearch()), Regex(new RegexSearch()), MethodCall(
|
||||
new MethodCallSearch()), FieldCall(new FieldCallSearch());
|
||||
|
||||
public final SearchTypeDetails details;
|
||||
|
||||
SearchType(final SearchTypeDetails details) {
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
public enum SearchRadius {
|
||||
All_Classes, Current_Class;
|
||||
}
|
||||
|
||||
public void resetWorkspace() {
|
||||
treeRoot.removeAllChildren();
|
||||
tree.updateUI();
|
||||
tree.updateUI();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
|
@ -21,8 +22,7 @@ import javax.swing.JTabbedPane;
|
|||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
|
||||
/**
|
||||
* Component to be used as tabComponent;
|
||||
* Contains a JLabel to show the text and
|
||||
* Component to be used as tabComponent; Contains a JLabel to show the text and
|
||||
* a JButton to close the tab it belongs to
|
||||
*
|
||||
* @author Konloch
|
||||
|
@ -33,131 +33,145 @@ 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));
|
||||
if (pane == null)
|
||||
throw new NullPointerException("TabbedPane is null");
|
||||
this.pane = pane;
|
||||
setOpaque(false);
|
||||
|
||||
//make JLabel read titles from JTabbedPane
|
||||
final JLabel label = new JLabel() {
|
||||
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));
|
||||
if (pane == null)
|
||||
throw new NullPointerException("TabbedPane is null");
|
||||
this.pane = pane;
|
||||
setOpaque(false);
|
||||
|
||||
// make JLabel read titles from JTabbedPane
|
||||
final JLabel label = new JLabel() {
|
||||
private static final long serialVersionUID = -5511025206527893360L;
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
final int i = pane.indexOfTabComponent(TabbedPane.this);
|
||||
if (i != -1)
|
||||
return pane.getTitleAt(i);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
add(label);
|
||||
//add more space between the label and the button
|
||||
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
|
||||
//tab button
|
||||
add(button);
|
||||
//add more space to the top of the component
|
||||
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
|
||||
button.addMouseListener(new MouseListener() {
|
||||
public String getText() {
|
||||
final int i = pane.indexOfTabComponent(TabbedPane.this);
|
||||
if (i != -1)
|
||||
return pane.getTitleAt(i);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
add(label);
|
||||
// add more space between the label and the button
|
||||
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
|
||||
// tab button
|
||||
add(button);
|
||||
// add more space to the top of the component
|
||||
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
|
||||
button.addMouseListener(new MouseListener() {
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
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) {}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private class TabButton extends JButton implements ActionListener {
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent arg0) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent arg0) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent arg0) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private class TabButton extends JButton implements ActionListener {
|
||||
private static final long serialVersionUID = -4492967978286454159L;
|
||||
|
||||
public TabButton() {
|
||||
final int size = 17;
|
||||
setPreferredSize(new Dimension(size, size));
|
||||
setToolTipText("Close this tab");
|
||||
//Make the button looks the same for all Laf's
|
||||
setUI(new BasicButtonUI());
|
||||
//Make it transparent
|
||||
setContentAreaFilled(false);
|
||||
//No need to be focusable
|
||||
setFocusable(false);
|
||||
setBorder(BorderFactory.createEtchedBorder());
|
||||
setBorderPainted(false);
|
||||
//Making nice rollover effect
|
||||
//we use the same listener for all buttons
|
||||
addMouseListener(buttonMouseListener);
|
||||
setRolloverEnabled(true);
|
||||
//Close the proper tab by clicking the button
|
||||
addActionListener(this);
|
||||
}
|
||||
final int size = 17;
|
||||
setPreferredSize(new Dimension(size, size));
|
||||
setToolTipText("Close this tab");
|
||||
// Make the button looks the same for all Laf's
|
||||
setUI(new BasicButtonUI());
|
||||
// Make it transparent
|
||||
setContentAreaFilled(false);
|
||||
// No need to be focusable
|
||||
setFocusable(false);
|
||||
setBorder(BorderFactory.createEtchedBorder());
|
||||
setBorderPainted(false);
|
||||
// Making nice rollover effect
|
||||
// we use the same listener for all buttons
|
||||
addMouseListener(buttonMouseListener);
|
||||
setRolloverEnabled(true);
|
||||
// Close the proper tab by clicking the button
|
||||
addActionListener(this);
|
||||
}
|
||||
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final int i = pane.indexOfTabComponent(TabbedPane.this);
|
||||
if (i != -1) {
|
||||
pane.remove(i);
|
||||
}
|
||||
}
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final int i = pane.indexOfTabComponent(TabbedPane.this);
|
||||
if (i != -1) {
|
||||
pane.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
//we don't want to update UI for this button
|
||||
@Override
|
||||
public void updateUI() {
|
||||
}
|
||||
// we don't want to update UI for this button
|
||||
@Override
|
||||
public void updateUI() {
|
||||
}
|
||||
|
||||
//paint the cross
|
||||
@Override
|
||||
protected void paintComponent(final Graphics g) {
|
||||
super.paintComponent(g);
|
||||
final Graphics2D g2 = (Graphics2D) g.create();
|
||||
//shift the image for pressed buttons
|
||||
if (getModel().isPressed()) {
|
||||
g2.translate(1, 1);
|
||||
}
|
||||
g2.setStroke(new BasicStroke(2));
|
||||
g2.setColor(Color.BLACK);
|
||||
if (getModel().isRollover()) {
|
||||
g2.setColor(Color.MAGENTA);
|
||||
}
|
||||
final int delta = 6;
|
||||
g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
|
||||
g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
// paint the cross
|
||||
@Override
|
||||
protected void paintComponent(final Graphics g) {
|
||||
super.paintComponent(g);
|
||||
final Graphics2D g2 = (Graphics2D) g.create();
|
||||
// shift the image for pressed buttons
|
||||
if (getModel().isPressed()) {
|
||||
g2.translate(1, 1);
|
||||
}
|
||||
g2.setStroke(new BasicStroke(2));
|
||||
g2.setColor(Color.BLACK);
|
||||
if (getModel().isRollover()) {
|
||||
g2.setColor(Color.MAGENTA);
|
||||
}
|
||||
final int delta = 6;
|
||||
g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight()
|
||||
- delta - 1);
|
||||
g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight()
|
||||
- delta - 1);
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private final static MouseListener buttonMouseListener = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(final MouseEvent e) {
|
||||
final Component component = e.getComponent();
|
||||
if (component instanceof AbstractButton) {
|
||||
final AbstractButton button = (AbstractButton) component;
|
||||
button.setBorderPainted(true);
|
||||
}
|
||||
}
|
||||
private final static MouseListener buttonMouseListener = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(final MouseEvent e) {
|
||||
final Component component = e.getComponent();
|
||||
if (component instanceof AbstractButton) {
|
||||
final AbstractButton button = (AbstractButton) component;
|
||||
button.setBorderPainted(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(final MouseEvent e) {
|
||||
final Component component = e.getComponent();
|
||||
if (component instanceof AbstractButton) {
|
||||
final AbstractButton button = (AbstractButton) component;
|
||||
button.setBorderPainted(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void mouseExited(final MouseEvent e) {
|
||||
final Component component = e.getComponent();
|
||||
if (component instanceof AbstractButton) {
|
||||
final AbstractButton button = (AbstractButton) component;
|
||||
button.setBorderPainted(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -12,24 +12,27 @@ import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class VisibleComponent extends JInternalFrame implements FileChangeNotifier {
|
||||
public abstract class VisibleComponent extends JInternalFrame implements
|
||||
FileChangeNotifier {
|
||||
|
||||
private static final long serialVersionUID = -6453413772343643526L;
|
||||
|
||||
public VisibleComponent(final String title) {
|
||||
super(title, false, false, false, false);
|
||||
this.setFrameIcon(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private VisibleComponent() { //because we want to enforce the title argument
|
||||
|
||||
super(title, false, false, false, false);
|
||||
this.setFrameIcon(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private VisibleComponent() { // because we want to enforce the title
|
||||
// argument
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openClassFile(final String name, final ClassNode cn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openClassFile(final String name, final ClassNode cn) {}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,113 +25,106 @@ import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class WorkPane extends VisibleComponent implements ActionListener {
|
||||
|
||||
|
||||
private static final long serialVersionUID = 6542337997679487946L;
|
||||
|
||||
|
||||
FileChangeNotifier fcn;
|
||||
JTabbedPane tabs;
|
||||
|
||||
JPanel buttonPanel;
|
||||
JButton refreshClass;
|
||||
|
||||
HashMap<String, Integer> workingOn = new HashMap<String, Integer>();
|
||||
|
||||
public static int SyntaxFontHeight = 12;
|
||||
|
||||
public WorkPane(final FileChangeNotifier fcn) {
|
||||
super("WorkPanel");
|
||||
setTitle("Work Space");
|
||||
|
||||
this.tabs = new JTabbedPane();
|
||||
this.fcn = fcn;
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
|
||||
getContentPane().add(tabs, BorderLayout.CENTER);
|
||||
|
||||
buttonPanel = new JPanel(new FlowLayout());
|
||||
|
||||
refreshClass = new JButton("Refresh class");
|
||||
refreshClass.addActionListener(this);
|
||||
|
||||
buttonPanel.add(refreshClass);
|
||||
|
||||
buttonPanel.setVisible(false);
|
||||
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
tabs.addContainerListener(new ContainerListener() {
|
||||
FileChangeNotifier fcn;
|
||||
JTabbedPane tabs;
|
||||
|
||||
@Override
|
||||
public void componentAdded(final ContainerEvent e) {
|
||||
}
|
||||
JPanel buttonPanel;
|
||||
JButton refreshClass;
|
||||
|
||||
@Override
|
||||
public void componentRemoved(final ContainerEvent e) {
|
||||
final Component c = e.getChild();
|
||||
if (c instanceof ClassViewer) {
|
||||
workingOn.remove(((ClassViewer)c).name);
|
||||
}
|
||||
}
|
||||
HashMap<String, Integer> workingOn = new HashMap<String, Integer>();
|
||||
|
||||
});
|
||||
tabs.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(final ChangeEvent arg0) {
|
||||
buttonPanel.setVisible(tabs.getSelectedIndex() != -1);
|
||||
}
|
||||
});
|
||||
|
||||
this.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
int tabCount = 0;
|
||||
|
||||
public void addWorkingFile(final String name, final ClassNode cn) {
|
||||
if(!BytecodeViewer.viewer.hexPane.isSelected() &&
|
||||
!BytecodeViewer.viewer.sourcePane.isSelected() &&
|
||||
!BytecodeViewer.viewer.bytecodePane.isSelected()) {
|
||||
BytecodeViewer.showMessage("You currently have no viewing panes selected.");
|
||||
return;
|
||||
}
|
||||
if (!workingOn.containsKey(name)) {
|
||||
final Component tabComp = new ClassViewer(name, cn);
|
||||
tabs.add(tabComp);
|
||||
final int tabCount = tabs.indexOfComponent(tabComp);
|
||||
workingOn.put(name, tabCount);
|
||||
tabs.setTabComponentAt(tabCount, new TabbedPane(tabs));
|
||||
tabs.setSelectedIndex(tabCount);
|
||||
} else {
|
||||
tabs.setSelectedIndex(workingOn.get(name));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openClassFile(final String name, final ClassNode cn) {
|
||||
addWorkingFile(name, cn);
|
||||
}
|
||||
|
||||
public ClassViewer getCurrentClass() {
|
||||
return (ClassViewer) tabs.getSelectedComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent arg0) {
|
||||
final JButton src = (JButton) arg0.getSource();
|
||||
if (src == refreshClass) {
|
||||
final Component tabComp = tabs.getSelectedComponent();
|
||||
if (tabComp != null) {
|
||||
public static int SyntaxFontHeight = 12;
|
||||
|
||||
public WorkPane(final FileChangeNotifier fcn) {
|
||||
super("WorkPanel");
|
||||
setTitle("Work Space");
|
||||
|
||||
this.tabs = new JTabbedPane();
|
||||
this.fcn = fcn;
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
|
||||
getContentPane().add(tabs, BorderLayout.CENTER);
|
||||
|
||||
buttonPanel = new JPanel(new FlowLayout());
|
||||
|
||||
refreshClass = new JButton("Refresh class");
|
||||
refreshClass.addActionListener(this);
|
||||
|
||||
buttonPanel.add(refreshClass);
|
||||
|
||||
buttonPanel.setVisible(false);
|
||||
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
tabs.addContainerListener(new ContainerListener() {
|
||||
|
||||
@Override
|
||||
public void componentAdded(final ContainerEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentRemoved(final ContainerEvent e) {
|
||||
final Component c = e.getChild();
|
||||
if (c instanceof ClassViewer) {
|
||||
workingOn.remove(((ClassViewer) c).name);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
tabs.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(final ChangeEvent arg0) {
|
||||
buttonPanel.setVisible(tabs.getSelectedIndex() != -1);
|
||||
}
|
||||
});
|
||||
|
||||
this.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
int tabCount = 0;
|
||||
|
||||
public void addWorkingFile(final String name, final ClassNode cn) {
|
||||
if (!workingOn.containsKey(name)) {
|
||||
final Component tabComp = new ClassViewer(name, cn);
|
||||
tabs.add(tabComp);
|
||||
final int tabCount = tabs.indexOfComponent(tabComp);
|
||||
workingOn.put(name, tabCount);
|
||||
tabs.setTabComponentAt(tabCount, new TabbedPane(tabs));
|
||||
tabs.setSelectedIndex(tabCount);
|
||||
} else {
|
||||
tabs.setSelectedIndex(workingOn.get(name));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openClassFile(final String name, final ClassNode cn) {
|
||||
addWorkingFile(name, cn);
|
||||
}
|
||||
|
||||
public ClassViewer getCurrentClass() {
|
||||
return (ClassViewer) tabs.getSelectedComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent arg0) {
|
||||
final JButton src = (JButton) arg0.getSource();
|
||||
if (src == refreshClass) {
|
||||
final Component tabComp = tabs.getSelectedComponent();
|
||||
if (tabComp != null) {
|
||||
BytecodeViewer.viewer.setC(true);
|
||||
((ClassViewer)tabComp).startPaneUpdater();
|
||||
((ClassViewer) tabComp).startPaneUpdater();
|
||||
BytecodeViewer.viewer.setC(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void resetWorkspace() {
|
||||
tabs.removeAll();
|
||||
|
|
|
@ -15,40 +15,44 @@ public abstract class JavaObfuscator extends Thread {
|
|||
BytecodeViewer.runningObfuscation = false;
|
||||
BytecodeViewer.viewer.setIcon(false);
|
||||
}
|
||||
|
||||
|
||||
public int getStringLength() {
|
||||
if(BytecodeViewer.viewer.obfuscatorGroup.isSelected(BytecodeViewer.viewer.strongObf.getModel())) {
|
||||
if (BytecodeViewer.viewer.obfuscatorGroup
|
||||
.isSelected(BytecodeViewer.viewer.strongObf.getModel())) {
|
||||
return MAX_STRING_LENGTH;
|
||||
} else { //if(BytecodeViewer.viewer.obfuscatorGroup.isSelected(BytecodeViewer.viewer.lightObf.getModel())) {
|
||||
} else { // if(BytecodeViewer.viewer.obfuscatorGroup.isSelected(BytecodeViewer.viewer.lightObf.getModel()))
|
||||
// {
|
||||
return MIN_STRING_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int MAX_STRING_LENGTH = 250;
|
||||
public static int MIN_STRING_LENGTH = 20;
|
||||
private ArrayList<String> names = new ArrayList<String>();
|
||||
private static final String AB = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
private static final String AN = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
private static Random rnd = new Random();
|
||||
|
||||
private static String randomString(int len) {
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for( int i = 0; i < len; i++ )
|
||||
sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
|
||||
return sb.toString();
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
sb.append(AB.charAt(rnd.nextInt(AB.length())));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String randomStringNum(int len) {
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for( int i = 0; i < len; i++ )
|
||||
sb.append( AN.charAt( rnd.nextInt(AN.length()) ) );
|
||||
return sb.toString();
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
sb.append(AN.charAt(rnd.nextInt(AN.length())));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
protected String generateUniqueName(int length) {
|
||||
boolean found = false;
|
||||
String name = "";
|
||||
while(!found) {
|
||||
String nameTry = randomString(1) + randomStringNum(length-1);
|
||||
if(!names.contains(nameTry)) {
|
||||
while (!found) {
|
||||
String nameTry = randomString(1) + randomStringNum(length - 1);
|
||||
if (!names.contains(nameTry)) {
|
||||
names.add(nameTry);
|
||||
name = nameTry;
|
||||
found = true;
|
||||
|
|
|
@ -6,18 +6,18 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|||
import the.bytecode.club.bytecodeviewer.api.ASMUtil_OLD;
|
||||
|
||||
public class RenameClasses extends JavaObfuscator {
|
||||
|
||||
|
||||
@Override
|
||||
public void obfuscate() {
|
||||
int stringLength = getStringLength();
|
||||
|
||||
|
||||
System.out.println("Obfuscating class names...");
|
||||
for(ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
for (ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
String newName = generateUniqueName(stringLength);
|
||||
ASMUtil_OLD.renameClassNode(c.name, newName);
|
||||
c.name = newName;
|
||||
}
|
||||
|
||||
|
||||
System.out.println("Obfuscated class names.");
|
||||
}
|
||||
|
||||
|
|
|
@ -7,21 +7,22 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|||
import the.bytecode.club.bytecodeviewer.api.ASMUtil_OLD;
|
||||
|
||||
public class RenameFields extends JavaObfuscator {
|
||||
|
||||
|
||||
@Override
|
||||
public void obfuscate() {
|
||||
int stringLength = getStringLength();
|
||||
|
||||
|
||||
System.out.println("Obfuscating fields names...");
|
||||
for(ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
for(Object o : c.fields.toArray()) {
|
||||
FieldNode f = (FieldNode)o;
|
||||
for (ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
for (Object o : c.fields.toArray()) {
|
||||
FieldNode f = (FieldNode) o;
|
||||
String newName = generateUniqueName(stringLength);
|
||||
ASMUtil_OLD.renameFieldNode(c.name,f.name,f.desc, null, newName, null);
|
||||
ASMUtil_OLD.renameFieldNode(c.name, f.name, f.desc, null,
|
||||
newName, null);
|
||||
f.name = newName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
System.out.println("Obfuscated field names.");
|
||||
}
|
||||
|
||||
|
|
|
@ -8,35 +8,40 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|||
import the.bytecode.club.bytecodeviewer.api.ASMUtil_OLD;
|
||||
|
||||
public class RenameMethods extends JavaObfuscator {
|
||||
|
||||
|
||||
@Override
|
||||
public void obfuscate() {
|
||||
int stringLength = getStringLength();
|
||||
|
||||
|
||||
System.out.println("Obfuscating method names...");
|
||||
for(ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
for(Object o : c.methods.toArray()) {
|
||||
MethodNode m = (MethodNode)o;
|
||||
if( m.access != Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_ABSTRACT + Opcodes.ACC_STATIC &&
|
||||
m.access != Opcodes.ACC_ABSTRACT + Opcodes.ACC_STATIC + Opcodes.ACC_PUBLIC &&
|
||||
m.access != Opcodes.ACC_ABSTRACT + Opcodes.ACC_STATIC + Opcodes.ACC_PRIVATE &&
|
||||
m.access != Opcodes.ACC_ABSTRACT + Opcodes.ACC_STATIC + Opcodes.ACC_PROTECTED &&
|
||||
m.access != Opcodes.ACC_ABSTRACT + Opcodes.ACC_PUBLIC &&
|
||||
m.access != Opcodes.ACC_ABSTRACT + Opcodes.ACC_PRIVATE &&
|
||||
m.access != Opcodes.ACC_ABSTRACT + Opcodes.ACC_PROTECTED)
|
||||
{
|
||||
if(!m.name.equals("main") &&
|
||||
!m.name.equals("<init>") &&
|
||||
!m.name.equals("<clinit>"))
|
||||
{
|
||||
for (ClassNode c : BytecodeViewer.getLoadedClasses()) {
|
||||
for (Object o : c.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
if (m.access != Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_ABSTRACT
|
||||
+ Opcodes.ACC_STATIC
|
||||
&& m.access != Opcodes.ACC_ABSTRACT
|
||||
+ Opcodes.ACC_STATIC + Opcodes.ACC_PUBLIC
|
||||
&& m.access != Opcodes.ACC_ABSTRACT
|
||||
+ Opcodes.ACC_STATIC + Opcodes.ACC_PRIVATE
|
||||
&& m.access != Opcodes.ACC_ABSTRACT
|
||||
+ Opcodes.ACC_STATIC + Opcodes.ACC_PROTECTED
|
||||
&& m.access != Opcodes.ACC_ABSTRACT
|
||||
+ Opcodes.ACC_PUBLIC
|
||||
&& m.access != Opcodes.ACC_ABSTRACT
|
||||
+ Opcodes.ACC_PRIVATE
|
||||
&& m.access != Opcodes.ACC_ABSTRACT
|
||||
+ Opcodes.ACC_PROTECTED) {
|
||||
if (!m.name.equals("main") && !m.name.equals("<init>")
|
||||
&& !m.name.equals("<clinit>")) {
|
||||
String newName = generateUniqueName(stringLength);
|
||||
ASMUtil_OLD.renameMethodNode(c.name,m.name,m.desc,null,newName,null);
|
||||
ASMUtil_OLD.renameMethodNode(c.name, m.name, m.desc,
|
||||
null, newName, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
System.out.println("Obfuscated method names.");
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import the.bytecode.club.bytecodeviewer.api.Plugin;
|
|||
* Coming soon.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class AllatoriStringDecrypter extends Plugin {
|
||||
|
|
|
@ -20,15 +20,16 @@ import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
|||
import the.bytecode.club.bytecodeviewer.gui.GraphicialReflectionKit;
|
||||
|
||||
/**
|
||||
* EZ Injection - This plugin is designed to provide a graphical way for the user to
|
||||
* easily change the access modifiers of all fields/methods, insert hooks into all
|
||||
* functions, and invoke the main function. It also contains an option to launch the
|
||||
* graphical reflection kit, which is pretty much a GUI for reflection.
|
||||
* EZ Injection - This plugin is designed to provide a graphical way for the
|
||||
* user to easily change the access modifiers of all fields/methods, insert
|
||||
* hooks into all functions, and invoke the main function. It also contains an
|
||||
* option to launch the graphical reflection kit, which is pretty much a GUI for
|
||||
* reflection.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
* TODO:
|
||||
* figure out a way to block runtime.exec without java agents, maybe by replacing the method call?
|
||||
* TODO: figure out a way to block runtime.exec without java agents,
|
||||
* maybe by replacing the method call?
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -36,40 +37,33 @@ public class EZInjection extends Plugin {
|
|||
|
||||
public static ArrayList<BytecodeHook> hookArray = new ArrayList<BytecodeHook>();
|
||||
private static String version = "1.0";
|
||||
private static PluginConsole gui = new PluginConsole("EZ Injection v"+version);
|
||||
private boolean
|
||||
accessModifiers,
|
||||
injectHooks,
|
||||
invokeMethod,
|
||||
useProxy,
|
||||
launchKit,
|
||||
console;
|
||||
public static boolean
|
||||
sandboxSystem,
|
||||
sandboxRuntime,
|
||||
printCmdL;
|
||||
private static boolean
|
||||
debugHooks,
|
||||
all = false;
|
||||
private String
|
||||
invokeMethodInformation,
|
||||
proxy;
|
||||
|
||||
private static PluginConsole gui = new PluginConsole("EZ Injection v"
|
||||
+ version);
|
||||
private boolean accessModifiers, injectHooks, invokeMethod, useProxy,
|
||||
launchKit, console;
|
||||
public static boolean sandboxSystem, sandboxRuntime, printCmdL;
|
||||
private static boolean debugHooks, all = false;
|
||||
private String invokeMethodInformation, proxy;
|
||||
|
||||
private static String[] debugClasses;
|
||||
|
||||
public EZInjection(boolean accessModifiers, boolean injectHooks, boolean debugHooks,
|
||||
boolean invokeMethod, String invokeMethodInformation, boolean sandboxRuntime,
|
||||
boolean sandboxSystem, String debugClasses, String proxy, boolean useProxy,
|
||||
boolean launchKit, boolean console, boolean printCmdL) {
|
||||
the.bytecode.club.bytecodeviewer.api.BytecodeViewer.createNewClassNodeLoaderInstance();
|
||||
|
||||
public EZInjection(boolean accessModifiers, boolean injectHooks,
|
||||
boolean debugHooks, boolean invokeMethod,
|
||||
String invokeMethodInformation, boolean sandboxRuntime,
|
||||
boolean sandboxSystem, String debugClasses, String proxy,
|
||||
boolean useProxy, boolean launchKit, boolean console,
|
||||
boolean printCmdL) {
|
||||
the.bytecode.club.bytecodeviewer.api.BytecodeViewer
|
||||
.createNewClassNodeLoaderInstance();
|
||||
this.accessModifiers = accessModifiers;
|
||||
this.injectHooks = injectHooks;
|
||||
EZInjection.debugHooks = debugHooks;
|
||||
this.invokeMethod = invokeMethod;
|
||||
this.invokeMethodInformation = invokeMethodInformation+"([Ljava/lang/String;)V";
|
||||
this.invokeMethodInformation = invokeMethodInformation
|
||||
+ "([Ljava/lang/String;)V";
|
||||
EZInjection.sandboxRuntime = sandboxRuntime;
|
||||
EZInjection.sandboxSystem = sandboxSystem;
|
||||
if(debugClasses.equals("*"))
|
||||
if (debugClasses.equals("*"))
|
||||
EZInjection.all = true;
|
||||
else
|
||||
EZInjection.debugClasses = debugClasses.split(",");
|
||||
|
@ -79,188 +73,242 @@ public class EZInjection extends Plugin {
|
|||
this.console = console;
|
||||
EZInjection.printCmdL = printCmdL;
|
||||
}
|
||||
|
||||
|
||||
public static void setProxy(String host, String port) {
|
||||
System.setProperty("java.net.useSystemProxies", "true");
|
||||
System.setProperty("socksProxyHost", host);
|
||||
System.setProperty("socksProxyPort", port);
|
||||
System.setProperty("socksProxyHost", host);
|
||||
System.setProperty("socksProxyPort", port);
|
||||
}
|
||||
|
||||
|
||||
private static String lastMessage = "";
|
||||
|
||||
public static void hook(String info) {
|
||||
for(BytecodeHook hook : hookArray)
|
||||
for (BytecodeHook hook : hookArray)
|
||||
hook.callHook(info);
|
||||
|
||||
if(debugHooks) {
|
||||
if(lastMessage.equals(info)) //just a small anti spam measurement
|
||||
|
||||
if (debugHooks) {
|
||||
if (lastMessage.equals(info)) // just a small anti spam measurement
|
||||
return;
|
||||
|
||||
|
||||
lastMessage = info;
|
||||
|
||||
|
||||
boolean print = all;
|
||||
|
||||
if(!all && debugClasses.length >= 1) {
|
||||
for(String s : debugClasses) {
|
||||
if(info.split("\\.")[0].equals(s.replaceAll("\\.", "/")))
|
||||
|
||||
if (!all && debugClasses.length >= 1) {
|
||||
for (String s : debugClasses) {
|
||||
if (info.split("\\.")[0].equals(s.replaceAll("\\.", "/")))
|
||||
print = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(print)
|
||||
print("Method call: "+info);
|
||||
|
||||
if (print)
|
||||
print("Method call: " + info);
|
||||
}
|
||||
}
|
||||
|
||||
public static void print(String message) {
|
||||
if(printCmdL)
|
||||
if (printCmdL)
|
||||
System.out.println(message);
|
||||
|
||||
if(gui.isVisible())
|
||||
|
||||
if (gui.isVisible())
|
||||
gui.appendText(message);
|
||||
}
|
||||
|
||||
|
||||
public static void exit(int i) {
|
||||
print("[SANDBOX] Tried to call on System.exit("+i+"), it's been blocked.");
|
||||
print("[SANDBOX] Tried to call on System.exit(" + i
|
||||
+ "), it's been blocked.");
|
||||
}
|
||||
|
||||
public static void exitR(int i) {
|
||||
print("[SANDBOX] Tried to call on Runtime.exit("+i+"), it's been blocked.");
|
||||
print("[SANDBOX] Tried to call on Runtime.exit(" + i
|
||||
+ "), it's been blocked.");
|
||||
}
|
||||
|
||||
|
||||
public static void announceSystem(String s) {
|
||||
print("[SANDBOX] Tried to call on Runtime.exec("+s+"), it's been blocked.");
|
||||
print("[SANDBOX] Tried to call on Runtime.exec(" + s
|
||||
+ "), it's been blocked.");
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void execute(ArrayList<ClassNode> classNodeList) {
|
||||
BytecodeViewer.viewer.setIcon(true);
|
||||
gui.setText("");
|
||||
|
||||
if(console)
|
||||
|
||||
if (console)
|
||||
gui.setVisible(true);
|
||||
|
||||
if(accessModifiers)
|
||||
|
||||
if (accessModifiers)
|
||||
print("Setting all of the access modifiers to public/public static.");
|
||||
if(injectHooks)
|
||||
if (injectHooks)
|
||||
print("Injecting hook...");
|
||||
if(debugHooks)
|
||||
if (debugHooks)
|
||||
print("Hooks are debugging.");
|
||||
else if(injectHooks)
|
||||
else if (injectHooks)
|
||||
print("Hooks are not debugging.");
|
||||
else
|
||||
print("Hooks are disabled completely.");
|
||||
if(sandboxRuntime || sandboxSystem)
|
||||
print("Sandboxing runtime: " + sandboxRuntime+", system: " +sandboxSystem+".");
|
||||
if (sandboxRuntime || sandboxSystem)
|
||||
print("Sandboxing runtime: " + sandboxRuntime + ", system: "
|
||||
+ sandboxSystem + ".");
|
||||
else
|
||||
print("WARNING: Sandboxing is disabled, this is NOT SAFE!");
|
||||
if(useProxy)
|
||||
print("Forcing proxy as '" + proxy +"'.");
|
||||
if(launchKit)
|
||||
if (useProxy)
|
||||
print("Forcing proxy as '" + proxy + "'.");
|
||||
if (launchKit)
|
||||
print("Launching the Graphicial Reflection Kit upon a succcessful invoke of the main method.");
|
||||
|
||||
for(ClassNode classNode : classNodeList) {
|
||||
for(Object o : classNode.fields.toArray()) {
|
||||
|
||||
for (ClassNode classNode : classNodeList) {
|
||||
for (Object o : classNode.fields.toArray()) {
|
||||
FieldNode f = (FieldNode) o;
|
||||
|
||||
if(accessModifiers) {
|
||||
if(f.access == Opcodes.ACC_PRIVATE || f.access == Opcodes.ACC_PROTECTED)
|
||||
if (accessModifiers) {
|
||||
if (f.access == Opcodes.ACC_PRIVATE
|
||||
|| f.access == Opcodes.ACC_PROTECTED)
|
||||
f.access = Opcodes.ACC_PUBLIC;
|
||||
|
||||
if(f.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC || f.access == Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC)
|
||||
if (f.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC
|
||||
|| f.access == Opcodes.ACC_PROTECTED
|
||||
+ Opcodes.ACC_STATIC)
|
||||
f.access = Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC;
|
||||
|
||||
if(f.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL || f.access == Opcodes.ACC_PROTECTED + Opcodes.ACC_FINAL)
|
||||
if (f.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL
|
||||
|| f.access == Opcodes.ACC_PROTECTED
|
||||
+ Opcodes.ACC_FINAL)
|
||||
f.access = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL;
|
||||
|
||||
if(f.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC || f.access == Opcodes.ACC_PROTECTED + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC)
|
||||
f.access = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC;
|
||||
|
||||
if (f.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL
|
||||
+ Opcodes.ACC_STATIC
|
||||
|| f.access == Opcodes.ACC_PROTECTED
|
||||
+ Opcodes.ACC_FINAL + Opcodes.ACC_STATIC)
|
||||
f.access = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL
|
||||
+ Opcodes.ACC_STATIC;
|
||||
}
|
||||
}
|
||||
for(Object o : classNode.methods.toArray()) {
|
||||
for (Object o : classNode.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
|
||||
if(accessModifiers) {
|
||||
if(m.access == Opcodes.ACC_PRIVATE || m.access == Opcodes.ACC_PROTECTED)
|
||||
if (accessModifiers) {
|
||||
if (m.access == Opcodes.ACC_PRIVATE
|
||||
|| m.access == Opcodes.ACC_PROTECTED)
|
||||
m.access = Opcodes.ACC_PUBLIC;
|
||||
|
||||
if(m.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC || m.access == Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC)
|
||||
|
||||
if (m.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC
|
||||
|| m.access == Opcodes.ACC_PROTECTED
|
||||
+ Opcodes.ACC_STATIC)
|
||||
m.access = Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC;
|
||||
|
||||
if(m.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL || m.access == Opcodes.ACC_PROTECTED + Opcodes.ACC_FINAL)
|
||||
if (m.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL
|
||||
|| m.access == Opcodes.ACC_PROTECTED
|
||||
+ Opcodes.ACC_FINAL)
|
||||
m.access = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL;
|
||||
|
||||
if(m.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC || m.access == Opcodes.ACC_PROTECTED + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC)
|
||||
m.access = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC;
|
||||
|
||||
if (m.access == Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL
|
||||
+ Opcodes.ACC_STATIC
|
||||
|| m.access == Opcodes.ACC_PROTECTED
|
||||
+ Opcodes.ACC_FINAL + Opcodes.ACC_STATIC)
|
||||
m.access = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL
|
||||
+ Opcodes.ACC_STATIC;
|
||||
}
|
||||
|
||||
if(injectHooks && m.access != Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_PRIVATE+Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_PROTECTED+Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_FINAL+Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_PRIVATE+Opcodes.ACC_FINAL+Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_PROTECTED+Opcodes.ACC_FINAL+Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC+Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_PRIVATE+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC+Opcodes.ACC_ABSTRACT &&
|
||||
m.access != Opcodes.ACC_PROTECTED+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC+Opcodes.ACC_ABSTRACT)
|
||||
{
|
||||
|
||||
if (injectHooks
|
||||
&& m.access != Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_PUBLIC
|
||||
+ Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_PRIVATE
|
||||
+ Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_PROTECTED
|
||||
+ Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_FINAL + Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL
|
||||
+ Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL
|
||||
+ Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_PROTECTED
|
||||
+ Opcodes.ACC_FINAL + Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL
|
||||
+ Opcodes.ACC_STATIC + Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL
|
||||
+ Opcodes.ACC_STATIC + Opcodes.ACC_ABSTRACT
|
||||
&& m.access != Opcodes.ACC_PROTECTED
|
||||
+ Opcodes.ACC_FINAL + Opcodes.ACC_STATIC
|
||||
+ Opcodes.ACC_ABSTRACT) {
|
||||
boolean inject = true;
|
||||
if(m.instructions.size() >= 2 && m.instructions.get(1) instanceof MethodInsnNode) {
|
||||
MethodInsnNode mn = (MethodInsnNode)m.instructions.get(1);
|
||||
if(mn.owner.equals("the/bytecode/club/bytecodeviewer/plugins/EZInjection")) //already been injected
|
||||
if (m.instructions.size() >= 2
|
||||
&& m.instructions.get(1) instanceof MethodInsnNode) {
|
||||
MethodInsnNode mn = (MethodInsnNode) m.instructions
|
||||
.get(1);
|
||||
if (mn.owner
|
||||
.equals("the/bytecode/club/bytecodeviewer/plugins/EZInjection")) // already
|
||||
// been
|
||||
// injected
|
||||
inject = false;
|
||||
}
|
||||
if(inject) {
|
||||
//make this function grab parameters eventually
|
||||
m.instructions.insert(new MethodInsnNode(Opcodes.INVOKESTATIC,
|
||||
"the/bytecode/club/bytecodeviewer/plugins/EZInjection",
|
||||
"hook",
|
||||
"(Ljava/lang/String;)V"));
|
||||
m.instructions.insert(new LdcInsnNode(classNode.name+"."+m.name+m.desc));
|
||||
if (inject) {
|
||||
// make this function grab parameters eventually
|
||||
m.instructions
|
||||
.insert(new MethodInsnNode(
|
||||
Opcodes.INVOKESTATIC,
|
||||
"the/bytecode/club/bytecodeviewer/plugins/EZInjection",
|
||||
"hook", "(Ljava/lang/String;)V"));
|
||||
m.instructions.insert(new LdcInsnNode(classNode.name
|
||||
+ "." + m.name + m.desc));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(sandboxRuntime) {
|
||||
ASMUtil_OLD.renameClassNode("java/lang/Runtime", "the/bytecode/club/bytecodeviewer/RuntimeOverride");
|
||||
if (sandboxRuntime) {
|
||||
ASMUtil_OLD.renameClassNode("java/lang/Runtime",
|
||||
"the/bytecode/club/bytecodeviewer/RuntimeOverride");
|
||||
}
|
||||
|
||||
if(sandboxSystem) {
|
||||
ASMUtil_OLD.renameMethodNode("java/lang/System", "exit", "(Ljava/lang/String;)V", "the/bytecode/club/bytecodeviewer/plugins/EZInjection", null, null);
|
||||
if (sandboxSystem) {
|
||||
ASMUtil_OLD.renameMethodNode("java/lang/System", "exit",
|
||||
"(Ljava/lang/String;)V",
|
||||
"the/bytecode/club/bytecodeviewer/plugins/EZInjection",
|
||||
null, null);
|
||||
}
|
||||
|
||||
if(useProxy) {
|
||||
|
||||
if (useProxy) {
|
||||
try {
|
||||
String[] split = proxy.split(":");
|
||||
setProxy(split[0], split[1]);
|
||||
} catch(Exception e) {
|
||||
//ignore
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
print("Done setting up.");
|
||||
|
||||
setFinished();
|
||||
|
||||
if(invokeMethod) {
|
||||
for(ClassNode cn : BytecodeViewer.getLoadedClasses()) //load all the classnodes into the classloader
|
||||
the.bytecode.club.bytecodeviewer.api.BytecodeViewer.getClassNodeLoader().addClass(cn);
|
||||
|
||||
print("Invoking " + invokeMethodInformation+":"+BytecodeViewer.nl+BytecodeViewer.nl);
|
||||
|
||||
for(ClassNode classNode : classNodeList) {
|
||||
for(Object o : classNode.methods.toArray()) {
|
||||
print("Done setting up.");
|
||||
|
||||
setFinished();
|
||||
|
||||
if (invokeMethod) {
|
||||
for (ClassNode cn : BytecodeViewer.getLoadedClasses())
|
||||
// load all the classnodes into the classloader
|
||||
the.bytecode.club.bytecodeviewer.api.BytecodeViewer
|
||||
.getClassNodeLoader().addClass(cn);
|
||||
|
||||
print("Invoking " + invokeMethodInformation + ":"
|
||||
+ BytecodeViewer.nl + BytecodeViewer.nl);
|
||||
|
||||
for (ClassNode classNode : classNodeList) {
|
||||
for (Object o : classNode.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
String methodInformation = classNode.name+"."+m.name+m.desc;
|
||||
if(invokeMethodInformation.equals(methodInformation)) {
|
||||
for(Method m2 : the.bytecode.club.bytecodeviewer.api.BytecodeViewer.getClassNodeLoader().nodeToClass(classNode).getMethods()) {
|
||||
if(m2.getName().equals(m.name)) {
|
||||
String methodInformation = classNode.name + "." + m.name
|
||||
+ m.desc;
|
||||
if (invokeMethodInformation.equals(methodInformation)) {
|
||||
for (Method m2 : the.bytecode.club.bytecodeviewer.api.BytecodeViewer
|
||||
.getClassNodeLoader().nodeToClass(classNode)
|
||||
.getMethods()) {
|
||||
if (m2.getName().equals(m.name)) {
|
||||
try {
|
||||
m2.invoke(classNode.getClass().newInstance(), (Object[])new String[1]);
|
||||
if(launchKit)
|
||||
new GraphicialReflectionKit().setVisible(true);
|
||||
m2.invoke(classNode.getClass()
|
||||
.newInstance(),
|
||||
(Object[]) new String[1]);
|
||||
if (launchKit)
|
||||
new GraphicialReflectionKit()
|
||||
.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw));
|
||||
|
@ -273,8 +321,8 @@ public class EZInjection extends Plugin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BytecodeViewer.viewer.setIcon(false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -15,28 +15,20 @@ import the.bytecode.club.bytecodeviewer.api.Plugin;
|
|||
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
||||
|
||||
/**
|
||||
* The idea/core was based off of J-RET's Malicious Code Searcher
|
||||
* I improved it, and added more stuff to search for.
|
||||
* The idea/core was based off of J-RET's Malicious Code Searcher I improved it,
|
||||
* and added more stuff to search for.
|
||||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class MaliciousCodeScanner extends Plugin {
|
||||
|
||||
public boolean
|
||||
ORE,
|
||||
ONE,
|
||||
ORU,
|
||||
OIO,
|
||||
LWW,
|
||||
LHT,
|
||||
LHS,
|
||||
LIP;
|
||||
|
||||
public MaliciousCodeScanner(boolean reflect, boolean runtime, boolean net, boolean io,
|
||||
boolean www, boolean http, boolean https, boolean ip) {
|
||||
public boolean ORE, ONE, ORU, OIO, LWW, LHT, LHS, LIP;
|
||||
|
||||
public MaliciousCodeScanner(boolean reflect, boolean runtime, boolean net,
|
||||
boolean io, boolean www, boolean http, boolean https, boolean ip) {
|
||||
ORE = reflect;
|
||||
ONE = net;
|
||||
ORU = runtime;
|
||||
|
@ -46,72 +38,83 @@ public class MaliciousCodeScanner extends Plugin {
|
|||
LHS = https;
|
||||
LIP = ip;
|
||||
}
|
||||
|
||||
|
||||
@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()) {
|
||||
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) {
|
||||
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);
|
||||
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;
|
||||
|
||||
|
||||
InsnList iList = m.instructions;
|
||||
for(AbstractInsnNode a : iList.toArray()) {
|
||||
if (a instanceof MethodInsnNode) {
|
||||
final MethodInsnNode min = (MethodInsnNode) a;
|
||||
if ((ORE && min.owner.startsWith("java/lang/reflect")) ||
|
||||
(ONE && min.owner.startsWith("java/net")) ||
|
||||
(ORU && min.owner.equals("java/lang/Runtime")) ||
|
||||
(OIO && min.owner.startsWith("java/io")))
|
||||
{
|
||||
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(((LdcInsnNode)a).cst instanceof String) {
|
||||
final String s = (String) ((LdcInsnNode)a).cst;
|
||||
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 method " + classNode.name + "." +m.name+"("+m.desc+")"+BytecodeViewer.nl);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (AbstractInsnNode a : iList.toArray()) {
|
||||
if (a instanceof MethodInsnNode) {
|
||||
final MethodInsnNode min = (MethodInsnNode) a;
|
||||
if ((ORE && min.owner.startsWith("java/lang/reflect"))
|
||||
|| (ONE && min.owner.startsWith("java/net"))
|
||||
|| (ORU && min.owner
|
||||
.equals("java/lang/Runtime"))
|
||||
|| (OIO && min.owner.startsWith("java/io"))) {
|
||||
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 (((LdcInsnNode) a).cst instanceof String) {
|
||||
final String s = (String) ((LdcInsnNode) a).cst;
|
||||
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 method "
|
||||
+ classNode.name + "." + m.name + "("
|
||||
+ m.desc + ")" + BytecodeViewer.nl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
frame.appendText(sb.toString());
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
|
|
@ -16,92 +16,105 @@ import the.bytecode.club.bytecodeviewer.api.Plugin;
|
|||
* Only allows one plugin to be running at once.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class PluginManager {
|
||||
|
||||
private static Plugin pluginInstance;
|
||||
|
||||
|
||||
public static void runPlugin(Plugin newPluginInstance) {
|
||||
if(pluginInstance == null || pluginInstance.isFinished()) {
|
||||
if (pluginInstance == null || pluginInstance.isFinished()) {
|
||||
pluginInstance = newPluginInstance;
|
||||
pluginInstance.start(); //start the thread
|
||||
} else if(!pluginInstance.isFinished()) {
|
||||
BytecodeViewer.showMessage("There is currently another plugin running right now, please wait for that to finish executing.");
|
||||
pluginInstance.start(); // start the thread
|
||||
} else if (!pluginInstance.isFinished()) {
|
||||
BytecodeViewer
|
||||
.showMessage("There is currently another plugin running right now, please wait for that to finish executing.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void runPlugin(File f) throws Exception {
|
||||
Plugin p = null;
|
||||
if(f.getName().endsWith(".gy") || f.getName().endsWith(".groovy")) {
|
||||
if (f.getName().endsWith(".gy") || f.getName().endsWith(".groovy")) {
|
||||
p = loadGroovyScript(f);
|
||||
}
|
||||
if(f.getName().endsWith(".py") || f.getName().endsWith(".python")) {
|
||||
if (f.getName().endsWith(".py") || f.getName().endsWith(".python")) {
|
||||
p = loadPythonScript(f);
|
||||
}
|
||||
if(f.getName().endsWith(".rb") || f.getName().endsWith(".ruby")) {
|
||||
if (f.getName().endsWith(".rb") || f.getName().endsWith(".ruby")) {
|
||||
p = loadRubyScript(f);
|
||||
}
|
||||
if(p != null) {
|
||||
if (p != null) {
|
||||
runPlugin(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a groovy file as a Script
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Plugin loadGroovyScript(File file) throws Exception {
|
||||
|
||||
/**
|
||||
* Loads a groovy file as a Script
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Plugin loadGroovyScript(File file) throws Exception {
|
||||
ScriptEngineManager manager = new ScriptEngineManager();
|
||||
ScriptEngine engine = manager.getEngineByName("groovy");
|
||||
|
||||
if(engine == null)
|
||||
throw new Exception("Cannot find Groovy script engine! Please contact Konloch.");
|
||||
|
||||
Reader reader = new FileReader(file);
|
||||
engine.eval(reader);
|
||||
|
||||
return (Plugin)engine.eval("new " + file.getName().replace(".gy", "").replace(".groovy", "") + "();");
|
||||
}
|
||||
ScriptEngine engine = manager.getEngineByName("groovy");
|
||||
|
||||
/**
|
||||
* Loads a python file as a Script
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Plugin loadPythonScript(File file) throws Exception {
|
||||
ScriptEngineManager manager = new ScriptEngineManager();
|
||||
ScriptEngine engine = manager.getEngineByName("python");
|
||||
|
||||
if(engine == null)
|
||||
throw new Exception("Cannot find Jython script engine! Please contact Konloch.");
|
||||
|
||||
Reader reader = new FileReader(file);
|
||||
engine.eval(reader);
|
||||
|
||||
return (Plugin)engine.eval(file.getName().replace(".py", "").replace(".python", "") + "()");
|
||||
}
|
||||
if (engine == null)
|
||||
throw new Exception(
|
||||
"Cannot find Groovy script engine! Please contact Konloch.");
|
||||
|
||||
/**
|
||||
* Loads a ruby file as a Script
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Plugin loadRubyScript(File file) throws Exception {
|
||||
ScriptEngineManager manager = new ScriptEngineManager();
|
||||
ScriptEngine engine = manager.getEngineByName("jruby");
|
||||
|
||||
if(engine == null)
|
||||
throw new Exception("Cannot find jRuby script engine! Please contact Konloch.");
|
||||
|
||||
Reader reader = new FileReader(file);
|
||||
engine.eval(reader);
|
||||
|
||||
return (Plugin)engine.eval(file.getName().replace(".rb", "").replace(".ruby", "") + ".new");
|
||||
}
|
||||
Reader reader = new FileReader(file);
|
||||
engine.eval(reader);
|
||||
|
||||
return (Plugin) engine.eval("new "
|
||||
+ file.getName().replace(".gy", "").replace(".groovy", "")
|
||||
+ "();");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a python file as a Script
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Plugin loadPythonScript(File file) throws Exception {
|
||||
ScriptEngineManager manager = new ScriptEngineManager();
|
||||
ScriptEngine engine = manager.getEngineByName("python");
|
||||
|
||||
if (engine == null)
|
||||
throw new Exception(
|
||||
"Cannot find Jython script engine! Please contact Konloch.");
|
||||
|
||||
Reader reader = new FileReader(file);
|
||||
engine.eval(reader);
|
||||
|
||||
return (Plugin) engine.eval(file.getName().replace(".py", "")
|
||||
.replace(".python", "")
|
||||
+ "()");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a ruby file as a Script
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Plugin loadRubyScript(File file) throws Exception {
|
||||
ScriptEngineManager manager = new ScriptEngineManager();
|
||||
ScriptEngine engine = manager.getEngineByName("jruby");
|
||||
|
||||
if (engine == null)
|
||||
throw new Exception(
|
||||
"Cannot find jRuby script engine! Please contact Konloch.");
|
||||
|
||||
Reader reader = new FileReader(file);
|
||||
engine.eval(reader);
|
||||
|
||||
return (Plugin) engine.eval(file.getName().replace(".rb", "")
|
||||
.replace(".ruby", "")
|
||||
+ ".new");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
|||
* Replaces all string and string[] instances with whatever.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class ReplaceStrings extends Plugin {
|
||||
|
@ -26,87 +26,120 @@ public class ReplaceStrings extends Plugin {
|
|||
String newLDC;
|
||||
String className;
|
||||
boolean contains;
|
||||
|
||||
public ReplaceStrings(String originalLDC, String newLDC, String className, boolean contains) {
|
||||
|
||||
public ReplaceStrings(String originalLDC, String newLDC, String className,
|
||||
boolean contains) {
|
||||
this.originalLDC = originalLDC;
|
||||
this.newLDC = newLDC;
|
||||
this.className = className;
|
||||
this.contains = contains;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(ArrayList<ClassNode> classNodeList) {
|
||||
if(!className.equals("*")) {
|
||||
for(ClassNode classNode : classNodeList) {
|
||||
if(classNode.name.equals(className))
|
||||
if (!className.equals("*")) {
|
||||
for (ClassNode classNode : classNodeList) {
|
||||
if (classNode.name.equals(className))
|
||||
scanClassNode(classNode);
|
||||
}
|
||||
} else {
|
||||
for(ClassNode classNode : classNodeList) {
|
||||
for (ClassNode classNode : classNodeList) {
|
||||
scanClassNode(classNode);
|
||||
}
|
||||
}
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
public void scanClassNode(ClassNode classNode) {
|
||||
for(Object o : classNode.fields.toArray()) {
|
||||
for (Object o : classNode.fields.toArray()) {
|
||||
FieldNode f = (FieldNode) o;
|
||||
Object v = f.value;
|
||||
if(v instanceof String) {
|
||||
String s = (String)v;
|
||||
if(contains) {
|
||||
if(s.contains(originalLDC))
|
||||
f.value = ((String)f.value).replaceAll(originalLDC, newLDC);
|
||||
if (v instanceof String) {
|
||||
String s = (String) v;
|
||||
if (contains) {
|
||||
if (s.contains(originalLDC))
|
||||
f.value = ((String) f.value).replaceAll(originalLDC,
|
||||
newLDC);
|
||||
} else {
|
||||
if(s.equals(originalLDC))
|
||||
if (s.equals(originalLDC))
|
||||
f.value = newLDC;
|
||||
}
|
||||
}
|
||||
if(v instanceof String[]) {
|
||||
for(int i = 0; i < ((String[])v).length; i++) {
|
||||
String s = ((String[])v)[i];
|
||||
if(contains) {
|
||||
if(s.contains(originalLDC)) {
|
||||
f.value = ((String[])f.value)[i].replaceAll(originalLDC, newLDC);
|
||||
String ugh = s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r");
|
||||
frame.appendText(classNode.name + "." +f.name+""+f.desc+" -> \"" + ugh + "\" replaced with \"" + s.replaceAll(originalLDC, newLDC) + "\"");
|
||||
}
|
||||
} else {
|
||||
if(s.equals(originalLDC)) {
|
||||
((String[])f.value)[i] = newLDC;
|
||||
String ugh = s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r");
|
||||
frame.appendText(classNode.name + "." +f.name+""+f.desc+" -> \"" + ugh + "\" replaced with \"" + newLDC + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (v instanceof String[]) {
|
||||
for (int i = 0; i < ((String[]) v).length; i++) {
|
||||
String s = ((String[]) v)[i];
|
||||
if (contains) {
|
||||
if (s.contains(originalLDC)) {
|
||||
f.value = ((String[]) f.value)[i].replaceAll(
|
||||
originalLDC, newLDC);
|
||||
String ugh = s.replaceAll("\\n", "\\\\n")
|
||||
.replaceAll("\\r", "\\\\r");
|
||||
frame.appendText(classNode.name + "." + f.name + ""
|
||||
+ f.desc + " -> \"" + ugh
|
||||
+ "\" replaced with \""
|
||||
+ s.replaceAll(originalLDC, newLDC) + "\"");
|
||||
}
|
||||
} else {
|
||||
if (s.equals(originalLDC)) {
|
||||
((String[]) f.value)[i] = newLDC;
|
||||
String ugh = s.replaceAll("\\n", "\\\\n")
|
||||
.replaceAll("\\r", "\\\\r");
|
||||
frame.appendText(classNode.name + "." + f.name + ""
|
||||
+ f.desc + " -> \"" + ugh
|
||||
+ "\" replaced with \"" + newLDC + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(Object o : classNode.methods.toArray()) {
|
||||
|
||||
for (Object o : classNode.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
|
||||
|
||||
InsnList iList = m.instructions;
|
||||
for(AbstractInsnNode a : iList.toArray()) {
|
||||
if (a instanceof LdcInsnNode) {
|
||||
if(((LdcInsnNode)a).cst instanceof String) {
|
||||
final String s = (String) ((LdcInsnNode)a).cst;
|
||||
if(contains) {
|
||||
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).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.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (AbstractInsnNode a : iList.toArray()) {
|
||||
if (a instanceof LdcInsnNode) {
|
||||
if (((LdcInsnNode) a).cst instanceof String) {
|
||||
final String s = (String) ((LdcInsnNode) a).cst;
|
||||
if (contains) {
|
||||
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)
|
||||
.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.replaceAll("\\n", "\\\\n")
|
||||
.replaceAll("\\r", "\\\\r")
|
||||
+ "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
|||
* Simply shows all the non-empty strings in every single class
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class ShowAllStrings extends Plugin {
|
||||
|
@ -26,40 +26,66 @@ public class ShowAllStrings extends Plugin {
|
|||
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()) {
|
||||
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(!s.isEmpty())
|
||||
sb.append(classNode.name + "." +f.name+""+f.desc+" -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""+BytecodeViewer.nl);
|
||||
if (v instanceof String) {
|
||||
String s = (String) v;
|
||||
if (!s.isEmpty())
|
||||
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())
|
||||
sb.append(classNode.name + "." +f.name+""+f.desc+"["+i+"] -> \"" + 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())
|
||||
sb.append(classNode.name
|
||||
+ "."
|
||||
+ f.name
|
||||
+ ""
|
||||
+ f.desc
|
||||
+ "["
|
||||
+ i
|
||||
+ "] -> \""
|
||||
+ s.replaceAll("\\n", "\\\\n").replaceAll(
|
||||
"\\r", "\\\\r") + "\""
|
||||
+ BytecodeViewer.nl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(Object o : classNode.methods.toArray()) {
|
||||
|
||||
for (Object o : classNode.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
|
||||
|
||||
InsnList iList = m.instructions;
|
||||
for(AbstractInsnNode a : iList.toArray()) {
|
||||
if (a instanceof LdcInsnNode) {
|
||||
if(((LdcInsnNode)a).cst instanceof String) {
|
||||
final String s = (String) ((LdcInsnNode)a).cst;
|
||||
if(!s.isEmpty())
|
||||
sb.append(classNode.name + "." +m.name+""+m.desc+" -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""+BytecodeViewer.nl);
|
||||
}
|
||||
}
|
||||
for (AbstractInsnNode a : iList.toArray()) {
|
||||
if (a instanceof LdcInsnNode) {
|
||||
if (((LdcInsnNode) a).cst instanceof String) {
|
||||
final String s = (String) ((LdcInsnNode) a).cst;
|
||||
if (!s.isEmpty())
|
||||
sb.append(classNode.name
|
||||
+ "."
|
||||
+ m.name
|
||||
+ ""
|
||||
+ m.desc
|
||||
+ " -> \""
|
||||
+ s.replaceAll("\\n", "\\\\n")
|
||||
.replaceAll("\\r", "\\\\r")
|
||||
+ "\"" + BytecodeViewer.nl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
frame.appendText(sb.toString());
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
|||
* Simply shows all classes that have a public static void main(String[])
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class ShowMainMethods extends Plugin {
|
||||
|
@ -20,12 +20,14 @@ public class ShowMainMethods extends Plugin {
|
|||
@Override
|
||||
public void execute(ArrayList<ClassNode> classNodeList) {
|
||||
PluginConsole frame = new PluginConsole("Show Main Methods");
|
||||
for(ClassNode classNode : classNodeList) {
|
||||
for(Object o : classNode.methods.toArray()) {
|
||||
for (ClassNode classNode : classNodeList) {
|
||||
for (Object o : classNode.methods.toArray()) {
|
||||
MethodNode m = (MethodNode) o;
|
||||
|
||||
if(m.name.equals("main") && m.desc.equals("([Ljava/lang/String;)V"))
|
||||
frame.appendText(classNode.name + "." +m.name+""+m.desc);
|
||||
|
||||
if (m.name.equals("main")
|
||||
&& m.desc.equals("([Ljava/lang/String;)V"))
|
||||
frame.appendText(classNode.name + "." + m.name + ""
|
||||
+ m.desc);
|
||||
}
|
||||
}
|
||||
frame.setVisible(true);
|
||||
|
|
|
@ -11,7 +11,7 @@ import the.bytecode.club.bytecodeviewer.api.Plugin;
|
|||
* Coming soon.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class ZKMStringDecrypter extends Plugin {
|
||||
|
|
|
@ -6,23 +6,23 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|||
* A simple class to make searching run in a background thread.
|
||||
*
|
||||
* @author Konloch
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class BackgroundSearchThread extends Thread {
|
||||
|
||||
public BackgroundSearchThread() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public BackgroundSearchThread(boolean finished) {
|
||||
this.finished = finished;
|
||||
}
|
||||
|
||||
|
||||
public boolean finished = false;
|
||||
|
||||
|
||||
public abstract void doSearch();
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
BytecodeViewer.viewer.setIcon(true);
|
||||
|
@ -30,5 +30,5 @@ public abstract class BackgroundSearchThread extends Thread {
|
|||
finished = true;
|
||||
BytecodeViewer.viewer.setIcon(false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -22,83 +22,99 @@ import eu.bibl.banalysis.asm.desc.OpcodeInfo;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author Water Wolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class FieldCallSearch implements SearchTypeDetails {
|
||||
|
||||
JTextField mOwner = new JTextField(""), mName = new JTextField(""), mDesc = new JTextField("");
|
||||
JPanel myPanel = null;
|
||||
|
||||
@Override
|
||||
public JPanel getPanel() {
|
||||
if (myPanel == null) {
|
||||
myPanel = new JPanel(new GridLayout(3, 2));
|
||||
myPanel.add(new JLabel("Owner: "));
|
||||
myPanel.add(mOwner);
|
||||
myPanel.add(new JLabel("Name: "));
|
||||
myPanel.add(mName);
|
||||
myPanel.add(new JLabel("Desc: "));
|
||||
myPanel.add(mDesc);
|
||||
}
|
||||
|
||||
return myPanel;
|
||||
}
|
||||
@Override
|
||||
public void search(final ClassNode node, final SearchResultNotifier srn, boolean exact) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final Iterator<MethodNode> methods = node.methods.iterator();
|
||||
String owner = mOwner.getText();
|
||||
if (owner.isEmpty()) {
|
||||
owner = null;
|
||||
}
|
||||
String name = mName.getText();
|
||||
if (name.isEmpty()) {
|
||||
name = null;
|
||||
}
|
||||
String desc = mDesc.getText();
|
||||
if (desc.isEmpty()) {
|
||||
desc = null;
|
||||
}
|
||||
while (methods.hasNext()) {
|
||||
final MethodNode method = methods.next();
|
||||
|
||||
final InsnList insnlist = method.instructions;
|
||||
@SuppressWarnings("unchecked")
|
||||
final ListIterator<AbstractInsnNode> instructions = insnlist.iterator();
|
||||
while (instructions.hasNext()) {
|
||||
final AbstractInsnNode insnNode = instructions.next();
|
||||
if (insnNode instanceof FieldInsnNode) {
|
||||
final FieldInsnNode min = (FieldInsnNode) insnNode;
|
||||
if(name == null && owner == null && desc == null)
|
||||
continue;
|
||||
if(exact) {
|
||||
if (name != null && !name.equals(min.name)) {
|
||||
continue;
|
||||
}
|
||||
if (owner != null && !owner.equals(min.owner)) {
|
||||
continue;
|
||||
}
|
||||
if (desc != null && !desc.equals(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (owner != null && !owner.contains(min.owner)) {
|
||||
continue;
|
||||
}
|
||||
if (desc != null && !desc.contains(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
srn.notifyOfResult(node.name + "." + method.name + Type.getType(method.desc) + " > " + OpcodeInfo.OPCODES.get(insnNode.getOpcode()).toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
JTextField mOwner = new JTextField(""), mName = new JTextField(""),
|
||||
mDesc = new JTextField("");
|
||||
JPanel myPanel = null;
|
||||
|
||||
@Override
|
||||
public JPanel getPanel() {
|
||||
if (myPanel == null) {
|
||||
myPanel = new JPanel(new GridLayout(3, 2));
|
||||
myPanel.add(new JLabel("Owner: "));
|
||||
myPanel.add(mOwner);
|
||||
myPanel.add(new JLabel("Name: "));
|
||||
myPanel.add(mName);
|
||||
myPanel.add(new JLabel("Desc: "));
|
||||
myPanel.add(mDesc);
|
||||
}
|
||||
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void search(final ClassNode node, final SearchResultNotifier srn,
|
||||
boolean exact) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final Iterator<MethodNode> methods = node.methods.iterator();
|
||||
String owner = mOwner.getText();
|
||||
if (owner.isEmpty()) {
|
||||
owner = null;
|
||||
}
|
||||
String name = mName.getText();
|
||||
if (name.isEmpty()) {
|
||||
name = null;
|
||||
}
|
||||
String desc = mDesc.getText();
|
||||
if (desc.isEmpty()) {
|
||||
desc = null;
|
||||
}
|
||||
while (methods.hasNext()) {
|
||||
final MethodNode method = methods.next();
|
||||
|
||||
final InsnList insnlist = method.instructions;
|
||||
@SuppressWarnings("unchecked")
|
||||
final ListIterator<AbstractInsnNode> instructions = insnlist
|
||||
.iterator();
|
||||
while (instructions.hasNext()) {
|
||||
final AbstractInsnNode insnNode = instructions.next();
|
||||
if (insnNode instanceof FieldInsnNode) {
|
||||
final FieldInsnNode min = (FieldInsnNode) insnNode;
|
||||
if (name == null && owner == null && desc == null)
|
||||
continue;
|
||||
if (exact) {
|
||||
if (name != null && !name.equals(min.name)) {
|
||||
continue;
|
||||
}
|
||||
if (owner != null && !owner.equals(min.owner)) {
|
||||
continue;
|
||||
}
|
||||
if (desc != null && !desc.equals(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (owner != null && !owner.contains(min.owner)) {
|
||||
continue;
|
||||
}
|
||||
if (desc != null && !desc.contains(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
srn.notifyOfResult(node.name
|
||||
+ "."
|
||||
+ method.name
|
||||
+ Type.getType(method.desc)
|
||||
+ " > "
|
||||
+ OpcodeInfo.OPCODES.get(insnNode.getOpcode())
|
||||
.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,57 +22,63 @@ import org.objectweb.asm.tree.MethodNode;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class LDCSearch implements SearchTypeDetails {
|
||||
|
||||
JTextField searchText = new JTextField("");
|
||||
JPanel myPanel = null;
|
||||
|
||||
@Override
|
||||
public JPanel getPanel() {
|
||||
if (myPanel == null) {
|
||||
myPanel = new JPanel(new GridLayout(1, 2));
|
||||
myPanel.add(new JLabel("Search String: "));
|
||||
myPanel.add(searchText);
|
||||
}
|
||||
|
||||
return myPanel;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void search(final ClassNode node, final SearchResultNotifier srn, boolean exact) {
|
||||
final Iterator<MethodNode> methods = node.methods.iterator();
|
||||
final String srchText = searchText.getText();
|
||||
if(srchText.isEmpty())
|
||||
return;
|
||||
while (methods.hasNext()) {
|
||||
final MethodNode method = methods.next();
|
||||
|
||||
final InsnList insnlist = method.instructions;
|
||||
final ListIterator<AbstractInsnNode> instructions = insnlist.iterator();
|
||||
while (instructions.hasNext()) {
|
||||
final AbstractInsnNode insnNode = instructions.next();
|
||||
if (insnNode instanceof LdcInsnNode) {
|
||||
final LdcInsnNode ldcObject = ((LdcInsnNode) insnNode);
|
||||
final String ldcString = ldcObject.cst.toString();
|
||||
if ((exact && ldcString.equals(srchText)) ||
|
||||
(!exact && ldcString.contains(srchText)))
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
JTextField searchText = new JTextField("");
|
||||
JPanel myPanel = null;
|
||||
|
||||
@Override
|
||||
public JPanel getPanel() {
|
||||
if (myPanel == null) {
|
||||
myPanel = new JPanel(new GridLayout(1, 2));
|
||||
myPanel.add(new JLabel("Search String: "));
|
||||
myPanel.add(searchText);
|
||||
}
|
||||
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void search(final ClassNode node, final SearchResultNotifier srn,
|
||||
boolean exact) {
|
||||
final Iterator<MethodNode> methods = node.methods.iterator();
|
||||
final String srchText = searchText.getText();
|
||||
if (srchText.isEmpty())
|
||||
return;
|
||||
while (methods.hasNext()) {
|
||||
final MethodNode method = methods.next();
|
||||
|
||||
final InsnList insnlist = method.instructions;
|
||||
final ListIterator<AbstractInsnNode> instructions = insnlist
|
||||
.iterator();
|
||||
while (instructions.hasNext()) {
|
||||
final AbstractInsnNode insnNode = instructions.next();
|
||||
if (insnNode instanceof LdcInsnNode) {
|
||||
final LdcInsnNode ldcObject = ((LdcInsnNode) insnNode);
|
||||
final String ldcString = ldcObject.cst.toString();
|
||||
if ((exact && ldcString.equals(srchText))
|
||||
|| (!exact && ldcString.contains(srchText))) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -22,83 +22,98 @@ import eu.bibl.banalysis.asm.desc.OpcodeInfo;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class MethodCallSearch implements SearchTypeDetails {
|
||||
|
||||
JTextField mOwner = new JTextField(""), mName = new JTextField(""), mDesc = new JTextField("");
|
||||
JPanel myPanel = null;
|
||||
|
||||
@Override
|
||||
public JPanel getPanel() {
|
||||
if (myPanel == null) {
|
||||
myPanel = new JPanel(new GridLayout(3, 2));
|
||||
myPanel.add(new JLabel("Owner: "));
|
||||
myPanel.add(mOwner);
|
||||
myPanel.add(new JLabel("Name: "));
|
||||
myPanel.add(mName);
|
||||
myPanel.add(new JLabel("Desc: "));
|
||||
myPanel.add(mDesc);
|
||||
}
|
||||
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void search(final ClassNode node, final SearchResultNotifier srn, boolean exact) {
|
||||
final Iterator<MethodNode> methods = node.methods.iterator();
|
||||
String owner = mOwner.getText();
|
||||
if (owner.isEmpty()) {
|
||||
owner = null;
|
||||
}
|
||||
String name = mName.getText();
|
||||
if (name.isEmpty()) {
|
||||
name = null;
|
||||
}
|
||||
String desc = mDesc.getText();
|
||||
if (desc.isEmpty()) {
|
||||
desc = null;
|
||||
}
|
||||
|
||||
while (methods.hasNext()) {
|
||||
final MethodNode method = methods.next();
|
||||
|
||||
final InsnList insnlist = method.instructions;
|
||||
final ListIterator<AbstractInsnNode> instructions = insnlist.iterator();
|
||||
while (instructions.hasNext()) {
|
||||
final AbstractInsnNode insnNode = instructions.next();
|
||||
if (insnNode instanceof MethodInsnNode) {
|
||||
final MethodInsnNode min = (MethodInsnNode) insnNode;
|
||||
if(name == null && owner == null && desc == null)
|
||||
continue;
|
||||
if(exact) {
|
||||
if (name != null && !name.equals(min.name)) {
|
||||
continue;
|
||||
}
|
||||
if (owner != null && !owner.equals(min.owner)) {
|
||||
continue;
|
||||
}
|
||||
if (desc != null && !desc.equals(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (owner != null && !owner.contains(min.owner)) {
|
||||
continue;
|
||||
}
|
||||
if (desc != null && !desc.contains(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
srn.notifyOfResult(node.name + "." + method.name + Type.getType(method.desc) + " > " + OpcodeInfo.OPCODES.get(insnNode.getOpcode()).toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
JTextField mOwner = new JTextField(""), mName = new JTextField(""),
|
||||
mDesc = new JTextField("");
|
||||
JPanel myPanel = null;
|
||||
|
||||
@Override
|
||||
public JPanel getPanel() {
|
||||
if (myPanel == null) {
|
||||
myPanel = new JPanel(new GridLayout(3, 2));
|
||||
myPanel.add(new JLabel("Owner: "));
|
||||
myPanel.add(mOwner);
|
||||
myPanel.add(new JLabel("Name: "));
|
||||
myPanel.add(mName);
|
||||
myPanel.add(new JLabel("Desc: "));
|
||||
myPanel.add(mDesc);
|
||||
}
|
||||
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void search(final ClassNode node, final SearchResultNotifier srn,
|
||||
boolean exact) {
|
||||
final Iterator<MethodNode> methods = node.methods.iterator();
|
||||
String owner = mOwner.getText();
|
||||
if (owner.isEmpty()) {
|
||||
owner = null;
|
||||
}
|
||||
String name = mName.getText();
|
||||
if (name.isEmpty()) {
|
||||
name = null;
|
||||
}
|
||||
String desc = mDesc.getText();
|
||||
if (desc.isEmpty()) {
|
||||
desc = null;
|
||||
}
|
||||
|
||||
while (methods.hasNext()) {
|
||||
final MethodNode method = methods.next();
|
||||
|
||||
final InsnList insnlist = method.instructions;
|
||||
final ListIterator<AbstractInsnNode> instructions = insnlist
|
||||
.iterator();
|
||||
while (instructions.hasNext()) {
|
||||
final AbstractInsnNode insnNode = instructions.next();
|
||||
if (insnNode instanceof MethodInsnNode) {
|
||||
final MethodInsnNode min = (MethodInsnNode) insnNode;
|
||||
if (name == null && owner == null && desc == null)
|
||||
continue;
|
||||
if (exact) {
|
||||
if (name != null && !name.equals(min.name)) {
|
||||
continue;
|
||||
}
|
||||
if (owner != null && !owner.equals(min.owner)) {
|
||||
continue;
|
||||
}
|
||||
if (desc != null && !desc.equals(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (owner != null && !owner.contains(min.owner)) {
|
||||
continue;
|
||||
}
|
||||
if (desc != null && !desc.contains(min.desc)) {
|
||||
continue;
|
||||
}
|
||||
srn.notifyOfResult(node.name
|
||||
+ "."
|
||||
+ method.name
|
||||
+ Type.getType(method.desc)
|
||||
+ " > "
|
||||
+ OpcodeInfo.OPCODES.get(insnNode.getOpcode())
|
||||
.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -86,10 +86,10 @@ public class RegexInsnFinder {
|
|||
private static String[] opcodesType = new String[] { "NEW", "ANEWARRAY",
|
||||
"ARRAYLENGTH", "CHECKCAST", "INSTANCEOF" };
|
||||
private static String opcodesTypes = buildRegexItems(opcodesType);
|
||||
|
||||
|
||||
private static String[] opcodesIf = new String[] { "IFEQ", "IFNE", "IFLT",
|
||||
"IFGE", "IFGT", "IFLE", "IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT",
|
||||
"IF_ICMPGE", "IF_ICMPGT", "IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE" };
|
||||
"IFGE", "IFGT", "IFLE", "IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT",
|
||||
"IF_ICMPGE", "IF_ICMPGT", "IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE" };
|
||||
private static String opcodesIfs = buildRegexItems(opcodesIf, false, false);
|
||||
|
||||
private static String[] opcodesAny = new String[] { "NOP", "ACONST_NULL",
|
||||
|
@ -118,15 +118,18 @@ public class RegexInsnFinder {
|
|||
"INVOKEDYNAMIC", "NEW", "NEWARRAY", "ANEWARRAY", "ARRAYLENGTH",
|
||||
"ATHROW", "CHECKCAST", "INSTANCEOF", "MONITORENTER", "MONITOREXIT",
|
||||
"MULTIANEWARRAY", "IFNULL", "IFNONNULL" };
|
||||
private static String opcodesAnys = buildRegexItems(opcodesAny, false, false);
|
||||
private static String opcodesAnys = buildRegexItems(opcodesAny, false,
|
||||
false);
|
||||
|
||||
private static String buildRegexItems(final String[] items, final boolean capture, final boolean stdRepl) {
|
||||
private static String buildRegexItems(final String[] items,
|
||||
final boolean capture, final boolean stdRepl) {
|
||||
if (items.length == 0)
|
||||
return "()";
|
||||
String result = (stdRepl ? "\\b" : "") + "(" + (capture ? "" : "?:") + items[0];
|
||||
String result = (stdRepl ? "\\b" : "") + "(" + (capture ? "" : "?:")
|
||||
+ items[0];
|
||||
for (int i = 1; i < items.length; i++) {
|
||||
result += "|" + items[i];
|
||||
}
|
||||
result += "|" + items[i];
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
@ -138,21 +141,24 @@ public class RegexInsnFinder {
|
|||
private static String processRegex(final String regex) {
|
||||
String result = regex.trim();
|
||||
result = result.replaceAll("\\bANYINSN *", opcodesAnys);
|
||||
result = result.replaceAll(opcodesInts + "\\\\\\{\\s*(\\d+)\\s*\\\\\\} *",
|
||||
"$1\\\\{$2\\\\} ");
|
||||
result = result.replaceAll(opcodesInts
|
||||
+ "\\\\\\{\\s*(\\d+)\\s*\\\\\\} *", "$1\\\\{$2\\\\} ");
|
||||
result = result.replaceAll(opcodesInts + " *", "$1\\\\{\\\\d+\\\\} ");
|
||||
result = result.replaceAll("\\bLDC\\\\\\{(.*?)\\\\\\}(?<!\\\\\\\\\\}) *",
|
||||
result = result.replaceAll(
|
||||
"\\bLDC\\\\\\{(.*?)\\\\\\}(?<!\\\\\\\\\\}) *",
|
||||
"LDC\\\\{$1\\\\}(?<!\\\\\\\\\\\\}) ");
|
||||
result = result.replaceAll("\\bLDC *", "LDC\\\\{.*?\\\\}(?<!\\\\\\\\\\\\}) ");
|
||||
result = result.replaceAll("\\bLDC *",
|
||||
"LDC\\\\{.*?\\\\}(?<!\\\\\\\\\\\\}) ");
|
||||
result = result.replaceAll(opcodeVars + "(_\\d+) *", "$1$2 ");
|
||||
result = result.replaceAll(opcodeVars + "(?!_) *", "$1_\\\\d+ ");
|
||||
result = result.replaceAll("\\bIINC\\\\\\{\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\\\\\} *",
|
||||
result = result.replaceAll(
|
||||
"\\bIINC\\\\\\{\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\\\\\} *",
|
||||
"IINC\\\\{$1,$2\\\\} ");
|
||||
result = result.replaceAll("\\bIINC\\\\\\{\\s*(\\d+)\\s*\\\\\\} *",
|
||||
"IINC\\\\{\\d+,$1\\\\} ");
|
||||
result = result.replaceAll("\\bIINC *", "IINC\\\\{\\d+,\\d+\\\\} ");
|
||||
result = result.replaceAll(opcodesFields +
|
||||
"\\\\\\{\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*\\\\\\} *",
|
||||
result = result.replaceAll(opcodesFields
|
||||
+ "\\\\\\{\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*\\\\\\} *",
|
||||
"$1\\\\{$2,$3,$4\\\\} ");
|
||||
result = result.replaceAll(opcodesFields
|
||||
+ "\\\\\\{((?:.(?!,))*)\\\\\\} *", "$1\\\\{$2,.*?,.*?\\\\} ");
|
||||
|
@ -164,14 +170,18 @@ public class RegexInsnFinder {
|
|||
+ "\\\\\\{((?:.(?!,))*)\\\\\\} *", "$1\\\\{$2,.*?,.*?\\\\} ");
|
||||
result = result.replaceAll(opcodesMethods + " *",
|
||||
"$1\\\\{.*?,.*?,.*?\\\\} ");
|
||||
result = result.replaceAll(opcodesTypes + "\\\\\\{\\s*(.*?)\\s*\\\\\\} +",
|
||||
"$1\\\\{$2\\\\} ");
|
||||
result = result.replaceAll(opcodesTypes
|
||||
+ "\\\\\\{\\s*(.*?)\\s*\\\\\\} +", "$1\\\\{$2\\\\} ");
|
||||
result = result.replaceAll(opcodesTypes + " +", "$1\\\\{\\\\.*?\\\\} ");
|
||||
result = result.replaceAll("\\bMULTIANEWARRAY\\\\\\{\\s*(\\d+)\\s*,\\s*(.*?)\\s*\\\\\\} *",
|
||||
"MULTIANEWARRAY\\\\{$1,$2\\\\} ");
|
||||
result = result.replaceAll("\\bMULTIANEWARRAY\\\\\\{\\s*(.*?)\\s*\\\\\\} *",
|
||||
result = result
|
||||
.replaceAll(
|
||||
"\\bMULTIANEWARRAY\\\\\\{\\s*(\\d+)\\s*,\\s*(.*?)\\s*\\\\\\} *",
|
||||
"MULTIANEWARRAY\\\\{$1,$2\\\\} ");
|
||||
result = result.replaceAll(
|
||||
"\\bMULTIANEWARRAY\\\\\\{\\s*(.*?)\\s*\\\\\\} *",
|
||||
"MULTIANEWARRAY\\\\{\\d+,$1\\\\} ");
|
||||
result = result.replaceAll("\\bMULTIANEWARRAY *", "MULTIANEWARRAY\\\\{\\\\\\d+,.*?\\\\} ");
|
||||
result = result.replaceAll("\\bMULTIANEWARRAY *",
|
||||
"MULTIANEWARRAY\\\\{\\\\\\d+,.*?\\\\} ");
|
||||
result = result.replaceAll("\\bIFINSN *", opcodesIfs + " ");
|
||||
return result;
|
||||
}
|
||||
|
@ -182,34 +192,35 @@ public class RegexInsnFinder {
|
|||
private int[] offsets;
|
||||
private String insnString;
|
||||
|
||||
public RegexInsnFinder (final ClassNode clazz, final MethodNode method) {
|
||||
public RegexInsnFinder(final ClassNode clazz, final MethodNode method) {
|
||||
setMethod(clazz, method);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings("unchecked")
|
||||
private AbstractInsnNode[] cleanInsn(final InsnList insnList) {
|
||||
final List<AbstractInsnNode> il = new ArrayList<AbstractInsnNode>();
|
||||
|
||||
final Iterator<AbstractInsnNode> iIt = insnList.iterator();
|
||||
while (iIt.hasNext()) {
|
||||
final AbstractInsnNode node = iIt.next();
|
||||
if (node.getOpcode() >= 0) {
|
||||
il.add(node);
|
||||
}
|
||||
final List<AbstractInsnNode> il = new ArrayList<AbstractInsnNode>();
|
||||
|
||||
final Iterator<AbstractInsnNode> iIt = insnList.iterator();
|
||||
while (iIt.hasNext()) {
|
||||
final AbstractInsnNode node = iIt.next();
|
||||
if (node.getOpcode() >= 0) {
|
||||
il.add(node);
|
||||
}
|
||||
return il.toArray(new AbstractInsnNode[il.size()]);
|
||||
}
|
||||
return il.toArray(new AbstractInsnNode[il.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the internal instruction list when you have made changes to the method.
|
||||
* Refreshes the internal instruction list when you have made changes to the
|
||||
* method.
|
||||
*/
|
||||
public void refresh() {
|
||||
origInstructions = cleanInsn(mn.instructions);
|
||||
final List<AbstractInsnNode> il = new ArrayList<AbstractInsnNode>();
|
||||
for (final AbstractInsnNode ain : mn.instructions.toArray())
|
||||
if (ain.getOpcode() >= 0) {
|
||||
il.add(ain);
|
||||
}
|
||||
il.add(ain);
|
||||
}
|
||||
instructions = il.toArray(new AbstractInsnNode[il.size()]);
|
||||
offsets = new int[instructions.length];
|
||||
insnString = "";
|
||||
|
@ -218,14 +229,14 @@ public class RegexInsnFinder {
|
|||
final AbstractInsnNode ain = instructions[i];
|
||||
if (ain.getOpcode() >= 0) {
|
||||
if (ain.getOpcode() >= opcodes.length) {
|
||||
try {
|
||||
try {
|
||||
throw new UnexpectedException(
|
||||
"Unknown opcode encountered: "
|
||||
+ ain.getOpcode());
|
||||
} catch (final UnexpectedException e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
offsets[i] = insnString.length();
|
||||
insnString += opcodes[ain.getOpcode()];
|
||||
switch (ain.getType()) {
|
||||
|
@ -271,26 +282,26 @@ public class RegexInsnFinder {
|
|||
}
|
||||
|
||||
public void setMethod(final ClassNode ci, final MethodNode mi) {
|
||||
this.mn = mi;
|
||||
this.mn = mi;
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
||||
private AbstractInsnNode[] makeResult(final int start, final int end) {
|
||||
int startIndex = 0;
|
||||
int endIndex = -1;
|
||||
for (int i = 0; i < offsets.length - 1; i++) {
|
||||
final int offset = offsets[i];
|
||||
if (offset == start) {
|
||||
startIndex = i;
|
||||
}
|
||||
startIndex = i;
|
||||
}
|
||||
if ((offset < end) && (offsets[i + 1] >= end)) {
|
||||
endIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (endIndex == -1) {
|
||||
endIndex = offsets.length - 1;
|
||||
}
|
||||
endIndex = offsets.length - 1;
|
||||
}
|
||||
final int length = endIndex - startIndex + 1;
|
||||
final AbstractInsnNode[] result = new AbstractInsnNode[length];
|
||||
System.arraycopy(origInstructions, startIndex, result, 0, length);
|
||||
|
@ -299,7 +310,9 @@ public class RegexInsnFinder {
|
|||
|
||||
/**
|
||||
* Searches for a regex in the instruction list and returns the first match.
|
||||
* @param regex the regular expression
|
||||
*
|
||||
* @param regex
|
||||
* the regular expression
|
||||
* @return the matching instructions
|
||||
*/
|
||||
public AbstractInsnNode[] find(final String regex) {
|
||||
|
@ -313,10 +326,12 @@ public class RegexInsnFinder {
|
|||
}
|
||||
return new AbstractInsnNode[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searches a regex in an instruction list and returns all matches.
|
||||
* @param regex the regular expression
|
||||
*
|
||||
* @param regex
|
||||
* the regular expression
|
||||
* @return a list with all sets of matching instructions
|
||||
*/
|
||||
public List<AbstractInsnNode[]> findAll(final String regex) {
|
||||
|
@ -325,8 +340,8 @@ public class RegexInsnFinder {
|
|||
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
|
||||
Pattern.MULTILINE).matcher(insnString);
|
||||
while (regexMatcher.find()) {
|
||||
results.add(makeResult(regexMatcher.start(), regexMatcher.end()));
|
||||
}
|
||||
results.add(makeResult(regexMatcher.start(), regexMatcher.end()));
|
||||
}
|
||||
} catch (final PatternSyntaxException ex) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex);
|
||||
}
|
||||
|
@ -334,8 +349,11 @@ public class RegexInsnFinder {
|
|||
}
|
||||
|
||||
/**
|
||||
* Searches for a regex in the instruction list and returns all groups for the first match.
|
||||
* @param regex the regular expression
|
||||
* Searches for a regex in the instruction list and returns all groups for
|
||||
* the first match.
|
||||
*
|
||||
* @param regex
|
||||
* the regular expression
|
||||
* @return the groups with matching instructions
|
||||
*/
|
||||
public AbstractInsnNode[][] findGroups(final String regex) {
|
||||
|
@ -343,10 +361,12 @@ public class RegexInsnFinder {
|
|||
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
|
||||
Pattern.MULTILINE).matcher(insnString);
|
||||
if (regexMatcher.find()) {
|
||||
final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher.groupCount() + 1][0];
|
||||
final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher
|
||||
.groupCount() + 1][0];
|
||||
for (int i = 0; i <= regexMatcher.groupCount(); i++) {
|
||||
result[i] = makeResult(regexMatcher.start(i), regexMatcher.end(i));
|
||||
}
|
||||
result[i] = makeResult(regexMatcher.start(i),
|
||||
regexMatcher.end(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} catch (final PatternSyntaxException ex) {
|
||||
|
@ -356,8 +376,11 @@ public class RegexInsnFinder {
|
|||
}
|
||||
|
||||
/**
|
||||
* Searches for a regex in the instruction list and returns all groups for all matches.
|
||||
* @param regex the regular expression
|
||||
* Searches for a regex in the instruction list and returns all groups for
|
||||
* all matches.
|
||||
*
|
||||
* @param regex
|
||||
* the regular expression
|
||||
* @return a list with all sets of groups with matching instructions
|
||||
*/
|
||||
public List<AbstractInsnNode[][]> findAllGroups(final String regex) {
|
||||
|
@ -366,10 +389,12 @@ public class RegexInsnFinder {
|
|||
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
|
||||
Pattern.MULTILINE).matcher(insnString);
|
||||
if (regexMatcher.find()) {
|
||||
final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher.groupCount() + 1][0];
|
||||
final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher
|
||||
.groupCount() + 1][0];
|
||||
for (int i = 0; i <= regexMatcher.groupCount(); i++) {
|
||||
result[i] = makeResult(regexMatcher.start(i), regexMatcher.end(i));
|
||||
}
|
||||
result[i] = makeResult(regexMatcher.start(i),
|
||||
regexMatcher.end(i));
|
||||
}
|
||||
results.add(result);
|
||||
}
|
||||
} catch (final PatternSyntaxException ex) {
|
||||
|
|
|
@ -15,48 +15,48 @@ import org.objectweb.asm.tree.MethodNode;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class RegexSearch implements SearchTypeDetails {
|
||||
|
||||
JTextField searchText = new JTextField("");
|
||||
JPanel myPanel = null;
|
||||
|
||||
private static RegexInsnFinder regexFinder;
|
||||
|
||||
@Override
|
||||
public JPanel getPanel() {
|
||||
if (myPanel == null) {
|
||||
myPanel = new JPanel(new GridLayout(1, 2));
|
||||
myPanel.add(new JLabel("Search Regex: "));
|
||||
myPanel.add(searchText);
|
||||
}
|
||||
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void search(final ClassNode node, final SearchResultNotifier srn, boolean exact) {
|
||||
final Iterator<MethodNode> methods = node.methods.iterator();
|
||||
final String srchText = searchText.getText();
|
||||
if(srchText.isEmpty())
|
||||
return;
|
||||
while (methods.hasNext()) {
|
||||
final MethodNode method = methods.next();
|
||||
|
||||
if (regexFinder == null) {
|
||||
regexFinder = new RegexInsnFinder(node, method);
|
||||
}
|
||||
else {
|
||||
regexFinder.setMethod(node, method);
|
||||
}
|
||||
|
||||
if (regexFinder.find(srchText).length > 0) {
|
||||
srn.notifyOfResult(node.name + "." + method.name + method.desc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
JTextField searchText = new JTextField("");
|
||||
JPanel myPanel = null;
|
||||
|
||||
private static RegexInsnFinder regexFinder;
|
||||
|
||||
@Override
|
||||
public JPanel getPanel() {
|
||||
if (myPanel == null) {
|
||||
myPanel = new JPanel(new GridLayout(1, 2));
|
||||
myPanel.add(new JLabel("Search Regex: "));
|
||||
myPanel.add(searchText);
|
||||
}
|
||||
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void search(final ClassNode node, final SearchResultNotifier srn,
|
||||
boolean exact) {
|
||||
final Iterator<MethodNode> methods = node.methods.iterator();
|
||||
final String srchText = searchText.getText();
|
||||
if (srchText.isEmpty())
|
||||
return;
|
||||
while (methods.hasNext()) {
|
||||
final MethodNode method = methods.next();
|
||||
|
||||
if (regexFinder == null) {
|
||||
regexFinder = new RegexInsnFinder(node, method);
|
||||
} else {
|
||||
regexFinder.setMethod(node, method);
|
||||
}
|
||||
|
||||
if (regexFinder.find(srchText).length > 0) {
|
||||
srn.notifyOfResult(node.name + "." + method.name + method.desc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,9 +5,9 @@ package the.bytecode.club.bytecodeviewer.searching;
|
|||
*
|
||||
* @author Konloch
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public interface SearchResultNotifier {
|
||||
public void notifyOfResult(String debug);
|
||||
public void notifyOfResult(String debug);
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
* Search type details
|
||||
*
|
||||
* @author WaterWolf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public interface SearchTypeDetails {
|
||||
public JPanel getPanel();
|
||||
public JPanel getPanel();
|
||||
|
||||
public void search(ClassNode node, SearchResultNotifier srn, boolean exact);
|
||||
public void search(ClassNode node, SearchResultNotifier srn, boolean exact);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user