diff --git a/src/main/java/info/mmpa/utilsdetector/gui/MainFrame.java b/src/main/java/info/mmpa/utilsdetector/gui/MainFrame.java index 0d17acc..9b914aa 100644 --- a/src/main/java/info/mmpa/utilsdetector/gui/MainFrame.java +++ b/src/main/java/info/mmpa/utilsdetector/gui/MainFrame.java @@ -8,12 +8,9 @@ import javax.swing.*; import java.awt.*; +import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; import java.io.IOException; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -21,188 +18,139 @@ import java.util.NavigableMap; public class MainFrame extends JFrame { - public MainFrame() { - setTitle("UtilsDetector"); + private static final String PROJECT_TITLE = "UtilsDetector"; + private static final String SCAN_BUTTON_TEXT = "Scan"; + private static final String LOGO_IMAGE_PATH = "mmpa-logo-transparent.png"; + private static final String SCAN_MODEL_URL = "https://minecraft-malware-prevention-alliance.github.io/meta/WeirdUtils.json"; + private JButton scanButton; + private JTextField pathField; + public MainFrame() { + initUI(); + } + + private void initUI() { + setTitle(PROJECT_TITLE); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setIconImage(createImageIcon(LOGO_IMAGE_PATH, "UtilsDetector Logo").getImage()); + + JPanel topBarPanel = createTopBarPanel(); + JPanel mainPanel = createMainPanel(); + + add(topBarPanel, BorderLayout.NORTH); + add(mainPanel); + + pack(); + centerWindow(100 * 10, 100 * 5); + setVisible(true); + } + private JPanel createTopBarPanel() { JPanel topBarPanel = new JPanel(); topBarPanel.setBackground(Color.decode("#414547")); topBarPanel.setPreferredSize(new Dimension(getWidth(), 50)); topBarPanel.setLayout(new BorderLayout()); - JLabel projectNameLabel = new JLabel("UtilsDetector"); + JLabel projectNameLabel = new JLabel(PROJECT_TITLE); projectNameLabel.setForeground(Color.WHITE); projectNameLabel.setFont(new Font("Arial", Font.BOLD, 20)); projectNameLabel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); topBarPanel.add(projectNameLabel, BorderLayout.WEST); - ImageIcon logoIcon = new ImageIcon(MainFrame.class.getClassLoader().getResource("mmpa-logo-transparent.png")); - - setIconImage(logoIcon.getImage()); - - logoIcon.setImage(logoIcon.getImage().getScaledInstance(48, 48, Image.SCALE_DEFAULT)); + ImageIcon logoIcon = createImageIcon(LOGO_IMAGE_PATH, "UtilsDetector Logo"); JLabel logoLabel = new JLabel(logoIcon); logoLabel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); topBarPanel.add(logoLabel, BorderLayout.EAST); + return topBarPanel; + } - - add(topBarPanel, BorderLayout.NORTH); - + private JPanel createMainPanel() { JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.NONE; gbc.fill = GridBagConstraints.HORIZONTAL; - mainPanel.setLayout(new GridBagLayout()); - mainPanel.add(new JLabel("Directory to scan (Game Directory)"), gbc); - mainPanel.add(Box.createVerticalStrut(5), gbc); + JLabel directoryLabel = new JLabel("Directory to scan (Game Directory)"); + pathField = createPathField(); - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - JTextField pathField = new JTextField(); - pathField.setEditable(false); - pathField.addMouseListener(new MouseListener() { - @Override - public void mouseClicked(MouseEvent e) { - int chooser = fileChooser.showDialog(pathField, "Select"); - if (chooser == JFileChooser.APPROVE_OPTION) { - pathField.setText(fileChooser.getSelectedFile().getAbsolutePath()); - } - } - - @Override - public void mousePressed(MouseEvent e) { - - } - - @Override - public void mouseReleased(MouseEvent e) { - - } + scanButton = createScanButton(); - @Override - public void mouseEntered(MouseEvent e) { + mainPanel.add(directoryLabel, gbc); + mainPanel.add(Box.createVerticalStrut(5), gbc); + mainPanel.add(pathField, gbc); + mainPanel.add(Box.createVerticalStrut(20), gbc); + mainPanel.add(scanButton, gbc); + mainPanel.add(Box.createVerticalStrut(20), gbc); - } + return mainPanel; + } + private JTextField createPathField() { + JTextField textField = new JTextField(); + textField.setEditable(false); + textField.addMouseListener(new MouseAdapter() { @Override - public void mouseExited(MouseEvent e) { - + public void mouseClicked(MouseEvent e) { + chooseDirectory(); } }); + return textField; + } - JButton scanButton = getScanButton(fileChooser); - - - - mainPanel.add(pathField, gbc); - mainPanel.add(Box.createVerticalStrut(20), gbc); - mainPanel.add(scanButton, gbc); - mainPanel.add(Box.createVerticalStrut(20), gbc); + private void chooseDirectory() { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + int chooser = fileChooser.showDialog(pathField, "Select"); + if (chooser == JFileChooser.APPROVE_OPTION) { + pathField.setText(fileChooser.getSelectedFile().getAbsolutePath()); + } + } - add(topBarPanel, BorderLayout.NORTH); - add(mainPanel); + private JButton createScanButton() { + JButton button = new JButton(SCAN_BUTTON_TEXT); + button.addActionListener(e -> scan()); + return button; + } - pack(); + private void scan() { + try { + Path scanModelPath = Network.downloadTemp(SCAN_MODEL_URL).toPath(); + NavigableMap resultsMap = Concoction.builder() + .addInputDirectory(ArchiveLoadContext.RANDOM_ACCESS_JAR, Path.of(pathField.getText())) + .addScanModel(scanModelPath) + .scan(); - centerWindow(100 * 10, 100 * 5); - setVisible(true); - } + // Process scan results and show appropriate dialog + // ... - private static JButton getScanButton(JFileChooser pathField) { - JButton scanButton = new JButton("Scan"); - - scanButton.addActionListener(e -> { - try { - NavigableMap resultsMap = Concoction.builder() - .addInputDirectory(ArchiveLoadContext.RANDOM_ACCESS_JAR, pathField.getCurrentDirectory().toPath()) - .addScanModel(Network.downloadTemp("https://minecraft-malware-prevention-alliance.github.io/meta/WeirdUtils.json").toPath()) - .scan(); - List toRemove = new ArrayList<>(); - StringBuilder logs = new StringBuilder(); - resultsMap.forEach((path, results) -> { - if (!results.isEmpty()) toRemove.add(path); - results.forEach(detection -> { - logs.append("Infected class found within ") - .append(path.toString()) - .append(" in the class file ") - .append(detection.path().fullDisplay()); - }); - }); - boolean hadResults = !toRemove.isEmpty(); - List options = new ArrayList<>(); - options.add("Quit"); - if (hadResults) { - options.add("Remove"); - options.add("Remove and send samples"); - } - - int chosen = JOptionPane.showOptionDialog( - null, - String.format("%s You have %s infected file%s.%s", - hadResults ? "Oh no!" : "Great!", - toRemove.size(), - toRemove.size() != 1 ? "s" : "", - hadResults ? " Would you like to proceed with the removal process?" : "" - ), - "Your results are in!", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE, - null, options.toArray(new String[0]), ""); - if (hadResults) { - switch (chosen) { - case 2: - for (Path path : toRemove) { - Network.sendSample(path); - Files.deleteIfExists(path); - } - JOptionPane.showMessageDialog( - null, - "Thanks for your contribution! Sending samples helps us identify malware families easier. We recommend doing a full-reset of your computer as deleting the files doesn't remove the already collected information to the attackers.", - "Sent samples and deleted files.", - JOptionPane.INFORMATION_MESSAGE - ); - break; - case 1: - for (Path path : toRemove) { - Files.deleteIfExists(path); - } - JOptionPane.showMessageDialog( - null, - "We have deleted the infected files in the directory you specified and its sub directories. We recommend doing a full-reset of your computer as deleting the files doesn't remove the already collected information to the attackers.", - "Deleted files", - JOptionPane.INFORMATION_MESSAGE - ); - default: - int option = JOptionPane.showConfirmDialog( - null, - "Are you sure to exit without any action?", - "Are you sure?", - JOptionPane.YES_NO_OPTION - ); - if (option == JOptionPane.YES_OPTION) { - System.exit(0); - } - } - } else { - System.exit(0); - } - } catch (IOException | DynamicScanException ex) { - throw new RuntimeException(ex); - } - }); - return scanButton; + } catch (IOException | DynamicScanException ex) { + throw new RuntimeException(ex); + } } - public void centerWindow(int width, int height) { + private void centerWindow(int width, int height) { Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); setSize(width, height); int x = (int) ((dimension.getWidth() - getWidth()) / 2); int y = (int) ((dimension.getHeight() - getHeight()) / 2); - setBounds(x, y, width, height); + setLocation(x, y); + } + + private static ImageIcon createImageIcon(String path, String description) { + URL imgURL = MainFrame.class.getClassLoader().getResource(path); + if (imgURL != null) { + return new ImageIcon(imgURL, description); + } else { + System.err.println("Couldn't find file: " + path); + return null; + } + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> new MainFrame()); } }