diff --git a/gui/src/main/java/me/nov/threadtear/graph/CFGraph.java b/gui/src/main/java/me/nov/threadtear/graph/CFGraph.java
index 0203655..3e1ce4e 100644
--- a/gui/src/main/java/me/nov/threadtear/graph/CFGraph.java
+++ b/gui/src/main/java/me/nov/threadtear/graph/CFGraph.java
@@ -1,16 +1,19 @@
package me.nov.threadtear.graph;
-import java.awt.*;
-import java.util.Map;
-
-import javax.swing.*;
-import javax.swing.border.EmptyBorder;
-
import com.mxgraph.canvas.mxGraphics2DCanvas;
import com.mxgraph.shape.mxRectangleShape;
import com.mxgraph.swing.mxGraphComponent;
-import com.mxgraph.util.*;
-import com.mxgraph.view.*;
+import com.mxgraph.util.mxConstants;
+import com.mxgraph.util.mxRectangle;
+import com.mxgraph.view.mxCellState;
+import com.mxgraph.view.mxGraph;
+import com.mxgraph.view.mxGraphView;
+import com.mxgraph.view.mxStylesheet;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+import java.util.Map;
public class CFGraph extends mxGraph {
private final CFGComponent component;
@@ -91,7 +94,7 @@ public CFGComponent(mxGraph g) {
} else if (scp != null) {
// do we need this on linux too?
scp.getVerticalScrollBar().setValue(scp.getVerticalScrollBar().getValue() +
- e.getUnitsToScroll() * scp.getVerticalScrollBar().getUnitIncrement());
+ e.getUnitsToScroll() * scp.getVerticalScrollBar().getUnitIncrement());
}
});
}
diff --git a/gui/src/main/java/me/nov/threadtear/swing/panel/ConfigurationPanel.java b/gui/src/main/java/me/nov/threadtear/swing/panel/ConfigurationPanel.java
index aa72185..346899c 100644
--- a/gui/src/main/java/me/nov/threadtear/swing/panel/ConfigurationPanel.java
+++ b/gui/src/main/java/me/nov/threadtear/swing/panel/ConfigurationPanel.java
@@ -1,34 +1,35 @@
package me.nov.threadtear.swing.panel;
-import java.awt.*;
-import java.io.File;
-import java.util.ArrayList;
-
-import javax.swing.*;
-import javax.swing.filechooser.FileNameExtensionFilter;
-
import me.nov.threadtear.CoreUtils;
+import me.nov.threadtear.Threadtear;
+import me.nov.threadtear.execution.Execution;
+import me.nov.threadtear.io.JarIO;
import me.nov.threadtear.logging.LogWrapper;
-import org.apache.commons.configuration2.*;
+import me.nov.threadtear.swing.SwingUtils;
+import me.nov.threadtear.swing.tree.component.ClassTreeNode;
+import me.nov.threadtear.swing.tree.component.ExecutionTreeNode;
+import org.apache.commons.configuration2.Configuration;
+import org.apache.commons.configuration2.FileBasedConfiguration;
+import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.fluent.Parameters;
import org.apache.commons.io.FilenameUtils;
-import me.nov.threadtear.Threadtear;
-import me.nov.threadtear.execution.Execution;
-import me.nov.threadtear.io.JarIO;
-import me.nov.threadtear.swing.SwingUtils;
-import me.nov.threadtear.swing.tree.component.*;
+import javax.swing.*;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import java.awt.*;
+import java.io.File;
+import java.util.ArrayList;
public class ConfigurationPanel extends JPanel {
private static final long serialVersionUID = 1L;
+ public JButton run;
+ public JButton save;
private Threadtear main;
private JCheckBox verbose;
private JCheckBox watermark;
private JCheckBox disableSecurity;
private JCheckBox removeSignature;
- public JButton run;
- public JButton save;
public ConfigurationPanel(Threadtear main) {
this.main = main;
@@ -40,28 +41,28 @@ public ConfigurationPanel(Threadtear main) {
private JPanel createCheckboxes() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setAlignmentY(Component.BOTTOM_ALIGNMENT);
- panel.add(verbose = new JCheckBox("Verbose logging"), SwingUtils.createGridBagConstraints(0,0));
+ panel.add(verbose = new JCheckBox("Verbose logging"), SwingUtils.createGridBagConstraints(0, 0));
verbose.setToolTipText("Log more information and print full stack traces.");
panel.add(watermark = new JCheckBox("Watermark MANIFEST.MF"),
- SwingUtils.createGridBagConstraints(1,0));
+ SwingUtils.createGridBagConstraints(1, 0));
watermark.setToolTipText("Adds a \"Deobfuscated-By\" attribute to the manifest file.");
watermark.setSelected(true);
panel.add(disableSecurity = new JCheckBox("Disable SecurityManager protection"),
- SwingUtils.createGridBagConstraints(0,1));
+ SwingUtils.createGridBagConstraints(0, 1));
disableSecurity
- .setToolTipText("Remove the protection against unwanted calls. Could improve deobfuscation.");
+ .setToolTipText("Remove the protection against unwanted calls. Could improve deobfuscation.");
disableSecurity.addActionListener(l -> {
if (disableSecurity.isSelected()) {
if (JOptionPane.showConfirmDialog(this.getParent(),
- "You are disabling the SecurityManager that protects " +
- "you
from arbitrary code execution. Are you sure?", "Warning",
- JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
+ "You are disabling the SecurityManager that protects " +
+ "you
from arbitrary code execution. Are you sure?", "Warning",
+ JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
disableSecurity.setSelected(false);
}
}
});
panel.add(removeSignature = new JCheckBox("Remove manifest signature"),
- SwingUtils.createGridBagConstraints(1,1));
+ SwingUtils.createGridBagConstraints(1, 1));
removeSignature.setToolTipText("Remove the signature from the manifest file, if available.");
return panel;
}
@@ -108,6 +109,20 @@ private JPanel createBottomButtons() {
JOptionPane.showMessageDialog(this, "You have to load a jar file first.");
return;
}
+ if (main.listPanel.executionList.getExecutions().size() > 0) {
+ JTextArea ta = new JTextArea();
+ ta.setText("This project is entirely open-source and many hours have went into developing it.\n" +
+ "Please consider donating a small amount, if you are happy with your deobfuscation results.\n" +
+ "Every paid coffee will result in motivation to develop this tool, as it lives of it.\n" +
+ "You can also contact me on twitter (@graxcoding) for more options.\n" +
+ "Thank you.\n\n" +
+ "Bitcoin adress: 3LfBXghKn8KAj74tyetaUdJLic4NpGY3Vr");
+ ta.setCaretPosition(0);
+ ta.setEditable(false);
+ JOptionPane.showMessageDialog(this,
+ ta, "Consider donating",
+ JOptionPane.INFORMATION_MESSAGE, SwingUtils.getIcon("bit_qr.png", 150, 150));
+ }
JFileChooser jfc = new JFileChooser(inputFile.getParentFile());
jfc.setAcceptAllFileFilterUsed(false);
jfc.setSelectedFile(new File(FilenameUtils.removeExtension(inputFile.getAbsolutePath()) + ".jar"));
@@ -117,7 +132,7 @@ private JPanel createBottomButtons() {
if (result == JFileChooser.APPROVE_OPTION) {
File output = jfc.getSelectedFile();
JarIO.saveAsJar(inputFile, output, main.listPanel.classList.classes, removeSignature.isSelected(),
- watermark.isSelected());
+ watermark.isSelected());
LogWrapper.logger.info("Saved to " + output.getAbsolutePath());
}
save.setEnabled(true);
@@ -129,9 +144,9 @@ private JPanel createBottomButtons() {
run.setEnabled(false);
if (!CoreUtils.isNoverify()) {
JOptionPane.showMessageDialog(main,
- "You started without \"-noverify\". Some deobfuscators could fail" +
- ".
Use \"java -noverify -jar ...\" to start the application.", "Warning",
- JOptionPane.WARNING_MESSAGE);
+ "You started without \"-noverify\". Some deobfuscators could fail" +
+ ".
Use \"java -noverify -jar ...\" to start the application.", "Warning",
+ JOptionPane.WARNING_MESSAGE);
}
main.run(verbose.isSelected(), disableSecurity.isSelected());
});
@@ -143,8 +158,8 @@ private void saveConfig(File output) {
try {
output.createNewFile();
FileBasedConfigurationBuilder builder =
- new FileBasedConfigurationBuilder(PropertiesConfiguration.class)
- .configure(new Parameters().fileBased().setFile(output));
+ new FileBasedConfigurationBuilder(PropertiesConfiguration.class)
+ .configure(new Parameters().fileBased().setFile(output));
FileBasedConfiguration config = builder.getConfiguration();
config.setProperty("verbose", verbose.isSelected());
config.setProperty("no_sec", disableSecurity.isSelected());
@@ -154,8 +169,8 @@ private void saveConfig(File output) {
if (input != null) {
config.setProperty("file", input.getAbsolutePath());
config.setProperty("ignored",
- main.listPanel.classList.classes.stream().filter(c -> !c.transform).map(c -> c.node.name)
- .toArray(String[]::new));
+ main.listPanel.classList.classes.stream().filter(c -> !c.transform).map(c -> c.node.name)
+ .toArray(String[]::new));
}
ArrayList executions = main.listPanel.executionList.getExecutions();
if (!executions.isEmpty()) {
@@ -170,8 +185,8 @@ private void saveConfig(File output) {
private void loadConfig(File input) {
try {
FileBasedConfigurationBuilder builder =
- new FileBasedConfigurationBuilder(PropertiesConfiguration.class)
- .configure(new Parameters().fileBased().setFile(input));
+ new FileBasedConfigurationBuilder(PropertiesConfiguration.class)
+ .configure(new Parameters().fileBased().setFile(input));
Configuration config = builder.getConfiguration();
verbose.setSelected(config.getBoolean("verbose"));
watermark.setSelected(true);
@@ -205,7 +220,7 @@ private void loadConfig(File input) {
main.listPanel.executionList.repaint();
} catch (Exception e) {
JOptionPane.showMessageDialog(this,
- "Execution failed to initialize: " + execution + " (" + e.toString() + ")");
+ "Execution failed to initialize: " + execution + " (" + e.toString() + ")");
}
}
}
diff --git a/gui/src/main/resources/me/nov/threadtear/bit_qr.png b/gui/src/main/resources/me/nov/threadtear/bit_qr.png
new file mode 100644
index 0000000..edad7ac
Binary files /dev/null and b/gui/src/main/resources/me/nov/threadtear/bit_qr.png differ