From b38c65b254613fd851d2173f582f87ea381a36d8 Mon Sep 17 00:00:00 2001 From: ReaJason Date: Thu, 26 Feb 2026 22:24:41 +0800 Subject: [PATCH] feat: java swing gui --- desktop/java-swing-gui/build.gradle.kts | 33 ++ .../memshell/MemShellDesktopApplication.java | 13 + .../controller/MemShellFormController.java | 331 ++++++++++++++++++ .../model/DesktopMemShellGenerateResult.java | 25 ++ .../memshell/model/MemShellFormState.java | 145 ++++++++ .../memshell/model/PackerCategoryModel.java | 15 + .../memshell/model/PackerEntryModel.java | 30 ++ .../model/PackerSchemaFieldModel.java | 43 +++ .../service/ConfigCatalogService.java | 127 +++++++ .../service/CustomClassNameParser.java | 22 ++ .../memshell/service/GenerationService.java | 147 ++++++++ .../memshell/ui/MemShellGeneratorFrame.java | 138 ++++++++ .../memshell/ui/panel/MainConfigPanel.java | 169 +++++++++ .../memshell/ui/panel/PackageConfigPanel.java | 131 +++++++ .../memshell/ui/panel/ResultPanel.java | 249 +++++++++++++ .../ui/panel/tool/AbstractToolPanel.java | 118 +++++++ .../ui/panel/tool/AntSwordToolPanel.java | 34 ++ .../ui/panel/tool/BehinderToolPanel.java | 34 ++ .../ui/panel/tool/CommandToolPanel.java | 99 ++++++ .../ui/panel/tool/CustomToolPanel.java | 131 +++++++ .../ui/panel/tool/GodzillaToolPanel.java | 40 +++ .../ui/panel/tool/NeoRegToolPanel.java | 30 ++ .../ui/panel/tool/ProxyToolPanel.java | 42 +++ .../ui/panel/tool/RefreshableToolPanel.java | 5 + .../memshell/ui/panel/tool/Suo5ToolPanel.java | 30 ++ .../desktop/memshell/util/ClipboardUtil.java | 12 + .../desktop/memshell/util/FileSaveUtil.java | 50 +++ .../desktop/memshell/util/SwingUiUtil.java | 32 ++ .../validation/MemShellValidator.java | 73 ++++ .../MemShellFormControllerTest.java | 51 +++ .../service/CustomClassNameParserTest.java | 34 ++ .../service/GenerationServiceTest.java | 29 ++ .../ui/MemShellGeneratorFrameLayoutTest.java | 56 +++ .../ui/ResultPanelBasicInfoLayoutTest.java | 71 ++++ .../validation/MemShellValidatorTest.java | 59 ++++ settings.gradle.kts | 1 + 36 files changed, 2649 insertions(+) create mode 100644 desktop/java-swing-gui/build.gradle.kts create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/MemShellDesktopApplication.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/controller/MemShellFormController.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/DesktopMemShellGenerateResult.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/MemShellFormState.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerCategoryModel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerEntryModel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerSchemaFieldModel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/service/ConfigCatalogService.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/service/CustomClassNameParser.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/service/GenerationService.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/MemShellGeneratorFrame.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/MainConfigPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/PackageConfigPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/ResultPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/tool/AbstractToolPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/tool/AntSwordToolPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/tool/BehinderToolPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/tool/CommandToolPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/tool/CustomToolPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/tool/GodzillaToolPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/tool/NeoRegToolPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/tool/ProxyToolPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/tool/RefreshableToolPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/ui/panel/tool/Suo5ToolPanel.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/util/ClipboardUtil.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/util/FileSaveUtil.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/util/SwingUiUtil.java create mode 100644 desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/validation/MemShellValidator.java create mode 100644 desktop/java-swing-gui/src/test/java/com/reajason/javaweb/desktop/memshell/controller/MemShellFormControllerTest.java create mode 100644 desktop/java-swing-gui/src/test/java/com/reajason/javaweb/desktop/memshell/service/CustomClassNameParserTest.java create mode 100644 desktop/java-swing-gui/src/test/java/com/reajason/javaweb/desktop/memshell/service/GenerationServiceTest.java create mode 100644 desktop/java-swing-gui/src/test/java/com/reajason/javaweb/desktop/memshell/ui/MemShellGeneratorFrameLayoutTest.java create mode 100644 desktop/java-swing-gui/src/test/java/com/reajason/javaweb/desktop/memshell/ui/ResultPanelBasicInfoLayoutTest.java create mode 100644 desktop/java-swing-gui/src/test/java/com/reajason/javaweb/desktop/memshell/validation/MemShellValidatorTest.java diff --git a/desktop/java-swing-gui/build.gradle.kts b/desktop/java-swing-gui/build.gradle.kts new file mode 100644 index 00000000..e22464a1 --- /dev/null +++ b/desktop/java-swing-gui/build.gradle.kts @@ -0,0 +1,33 @@ +plugins { + id("java") + id("application") +} + +group = "com.reajason.javaweb" +version = rootProject.version + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(8) + } + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +dependencies { + implementation(project(":generator")) + implementation(project(":packer")) + implementation("com.formdev:flatlaf:3.7") + implementation("com.miglayout:miglayout-swing:5.3") + + testImplementation(libs.junit.jupiter) + testRuntimeOnly(libs.junit.platform.launcher) +} + +application { + mainClass.set("com.reajason.javaweb.desktop.memshell.MemShellDesktopApplication") +} + +tasks.test { + useJUnitPlatform() +} diff --git a/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/MemShellDesktopApplication.java b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/MemShellDesktopApplication.java new file mode 100644 index 00000000..27a8fc56 --- /dev/null +++ b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/MemShellDesktopApplication.java @@ -0,0 +1,13 @@ +package com.reajason.javaweb.desktop.memshell; + +import com.formdev.flatlaf.FlatLightLaf; +import com.reajason.javaweb.desktop.memshell.ui.MemShellGeneratorFrame; + +import javax.swing.*; + +public class MemShellDesktopApplication { + public static void main(String[] args) { + FlatLightLaf.setup(); + SwingUtilities.invokeLater(() -> new MemShellGeneratorFrame().setVisible(true)); + } +} diff --git a/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/controller/MemShellFormController.java b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/controller/MemShellFormController.java new file mode 100644 index 00000000..ef82609c --- /dev/null +++ b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/controller/MemShellFormController.java @@ -0,0 +1,331 @@ +package com.reajason.javaweb.desktop.memshell.controller; + +import com.reajason.javaweb.desktop.memshell.model.MemShellFormState; +import com.reajason.javaweb.desktop.memshell.model.PackerCategoryModel; +import com.reajason.javaweb.desktop.memshell.model.PackerEntryModel; +import com.reajason.javaweb.desktop.memshell.model.PackerSchemaFieldModel; +import com.reajason.javaweb.desktop.memshell.service.ConfigCatalogService; +import com.reajason.javaweb.desktop.memshell.validation.MemShellValidator; +import com.reajason.javaweb.memshell.ShellTool; + +import java.util.*; + +public class MemShellFormController { + private final ConfigCatalogService configCatalogService; + private final MemShellValidator validator; + private final ConfigCatalogService.ConfigCatalog catalog; + private final MemShellFormState state = new MemShellFormState(); + + public MemShellFormController(ConfigCatalogService configCatalogService, MemShellValidator validator) { + this.configCatalogService = configCatalogService; + this.validator = validator; + this.catalog = configCatalogService.load(); + reconcileAfterServerChange(true); + reconcilePackerSelection(); + } + + public ConfigCatalogService getConfigCatalogService() { return configCatalogService; } + public MemShellFormState getState() { return state; } + public ConfigCatalogService.ConfigCatalog getCatalog() { return catalog; } + public MemShellValidator getValidator() { return validator; } + + public List getServers() { + return new ArrayList<>(catalog.getServers().keySet()); + } + + public List getServerVersionOptions() { + return configCatalogService.getServerVersionOptions(state.getServer()); + } + + public List getShellTools() { + Map> toolMap = catalog.getCore().get(state.getServer()); + if (toolMap == null) return Collections.emptyList(); + LinkedHashSet tools = new LinkedHashSet<>(toolMap.keySet()); + tools.add(ShellTool.Custom); + return new ArrayList<>(tools); + } + + public List getCustomShellTypes() { + List values = catalog.getServers().get(state.getServer()); + return new ArrayList(values == null ? Collections.emptyList() : values); + } + + public List getShellTypesForCurrentTool() { + Map> toolMap = catalog.getCore().get(state.getServer()); + if (toolMap == null) return Collections.emptyList(); + if (ShellTool.Custom.equals(state.getShellTool())) { + return getCustomShellTypes(); + } + List values = toolMap.get(state.getShellTool()); + return new ArrayList(values == null ? Collections.emptyList() : values); + } + + public List getFilteredPackers() { + List out = new ArrayList<>(); + for (PackerCategoryModel c : catalog.getPackers()) { + for (PackerEntryModel p : c.getPackers()) { + if (p.isCategoryAnchor()) continue; + String name = p.getName(); + String shellType = state.getShellType(); + String server = state.getServer(); + if (shellType != null && shellType.startsWith("Agent")) { + if (name.startsWith("Agent")) out.add(p); + continue; + } + if (server != null && server.startsWith("XXL")) { + if (!name.startsWith("Agent")) out.add(p); + continue; + } + if (!name.startsWith("Agent") && !name.toLowerCase(Locale.ROOT).startsWith("xxl")) { + out.add(p); + } + } + } + return out; + } + + public PackerEntryModel getSelectedPackerEntry() { + String selected = state.getPackingMethod(); + if (selected == null || selected.trim().isEmpty()) return null; + for (PackerCategoryModel c : catalog.getPackers()) { + for (PackerEntryModel p : c.getPackers()) { + if (selected.equals(p.getName())) return p; + } + } + return null; + } + + public List getSelectedPackerFields() { + PackerEntryModel p = getSelectedPackerEntry(); + return p == null ? Collections.emptyList() : p.getFields(); + } + + public List getCommandEncryptors() { return catalog.getCommandEncryptors(); } + public List getCommandImplementationClasses() { return catalog.getCommandImplementationClasses(); } + + public void setServer(String server) { + state.setServer(server); + reconcileAfterServerChange(false); + reconcilePackerSelection(); + } + + public void setServerVersion(String version) { state.setServerVersion(version); } + + public void setTargetJdkVersion(String value) { + state.setTargetJdkVersion(value); + try { + state.setByPassJavaModule(Integer.parseInt(value) >= 53); + } catch (Exception ignored) { + } + } + + public void setShellTool(String tool) { + handleShellToolChange(tool); + reconcilePackerSelection(); + } + + public void setShellType(String shellType) { + state.setShellType(shellType); + state.setUrlPattern(""); + reconcilePackerSelection(); + } + + public void setUrlPattern(String urlPattern) { state.setUrlPattern(urlPattern); } + public void setDebug(boolean value) { state.setDebug(value); } + public void setProbe(boolean value) { state.setProbe(value); } + public void setByPassJavaModule(boolean value) { state.setByPassJavaModule(value); } + public void setLambdaSuffix(boolean value) { state.setLambdaSuffix(value); } + public void setShrink(boolean value) { state.setShrink(value); } + public void setStaticInitialize(boolean value) { state.setStaticInitialize(value); } + + public void setGodzillaPass(String v) { state.setGodzillaPass(v); } + public void setGodzillaKey(String v) { state.setGodzillaKey(v); } + public void setBehinderPass(String v) { state.setBehinderPass(v); } + public void setAntSwordPass(String v) { state.setAntSwordPass(v); } + public void setCommandParamName(String v) { state.setCommandParamName(v); } + public void setCommandTemplate(String v) { state.setCommandTemplate(v); } + public void setHeaderName(String v) { state.setHeaderName(v); } + public void setHeaderValue(String v) { state.setHeaderValue(v); } + public void setShellClassBase64(String v) { state.setShellClassBase64(v); } + public void setEncryptor(String v) { state.setEncryptor(v); } + public void setImplementationClass(String v) { state.setImplementationClass(v); } + + public void setShellClassName(String v) { + state.setShellClassName(v); + autoDisableRandomIfManualNames(); + } + + public void setInjectorClassName(String v) { + state.setInjectorClassName(v); + autoDisableRandomIfManualNames(); + } + + public void setRandomClassName(boolean checked) { + state.setRandomClassName(checked); + if (checked) { + state.setSavedShellClassName(state.getShellClassName()); + state.setSavedInjectorClassName(state.getInjectorClassName()); + state.setShellClassName(""); + state.setInjectorClassName(""); + } else { + state.setShellClassName(state.getSavedShellClassName()); + state.setInjectorClassName(state.getSavedInjectorClassName()); + } + } + + public void setCustomInputMode(String mode) { state.setCustomInputMode(mode); } + + public void setPacker(String packerName) { + state.setPackingMethod(packerName); + resetPackerCustomConfigToDefaults(); + } + + public void setPackerCustomField(String key, Object value) { + if (value == null) { + state.getPackerCustomConfig().remove(key); + } else { + state.getPackerCustomConfig().put(key, value); + } + } + + public Map getPackerCustomConfig() { return state.getPackerCustomConfig(); } + + public boolean isUrlPatternVisible() { + return validator.needsUrlPattern(state.getShellType()); + } + + public boolean isCommandHeaderVisible() { + return "BypassNginxWebSocket".equals(state.getShellType()) || "BypassNginxJakartaWebSocket".equals(state.getShellType()); + } + + public boolean isProxyHeaderVisible() { return isCommandHeaderVisible(); } + + public boolean isCommandParamVisible() { + return state.getShellType() == null || !state.getShellType().contains("WebSocket"); + } + + public MemShellValidator.Result validate() { return validator.validate(state); } + + private void reconcileAfterServerChange(boolean initial) { + List serverVersions = getServerVersionOptions(); + if (!serverVersions.contains(state.getServerVersion())) { + state.setServerVersion(serverVersions.get(0)); + } + Map> toolMap = catalog.getCore().get(state.getServer()); + if (toolMap == null || toolMap.isEmpty()) { + return; + } + List toolKeys = new ArrayList<>(toolMap.keySet()); + String currentTool = state.getShellTool(); + String nextTool = toolMap.containsKey(currentTool) ? currentTool : toolKeys.get(0); + state.setShellTool(nextTool); + + String currentTargetJdk = state.getTargetJdkVersion(); + int currentJdk = parseInt(currentTargetJdk, 50); + boolean raise = ("SpringWebFlux".equals(state.getServer()) || "XXLJOB".equals(state.getServer())) && currentJdk <= 52; + state.setTargetJdkVersion(raise ? "52" : "50"); + state.setByPassJavaModule(parseInt(state.getTargetJdkVersion(), 50) >= 53); + if (!initial) { + state.setUrlPattern(""); + } + + if (!serverVersions.contains(state.getServerVersion())) { + state.setServerVersion(serverVersions.get(0)); + } + ensureShellTypeValidForCurrentTool(); + } + + private void ensureShellTypeValidForCurrentTool() { + List shellTypes = getShellTypesForCurrentTool(); + if (shellTypes.isEmpty()) { + state.setShellType(""); + return; + } + if (!shellTypes.contains(state.getShellType())) { + state.setShellType(shellTypes.get(0)); + } + } + + private void handleShellToolChange(String value) { + if (value == null || value.trim().isEmpty()) return; + + state.setUrlPattern(""); + state.setShellClassName(""); + state.setInjectorClassName(""); + + if (ShellTool.Command.equals(value)) { + state.setCommandParamName(""); + state.setImplementationClass(""); + state.setEncryptor(""); + } else if (ShellTool.Godzilla.equals(value)) { + state.setGodzillaKey(""); + state.setGodzillaPass(""); + state.setHeaderName("User-Agent"); + state.setHeaderValue(""); + } else if (ShellTool.Behinder.equals(value)) { + state.setBehinderPass(""); + state.setHeaderName("User-Agent"); + state.setHeaderValue(""); + } else if (ShellTool.Suo5.equals(value) || ShellTool.Suo5v2.equals(value)) { + state.setHeaderName("User-Agent"); + state.setHeaderValue(""); + } else if (ShellTool.AntSword.equals(value)) { + state.setAntSwordPass(""); + state.setHeaderName("User-Agent"); + state.setHeaderValue(""); + } else if (ShellTool.NeoreGeorg.equals(value)) { + state.setHeaderName("Referer"); + state.setHeaderValue(""); + } else if (ShellTool.Custom.equals(value)) { + state.setShellClassBase64(""); + } else if (ShellTool.Proxy.equals(value)) { + state.setHeaderName("User-Agent"); + state.setHeaderValue(""); + } + + state.setShellTool(value); + ensureShellTypeValidForCurrentTool(); + } + + private void reconcilePackerSelection() { + List filtered = getFilteredPackers(); + if (filtered.isEmpty()) { + state.setPackingMethod(""); + state.getPackerCustomConfig().clear(); + return; + } + boolean exists = filtered.stream().anyMatch(p -> p.getName().equals(state.getPackingMethod())); + if (!exists) { + state.setPackingMethod(filtered.get(0).getName()); + resetPackerCustomConfigToDefaults(); + } else if (state.getPackerCustomConfig().isEmpty()) { + resetPackerCustomConfigToDefaults(); + } + } + + private void resetPackerCustomConfigToDefaults() { + state.getPackerCustomConfig().clear(); + PackerEntryModel selected = getSelectedPackerEntry(); + if (selected != null) { + state.getPackerCustomConfig().putAll(selected.getDefaultConfig()); + } + } + + private void autoDisableRandomIfManualNames() { + if (state.isRandomClassName() && (!state.getShellClassName().trim().isEmpty() || !state.getInjectorClassName().trim().isEmpty())) { + state.setRandomClassName(false); + } + if (!state.isRandomClassName()) { + state.setSavedShellClassName(state.getShellClassName()); + state.setSavedInjectorClassName(state.getInjectorClassName()); + } + } + + private int parseInt(String v, int d) { + try { + return Integer.parseInt(v); + } catch (Exception e) { + return d; + } + } +} diff --git a/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/DesktopMemShellGenerateResult.java b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/DesktopMemShellGenerateResult.java new file mode 100644 index 00000000..db266e49 --- /dev/null +++ b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/DesktopMemShellGenerateResult.java @@ -0,0 +1,25 @@ +package com.reajason.javaweb.desktop.memshell.model; + +import com.reajason.javaweb.memshell.MemShellResult; + +public class DesktopMemShellGenerateResult { + private final MemShellResult memShellResult; + private final String packMethod; + private final String packResult; + private final boolean jarOutput; + private final boolean agentOutput; + + public DesktopMemShellGenerateResult(MemShellResult memShellResult, String packMethod, String packResult) { + this.memShellResult = memShellResult; + this.packMethod = packMethod; + this.packResult = packResult; + this.jarOutput = packMethod != null && packMethod.endsWith("Jar"); + this.agentOutput = packMethod != null && packMethod.startsWith("Agent"); + } + + public MemShellResult getMemShellResult() { return memShellResult; } + public String getPackMethod() { return packMethod; } + public String getPackResult() { return packResult; } + public boolean isJarOutput() { return jarOutput; } + public boolean isAgentOutput() { return agentOutput; } +} diff --git a/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/MemShellFormState.java b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/MemShellFormState.java new file mode 100644 index 00000000..958031e2 --- /dev/null +++ b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/MemShellFormState.java @@ -0,0 +1,145 @@ +package com.reajason.javaweb.desktop.memshell.model; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class MemShellFormState { + private String server = "Tomcat"; + private String serverVersion = "Unknown"; + private String targetJdkVersion = "50"; + private boolean debug; + private boolean byPassJavaModule; + private boolean probe; + private boolean lambdaSuffix; + private boolean shrink = true; + private boolean staticInitialize = true; + + private String shellTool = "Godzilla"; + private String shellType = "Listener"; + private String urlPattern = "/*"; + + private String shellClassName = ""; + private String injectorClassName = ""; + + private String godzillaPass = ""; + private String godzillaKey = ""; + private String behinderPass = ""; + private String antSwordPass = ""; + private String commandParamName = ""; + private String commandTemplate = ""; + private String headerName = "User-Agent"; + private String headerValue = ""; + private String shellClassBase64 = ""; + private String encryptor = ""; + private String implementationClass = ""; + + private String packingMethod = ""; + private final Map packerCustomConfig = new LinkedHashMap<>(); + + private boolean randomClassName = true; + private String customInputMode = "base64"; + + private String savedShellClassName = ""; + private String savedInjectorClassName = ""; + + public MemShellFormState copy() { + MemShellFormState c = new MemShellFormState(); + c.server = server; + c.serverVersion = serverVersion; + c.targetJdkVersion = targetJdkVersion; + c.debug = debug; + c.byPassJavaModule = byPassJavaModule; + c.probe = probe; + c.lambdaSuffix = lambdaSuffix; + c.shrink = shrink; + c.staticInitialize = staticInitialize; + c.shellTool = shellTool; + c.shellType = shellType; + c.urlPattern = urlPattern; + c.shellClassName = shellClassName; + c.injectorClassName = injectorClassName; + c.godzillaPass = godzillaPass; + c.godzillaKey = godzillaKey; + c.behinderPass = behinderPass; + c.antSwordPass = antSwordPass; + c.commandParamName = commandParamName; + c.commandTemplate = commandTemplate; + c.headerName = headerName; + c.headerValue = headerValue; + c.shellClassBase64 = shellClassBase64; + c.encryptor = encryptor; + c.implementationClass = implementationClass; + c.packingMethod = packingMethod; + c.packerCustomConfig.putAll(packerCustomConfig); + c.randomClassName = randomClassName; + c.customInputMode = customInputMode; + c.savedShellClassName = savedShellClassName; + c.savedInjectorClassName = savedInjectorClassName; + return c; + } + + public Map getPackerCustomConfig() { return packerCustomConfig; } + + public String getServer() { return server; } + public void setServer(String server) { this.server = server; } + public String getServerVersion() { return serverVersion; } + public void setServerVersion(String serverVersion) { this.serverVersion = serverVersion; } + public String getTargetJdkVersion() { return targetJdkVersion; } + public void setTargetJdkVersion(String targetJdkVersion) { this.targetJdkVersion = targetJdkVersion; } + public boolean isDebug() { return debug; } + public void setDebug(boolean debug) { this.debug = debug; } + public boolean isByPassJavaModule() { return byPassJavaModule; } + public void setByPassJavaModule(boolean byPassJavaModule) { this.byPassJavaModule = byPassJavaModule; } + public boolean isProbe() { return probe; } + public void setProbe(boolean probe) { this.probe = probe; } + public boolean isLambdaSuffix() { return lambdaSuffix; } + public void setLambdaSuffix(boolean lambdaSuffix) { this.lambdaSuffix = lambdaSuffix; } + public boolean isShrink() { return shrink; } + public void setShrink(boolean shrink) { this.shrink = shrink; } + public boolean isStaticInitialize() { return staticInitialize; } + public void setStaticInitialize(boolean staticInitialize) { this.staticInitialize = staticInitialize; } + public String getShellTool() { return shellTool; } + public void setShellTool(String shellTool) { this.shellTool = shellTool; } + public String getShellType() { return shellType; } + public void setShellType(String shellType) { this.shellType = shellType; } + public String getUrlPattern() { return urlPattern; } + public void setUrlPattern(String urlPattern) { this.urlPattern = urlPattern; } + public String getShellClassName() { return shellClassName; } + public void setShellClassName(String shellClassName) { this.shellClassName = shellClassName == null ? "" : shellClassName; } + public String getInjectorClassName() { return injectorClassName; } + public void setInjectorClassName(String injectorClassName) { this.injectorClassName = injectorClassName == null ? "" : injectorClassName; } + public String getGodzillaPass() { return godzillaPass; } + public void setGodzillaPass(String godzillaPass) { this.godzillaPass = nv(godzillaPass); } + public String getGodzillaKey() { return godzillaKey; } + public void setGodzillaKey(String godzillaKey) { this.godzillaKey = nv(godzillaKey); } + public String getBehinderPass() { return behinderPass; } + public void setBehinderPass(String behinderPass) { this.behinderPass = nv(behinderPass); } + public String getAntSwordPass() { return antSwordPass; } + public void setAntSwordPass(String antSwordPass) { this.antSwordPass = nv(antSwordPass); } + public String getCommandParamName() { return commandParamName; } + public void setCommandParamName(String commandParamName) { this.commandParamName = nv(commandParamName); } + public String getCommandTemplate() { return commandTemplate; } + public void setCommandTemplate(String commandTemplate) { this.commandTemplate = nv(commandTemplate); } + public String getHeaderName() { return headerName; } + public void setHeaderName(String headerName) { this.headerName = nv(headerName); } + public String getHeaderValue() { return headerValue; } + public void setHeaderValue(String headerValue) { this.headerValue = nv(headerValue); } + public String getShellClassBase64() { return shellClassBase64; } + public void setShellClassBase64(String shellClassBase64) { this.shellClassBase64 = nv(shellClassBase64); } + public String getEncryptor() { return encryptor; } + public void setEncryptor(String encryptor) { this.encryptor = nv(encryptor); } + public String getImplementationClass() { return implementationClass; } + public void setImplementationClass(String implementationClass) { this.implementationClass = nv(implementationClass); } + public String getPackingMethod() { return packingMethod; } + public void setPackingMethod(String packingMethod) { this.packingMethod = nv(packingMethod); } + public boolean isRandomClassName() { return randomClassName; } + public void setRandomClassName(boolean randomClassName) { this.randomClassName = randomClassName; } + public String getCustomInputMode() { return customInputMode; } + public void setCustomInputMode(String customInputMode) { this.customInputMode = nv(customInputMode); } + public String getSavedShellClassName() { return savedShellClassName; } + public void setSavedShellClassName(String savedShellClassName) { this.savedShellClassName = nv(savedShellClassName); } + public String getSavedInjectorClassName() { return savedInjectorClassName; } + public void setSavedInjectorClassName(String savedInjectorClassName) { this.savedInjectorClassName = nv(savedInjectorClassName); } + + private static String nv(String v) { return v == null ? "" : v; } +} diff --git a/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerCategoryModel.java b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerCategoryModel.java new file mode 100644 index 00000000..eb8730b4 --- /dev/null +++ b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerCategoryModel.java @@ -0,0 +1,15 @@ +package com.reajason.javaweb.desktop.memshell.model; + +import java.util.ArrayList; +import java.util.List; + +public class PackerCategoryModel { + private String name; + private final List packers = new ArrayList<>(); + + public PackerCategoryModel() {} + public PackerCategoryModel(String name) { this.name = name; } + public String getName() { return name; } + public void setName(String name) { this.name = name; } + public List getPackers() { return packers; } +} diff --git a/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerEntryModel.java b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerEntryModel.java new file mode 100644 index 00000000..2bdfedca --- /dev/null +++ b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerEntryModel.java @@ -0,0 +1,30 @@ +package com.reajason.javaweb.desktop.memshell.model; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class PackerEntryModel { + private String categoryName; + private String name; + private String outputKind; + private boolean categoryAnchor; + private final List fields = new ArrayList<>(); + private final Map defaultConfig = new LinkedHashMap<>(); + + public String getCategoryName() { return categoryName; } + public void setCategoryName(String categoryName) { this.categoryName = categoryName; } + public String getName() { return name; } + public void setName(String name) { this.name = name; } + public String getOutputKind() { return outputKind; } + public void setOutputKind(String outputKind) { this.outputKind = outputKind; } + public boolean isCategoryAnchor() { return categoryAnchor; } + public void setCategoryAnchor(boolean categoryAnchor) { this.categoryAnchor = categoryAnchor; } + public List getFields() { return fields; } + public Map getDefaultConfig() { return defaultConfig; } + + public String displayLabel() { + return categoryName == null || categoryName.equals(name) ? name : categoryName + " / " + name; + } +} diff --git a/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerSchemaFieldModel.java b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerSchemaFieldModel.java new file mode 100644 index 00000000..a51079b4 --- /dev/null +++ b/desktop/java-swing-gui/src/main/java/com/reajason/javaweb/desktop/memshell/model/PackerSchemaFieldModel.java @@ -0,0 +1,43 @@ +package com.reajason.javaweb.desktop.memshell.model; + +import java.util.ArrayList; +import java.util.List; + +public class PackerSchemaFieldModel { + public static class Option { + private String value; + private String label; + + public Option() {} + public Option(String value, String label) { + this.value = value; + this.label = label; + } + public String getValue() { return value; } + public void setValue(String value) { this.value = value; } + public String getLabel() { return label; } + public void setLabel(String label) { this.label = label; } + } + + private String key; + private String type; + private boolean required; + private Object defaultValue; + private String description; + private String descriptionI18nKey; + private final List