mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-24 07:51:52 +08:00
refactor: simplify shell generator
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package com.reajason.javaweb.memshell.generator;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
|
import com.reajason.javaweb.memshell.config.ShellToolConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/5/27
|
||||||
|
*/
|
||||||
|
public abstract class ASMShellGenerator<T extends ShellToolConfig> implements ShellGenerator {
|
||||||
|
protected final ShellConfig shellConfig;
|
||||||
|
protected final T shellToolConfig;
|
||||||
|
|
||||||
|
protected ASMShellGenerator(ShellConfig shellConfig, T shellToolConfig) {
|
||||||
|
this.shellConfig = shellConfig;
|
||||||
|
this.shellToolConfig = shellToolConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-43
@@ -1,14 +1,8 @@
|
|||||||
package com.reajason.javaweb.memshell.generator;
|
package com.reajason.javaweb.memshell.generator;
|
||||||
|
|
||||||
import com.reajason.javaweb.ClassBytesShrink;
|
|
||||||
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
|
|
||||||
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.memshell.config.AntSwordConfig;
|
import com.reajason.javaweb.memshell.config.AntSwordConfig;
|
||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
import net.bytebuddy.ByteBuddy;
|
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
@@ -16,44 +10,15 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2025/02/18
|
* @since 2025/02/18
|
||||||
*/
|
*/
|
||||||
public class AntSwordGenerator {
|
public class AntSwordGenerator extends ByteBuddyShellGenerator<AntSwordConfig> {
|
||||||
private final ShellConfig shellConfig;
|
public AntSwordGenerator(ShellConfig shellConfig, AntSwordConfig shellToolConfig) {
|
||||||
private final AntSwordConfig antSwordConfig;
|
super(shellConfig, shellToolConfig);
|
||||||
|
|
||||||
public AntSwordGenerator(ShellConfig shellConfig, AntSwordConfig antSwordConfig) {
|
|
||||||
this.shellConfig = shellConfig;
|
|
||||||
this.antSwordConfig = antSwordConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicType.Builder<?> getBuilder() {
|
@Override
|
||||||
if (antSwordConfig.getShellClass() == null) {
|
protected DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
|
||||||
throw new IllegalArgumentException("antSwordConfig.getClazz() == null");
|
return builder.field(named("pass")).value(shellToolConfig.getPass())
|
||||||
}
|
.field(named("headerName")).value(shellToolConfig.getHeaderName())
|
||||||
if (StringUtils.isBlank(antSwordConfig.getPass())) {
|
.field(named("headerValue")).value(shellToolConfig.getHeaderValue());
|
||||||
throw new IllegalArgumentException("antSwordConfig.getPass().isBlank()");
|
|
||||||
}
|
|
||||||
DynamicType.Builder<?> builder = new ByteBuddy()
|
|
||||||
.redefine(antSwordConfig.getShellClass())
|
|
||||||
.name(antSwordConfig.getShellClassName())
|
|
||||||
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()));
|
|
||||||
|
|
||||||
if (shellConfig.isJakarta()) {
|
|
||||||
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shellConfig.isDebugOff()) {
|
|
||||||
builder = LogRemoveMethodVisitor.extend(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.field(named("pass")).value(antSwordConfig.getPass())
|
|
||||||
.field(named("headerName")).value(antSwordConfig.getHeaderName())
|
|
||||||
.field(named("headerValue")).value(antSwordConfig.getHeaderValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes() {
|
|
||||||
DynamicType.Builder<?> builder = getBuilder();
|
|
||||||
try (DynamicType.Unloaded<?> make = builder.make()) {
|
|
||||||
return ClassBytesShrink.shrink(make.getBytes(), shellConfig.isShrink());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-44
@@ -1,15 +1,9 @@
|
|||||||
package com.reajason.javaweb.memshell.generator;
|
package com.reajason.javaweb.memshell.generator;
|
||||||
|
|
||||||
import com.reajason.javaweb.ClassBytesShrink;
|
|
||||||
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
|
|
||||||
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.memshell.config.BehinderConfig;
|
import com.reajason.javaweb.memshell.config.BehinderConfig;
|
||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
import com.reajason.javaweb.memshell.utils.DigestUtils;
|
import com.reajason.javaweb.memshell.utils.DigestUtils;
|
||||||
import net.bytebuddy.ByteBuddy;
|
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
@@ -17,46 +11,15 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2024/12/21
|
* @since 2024/12/21
|
||||||
*/
|
*/
|
||||||
public class BehinderGenerator {
|
public class BehinderGenerator extends ByteBuddyShellGenerator<BehinderConfig> {
|
||||||
private final ShellConfig shellConfig;
|
public BehinderGenerator(ShellConfig shellConfig, BehinderConfig shellToolConfig) {
|
||||||
private final BehinderConfig behinderConfig;
|
super(shellConfig, shellToolConfig);
|
||||||
|
|
||||||
public BehinderGenerator(ShellConfig shellConfig, BehinderConfig behinderConfig) {
|
|
||||||
this.shellConfig = shellConfig;
|
|
||||||
this.behinderConfig = behinderConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicType.Builder<?> getBuilder() {
|
public DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
|
||||||
if (behinderConfig.getShellClass() == null) {
|
String md5Key = DigestUtils.md5Hex(shellToolConfig.getPass()).substring(0, 16);
|
||||||
throw new IllegalArgumentException("behinderConfig.getClazz() == null");
|
|
||||||
}
|
|
||||||
if (StringUtils.isBlank(behinderConfig.getPass())) {
|
|
||||||
throw new IllegalArgumentException("behinderConfig.getPass().isBlank()");
|
|
||||||
}
|
|
||||||
String md5Key = DigestUtils.md5Hex(behinderConfig.getPass()).substring(0, 16);
|
|
||||||
|
|
||||||
DynamicType.Builder<?> builder = new ByteBuddy()
|
|
||||||
.redefine(behinderConfig.getShellClass())
|
|
||||||
.name(behinderConfig.getShellClassName())
|
|
||||||
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()));
|
|
||||||
|
|
||||||
if (shellConfig.isJakarta()) {
|
|
||||||
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shellConfig.isDebugOff()) {
|
|
||||||
builder = LogRemoveMethodVisitor.extend(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.field(named("pass")).value(md5Key)
|
return builder.field(named("pass")).value(md5Key)
|
||||||
.field(named("headerName")).value(behinderConfig.getHeaderName())
|
.field(named("headerName")).value(shellToolConfig.getHeaderName())
|
||||||
.field(named("headerValue")).value(behinderConfig.getHeaderValue());
|
.field(named("headerValue")).value(shellToolConfig.getHeaderValue());
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes() {
|
|
||||||
DynamicType.Builder<?> builder = getBuilder();
|
|
||||||
try (DynamicType.Unloaded<?> make = builder.make()) {
|
|
||||||
return ClassBytesShrink.shrink(make.getBytes(), shellConfig.isShrink());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
package com.reajason.javaweb.memshell.generator;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.ClassBytesShrink;
|
||||||
|
import com.reajason.javaweb.buddy.ByPassJavaModuleInterceptor;
|
||||||
|
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
|
||||||
|
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
||||||
|
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
||||||
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
|
import com.reajason.javaweb.memshell.config.ShellToolConfig;
|
||||||
|
import net.bytebuddy.ByteBuddy;
|
||||||
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/5/27
|
||||||
|
*/
|
||||||
|
public abstract class ByteBuddyShellGenerator<T extends ShellToolConfig> implements ShellGenerator {
|
||||||
|
protected final ShellConfig shellConfig;
|
||||||
|
protected final T shellToolConfig;
|
||||||
|
|
||||||
|
protected ByteBuddyShellGenerator(ShellConfig shellConfig, T shellToolConfig) {
|
||||||
|
this.shellConfig = shellConfig;
|
||||||
|
this.shellToolConfig = shellToolConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract DynamicType.Builder<?> build(DynamicType.Builder<?> builder);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBytes() {
|
||||||
|
DynamicType.Builder<?> builder = build(new ByteBuddy()
|
||||||
|
.redefine(shellToolConfig.getShellClass())
|
||||||
|
.name(shellToolConfig.getShellClassName())
|
||||||
|
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion())));
|
||||||
|
|
||||||
|
if (shellConfig.isJakarta()) {
|
||||||
|
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shellConfig.isDebugOff()) {
|
||||||
|
builder = LogRemoveMethodVisitor.extend(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
try (DynamicType.Unloaded<?> unloaded = builder.make()) {
|
||||||
|
return ClassBytesShrink.shrink(unloaded.getBytes(), shellConfig.isShrink());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-10
@@ -12,25 +12,21 @@ import java.util.Base64;
|
|||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2025/3/18
|
* @since 2025/3/18
|
||||||
*/
|
*/
|
||||||
public class CustomShellGenerator {
|
public class CustomShellGenerator extends ASMShellGenerator<CustomConfig> {
|
||||||
|
|
||||||
private final ShellConfig shellConfig;
|
|
||||||
private final CustomConfig customConfig;
|
|
||||||
|
|
||||||
public CustomShellGenerator(ShellConfig shellConfig, CustomConfig customConfig) {
|
public CustomShellGenerator(ShellConfig shellConfig, CustomConfig customConfig) {
|
||||||
this.shellConfig = shellConfig;
|
super(shellConfig, customConfig);
|
||||||
this.customConfig = customConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
String shellClassBase64 = customConfig.getShellClassBase64();
|
String shellClassBase64 = shellToolConfig.getShellClassBase64();
|
||||||
|
|
||||||
if (StringUtils.isBlank(shellClassBase64)) {
|
if (StringUtils.isBlank(shellClassBase64)) {
|
||||||
throw new IllegalArgumentException("Custom shell class is empty");
|
throw new IllegalArgumentException("Custom shell class is empty");
|
||||||
}
|
}
|
||||||
|
byte[] classBytes = Base64.getDecoder().decode(shellClassBase64);
|
||||||
byte[] bytes = ClassRenameUtils.renameClass(Base64.getDecoder().decode(shellClassBase64), customConfig.getShellClassName());
|
byte[] bytes = ClassRenameUtils.renameClass(classBytes, shellToolConfig.getShellClassName());
|
||||||
|
|
||||||
return ClassBytesShrink.shrink(bytes, shellConfig.isShrink());
|
return ClassBytesShrink.shrink(bytes, shellConfig.isShrink());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-43
@@ -1,15 +1,10 @@
|
|||||||
package com.reajason.javaweb.memshell.generator;
|
package com.reajason.javaweb.memshell.generator;
|
||||||
|
|
||||||
import com.reajason.javaweb.ClassBytesShrink;
|
import com.reajason.javaweb.ClassBytesShrink;
|
||||||
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
|
|
||||||
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.memshell.config.GodzillaConfig;
|
import com.reajason.javaweb.memshell.config.GodzillaConfig;
|
||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
import com.reajason.javaweb.memshell.utils.DigestUtils;
|
import com.reajason.javaweb.memshell.utils.DigestUtils;
|
||||||
import net.bytebuddy.ByteBuddy;
|
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
@@ -17,49 +12,20 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2024/11/23
|
* @since 2024/11/23
|
||||||
*/
|
*/
|
||||||
public class GodzillaGenerator {
|
public class GodzillaGenerator extends ByteBuddyShellGenerator<GodzillaConfig> {
|
||||||
private final ShellConfig shellConfig;
|
|
||||||
private final GodzillaConfig godzillaConfig;
|
|
||||||
|
|
||||||
public GodzillaGenerator(ShellConfig shellConfig, GodzillaConfig godzillaConfig) {
|
public GodzillaGenerator(ShellConfig shellConfig, GodzillaConfig godzillaConfig) {
|
||||||
this.shellConfig = shellConfig;
|
super(shellConfig, godzillaConfig);
|
||||||
this.godzillaConfig = godzillaConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicType.Builder<?> getBuilder() {
|
@Override
|
||||||
if (godzillaConfig.getShellClass() == null) {
|
public DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
|
||||||
throw new IllegalArgumentException("godzillaConfig.getClazz() == null");
|
String md5Key = DigestUtils.md5Hex(shellToolConfig.getKey()).substring(0, 16);
|
||||||
}
|
String md5 = DigestUtils.md5Hex(shellToolConfig.getPass() + md5Key).toUpperCase();
|
||||||
if (StringUtils.isBlank(godzillaConfig.getKey()) || StringUtils.isBlank(godzillaConfig.getPass())) {
|
return builder.field(named("pass")).value(shellToolConfig.getPass())
|
||||||
throw new IllegalArgumentException("godzillaConfig.getKey().isBlank() || godzillaConfig.getPass().isBlank()");
|
|
||||||
}
|
|
||||||
String md5Key = DigestUtils.md5Hex(godzillaConfig.getKey()).substring(0, 16);
|
|
||||||
String md5 = DigestUtils.md5Hex(godzillaConfig.getPass() + md5Key).toUpperCase();
|
|
||||||
|
|
||||||
DynamicType.Builder<?> builder = new ByteBuddy()
|
|
||||||
.redefine(godzillaConfig.getShellClass())
|
|
||||||
.name(godzillaConfig.getShellClassName())
|
|
||||||
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()));
|
|
||||||
|
|
||||||
if (shellConfig.isJakarta()) {
|
|
||||||
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shellConfig.isDebugOff()) {
|
|
||||||
builder = LogRemoveMethodVisitor.extend(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.field(named("pass")).value(godzillaConfig.getPass())
|
|
||||||
.field(named("key")).value(md5Key)
|
.field(named("key")).value(md5Key)
|
||||||
.field(named("md5")).value(md5)
|
.field(named("md5")).value(md5)
|
||||||
.field(named("headerName")).value(godzillaConfig.getHeaderName())
|
.field(named("headerName")).value(shellToolConfig.getHeaderName())
|
||||||
.field(named("headerValue")).value(godzillaConfig.getHeaderValue());
|
.field(named("headerValue")).value(shellToolConfig.getHeaderValue());
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes() {
|
|
||||||
DynamicType.Builder<?> builder = getBuilder();
|
|
||||||
try (DynamicType.Unloaded<?> make = builder.make()) {
|
|
||||||
return ClassBytesShrink.shrink(make.getBytes(), shellConfig.isShrink());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-34
@@ -1,12 +1,7 @@
|
|||||||
package com.reajason.javaweb.memshell.generator;
|
package com.reajason.javaweb.memshell.generator;
|
||||||
|
|
||||||
import com.reajason.javaweb.ClassBytesShrink;
|
|
||||||
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
|
|
||||||
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.memshell.config.NeoreGeorgConfig;
|
import com.reajason.javaweb.memshell.config.NeoreGeorgConfig;
|
||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
import net.bytebuddy.ByteBuddy;
|
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
@@ -15,37 +10,14 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2025/2/12
|
* @since 2025/2/12
|
||||||
*/
|
*/
|
||||||
public class NeoreGeorgGenerator {
|
public class NeoreGeorgGenerator extends ByteBuddyShellGenerator<NeoreGeorgConfig> {
|
||||||
private final ShellConfig shellConfig;
|
|
||||||
private final NeoreGeorgConfig neoreGeorgConfig;
|
|
||||||
|
|
||||||
public NeoreGeorgGenerator(ShellConfig shellConfig, NeoreGeorgConfig neoreGeorgConfig) {
|
public NeoreGeorgGenerator(ShellConfig shellConfig, NeoreGeorgConfig neoreGeorgConfig) {
|
||||||
this.shellConfig = shellConfig;
|
super(shellConfig, neoreGeorgConfig);
|
||||||
this.neoreGeorgConfig = neoreGeorgConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicType.Builder<?> getBuilder() {
|
@Override
|
||||||
DynamicType.Builder<?> builder = new ByteBuddy()
|
protected DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
|
||||||
.redefine(neoreGeorgConfig.getShellClass())
|
return builder.field(named("headerName")).value(shellToolConfig.getHeaderName())
|
||||||
.name(neoreGeorgConfig.getShellClassName())
|
.field(named("headerValue")).value(shellToolConfig.getHeaderValue());
|
||||||
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()));
|
|
||||||
|
|
||||||
if (shellConfig.isJakarta()) {
|
|
||||||
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shellConfig.isDebugOff()) {
|
|
||||||
builder = LogRemoveMethodVisitor.extend(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.field(named("headerName")).value(neoreGeorgConfig.getHeaderName())
|
|
||||||
.field(named("headerValue")).value(neoreGeorgConfig.getHeaderValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes() {
|
|
||||||
DynamicType.Builder<?> builder = getBuilder();
|
|
||||||
try (DynamicType.Unloaded<?> make = builder.make()) {
|
|
||||||
return ClassBytesShrink.shrink(make.getBytes(), shellConfig.isShrink());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.reajason.javaweb.memshell.generator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2025/5/27
|
||||||
|
*/
|
||||||
|
public interface ShellGenerator {
|
||||||
|
|
||||||
|
byte[] getBytes();
|
||||||
|
}
|
||||||
@@ -1,12 +1,7 @@
|
|||||||
package com.reajason.javaweb.memshell.generator;
|
package com.reajason.javaweb.memshell.generator;
|
||||||
|
|
||||||
import com.reajason.javaweb.ClassBytesShrink;
|
|
||||||
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
|
|
||||||
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
|
||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
import com.reajason.javaweb.memshell.config.Suo5Config;
|
import com.reajason.javaweb.memshell.config.Suo5Config;
|
||||||
import net.bytebuddy.ByteBuddy;
|
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
@@ -15,38 +10,16 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2025/2/12
|
* @since 2025/2/12
|
||||||
*/
|
*/
|
||||||
public class Suo5Generator {
|
public class Suo5Generator extends ByteBuddyShellGenerator<Suo5Config> {
|
||||||
private final ShellConfig shellConfig;
|
|
||||||
private final Suo5Config suo5Config;
|
|
||||||
|
|
||||||
public Suo5Generator(ShellConfig shellConfig, Suo5Config suo5Config) {
|
public Suo5Generator(ShellConfig shellConfig, Suo5Config suo5Config) {
|
||||||
this.shellConfig = shellConfig;
|
super(shellConfig, suo5Config);
|
||||||
this.suo5Config = suo5Config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicType.Builder<?> getBuilder() {
|
@Override
|
||||||
DynamicType.Builder<?> builder = new ByteBuddy()
|
protected DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
|
||||||
.redefine(suo5Config.getShellClass())
|
|
||||||
.name(suo5Config.getShellClassName())
|
|
||||||
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()));
|
|
||||||
|
|
||||||
if (shellConfig.isJakarta()) {
|
|
||||||
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shellConfig.isDebugOff()) {
|
|
||||||
builder = LogRemoveMethodVisitor.extend(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder
|
return builder
|
||||||
.field(named("headerName")).value(suo5Config.getHeaderName())
|
.field(named("headerName")).value(shellToolConfig.getHeaderName())
|
||||||
.field(named("headerValue")).value(suo5Config.getHeaderValue());
|
.field(named("headerValue")).value(shellToolConfig.getHeaderValue());
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes() {
|
|
||||||
DynamicType.Builder<?> builder = getBuilder();
|
|
||||||
try (DynamicType.Unloaded<?> make = builder.make()) {
|
|
||||||
return ClassBytesShrink.shrink(make.getBytes(), shellConfig.isShrink());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -7,6 +7,7 @@ import com.reajason.javaweb.memshell.config.GodzillaConfig;
|
|||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
|
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
|
||||||
import com.reajason.javaweb.memshell.utils.CommonUtil;
|
import com.reajason.javaweb.memshell.utils.CommonUtil;
|
||||||
|
import com.reajason.javaweb.util.ClassDefiner;
|
||||||
import com.reajason.javaweb.util.ClassUtils;
|
import com.reajason.javaweb.util.ClassUtils;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
@@ -38,8 +39,8 @@ class GodzillaGeneratorTest {
|
|||||||
.key("key")
|
.key("key")
|
||||||
.headerName("User-Agent")
|
.headerName("User-Agent")
|
||||||
.headerValue("test").build();
|
.headerValue("test").build();
|
||||||
DynamicType.Builder<?> builder = new GodzillaGenerator(shellConfig, godzillaConfig).getBuilder();
|
byte[] bytes = new GodzillaGenerator(shellConfig, godzillaConfig).getBytes();
|
||||||
Class<?> loaded = builder.make().load(this.getClass().getClassLoader()).getLoaded();
|
Class<?> loaded = ClassDefiner.defineClass(bytes);
|
||||||
Object o = loaded.getDeclaredConstructor().newInstance();
|
Object o = loaded.getDeclaredConstructor().newInstance();
|
||||||
assertEquals(godzillaConfig.getPass(), ClassUtils.getFieldValue(o, "pass"));
|
assertEquals(godzillaConfig.getPass(), ClassUtils.getFieldValue(o, "pass"));
|
||||||
assertEquals(godzillaConfig.getHeaderName(), ClassUtils.getFieldValue(o, "headerName"));
|
assertEquals(godzillaConfig.getHeaderName(), ClassUtils.getFieldValue(o, "headerName"));
|
||||||
|
|||||||
Reference in New Issue
Block a user