1
1
package com .reajason .javaweb .memshell .generator ;
2
2
3
3
import com .reajason .javaweb .ClassBytesShrink ;
4
- import com .reajason .javaweb .buddy .ByPassJavaModuleInterceptor ;
5
- import com .reajason .javaweb .buddy .LogRemoveMethodVisitor ;
6
- import com .reajason .javaweb .buddy .ServletRenameVisitorWrapper ;
7
- import com .reajason .javaweb .buddy .TargetJreVersionVisitorWrapper ;
4
+ import com .reajason .javaweb .asm .InnerClassDiscovery ;
5
+ import com .reajason .javaweb .buddy .*;
8
6
import com .reajason .javaweb .memshell .config .InjectorConfig ;
9
7
import com .reajason .javaweb .memshell .config .ShellConfig ;
10
8
import com .reajason .javaweb .memshell .utils .CommonUtil ;
11
9
import lombok .SneakyThrows ;
12
10
import net .bytebuddy .ByteBuddy ;
11
+ import net .bytebuddy .description .type .TypeDescription ;
12
+ import net .bytebuddy .dynamic .ClassFileLocator ;
13
13
import net .bytebuddy .dynamic .DynamicType ;
14
+ import net .bytebuddy .dynamic .scaffold .TypeValidation ;
14
15
import net .bytebuddy .implementation .FixedValue ;
16
+ import net .bytebuddy .pool .TypePool ;
15
17
import org .apache .commons .codec .binary .Base64 ;
16
18
17
- import java .util .Objects ;
19
+ import java .util .* ;
18
20
19
21
import static net .bytebuddy .matcher .ElementMatchers .named ;
20
22
@@ -34,10 +36,13 @@ public InjectorGenerator(ShellConfig shellConfig, InjectorConfig injectorConfig)
34
36
@ SneakyThrows
35
37
public DynamicType .Builder <?> getBuilder () {
36
38
String base64String = Base64 .encodeBase64String (CommonUtil .gzipCompress (injectorConfig .getShellClassBytes ()));
39
+ String originalClassName = injectorConfig .getInjectorClass ().getName ();
40
+ String newClassName = injectorConfig .getInjectorClassName ();
41
+
37
42
DynamicType .Builder <?> builder = new ByteBuddy ()
38
43
.redefine (injectorConfig .getInjectorClass ())
39
- .name (injectorConfig .getInjectorClassName ())
40
44
.visit (new TargetJreVersionVisitorWrapper (shellConfig .getTargetJreVersion ()))
45
+ .visit (new ClassRenameVisitorWrapper (originalClassName , newClassName ))
41
46
.method (named ("getUrlPattern" )).intercept (FixedValue .value (Objects .toString (injectorConfig .getUrlPattern (), "/*" )))
42
47
.method (named ("getBase64String" )).intercept (FixedValue .value (base64String ))
43
48
.method (named ("getClassName" )).intercept (FixedValue .value (injectorConfig .getShellClassName ()));
@@ -56,6 +61,38 @@ public DynamicType.Builder<?> getBuilder() {
56
61
return builder ;
57
62
}
58
63
64
+ @ SneakyThrows
65
+ public Map <String , byte []> getInnerClassBytes () {
66
+ Set <String > innerClassNames = InnerClassDiscovery .findAllInnerClasses (injectorConfig .getInjectorClass ());
67
+ if (innerClassNames .isEmpty ()) {
68
+ return Collections .emptyMap ();
69
+ }
70
+
71
+ String originalClassName = injectorConfig .getInjectorClass ().getName ();
72
+ String newClassName = injectorConfig .getInjectorClassName ();
73
+
74
+ ClassFileLocator classFileLocator = ClassFileLocator .ForClassLoader .of (injectorConfig .getInjectorClass ().getClassLoader ());
75
+ TypePool typePool = TypePool .Default .of (classFileLocator );
76
+
77
+ Map <String , byte []> bytes = new HashMap <>();
78
+ for (String innerClassName : innerClassNames ) {
79
+ TypeDescription innerTypeDesc = typePool .describe (innerClassName ).resolve ();
80
+ String newInnerClassName = innerClassName .replace (originalClassName , newClassName );
81
+ DynamicType .Builder <?> innerBuilder = new ByteBuddy ()
82
+ .with (TypeValidation .DISABLED )
83
+ .redefine (innerTypeDesc , classFileLocator )
84
+ .visit (new TargetJreVersionVisitorWrapper (shellConfig .getTargetJreVersion ()))
85
+ .visit (new ClassRenameVisitorWrapper (originalClassName , newClassName ));
86
+
87
+ try (DynamicType .Unloaded <?> unloaded = innerBuilder .make ()) {
88
+ for (Map .Entry <TypeDescription , byte []> entry : unloaded .getAllTypes ().entrySet ()) {
89
+ bytes .put (newInnerClassName , entry .getValue ());
90
+ }
91
+ }
92
+ }
93
+ return bytes ;
94
+ }
95
+
59
96
@ SneakyThrows
60
97
public byte [] generate () {
61
98
DynamicType .Builder <?> builder = getBuilder ();
0 commit comments