mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support GroovyTransformJar packer
This commit is contained in:
+99
@@ -0,0 +1,99 @@
|
||||
package com.reajason.javaweb.asm;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/12/6
|
||||
*/
|
||||
public class ClassAnnotationUtils {
|
||||
|
||||
public static byte[] setAnnotation(byte[] bytes, String annotationClassName) {
|
||||
ClassReader cr = new ClassReader(bytes);
|
||||
ClassWriter cw = new ClassWriter(cr, 0);
|
||||
ClassVisitor cv = new AddAnnotationClassVisitor(cw, annotationClassName);
|
||||
cr.accept(cv, 0);
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
static class AddAnnotationClassVisitor extends ClassVisitor {
|
||||
private final String annotationClassName;
|
||||
|
||||
public AddAnnotationClassVisitor(ClassVisitor cv, String annotationClassName) {
|
||||
super(Opcodes.ASM9, cv);
|
||||
this.annotationClassName = annotationClassName.replace('.', '/');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(
|
||||
int version, int access, String name,
|
||||
String signature, String superName, String[] interfaces) {
|
||||
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
super.visitAnnotation(
|
||||
"L" + annotationClassName + ";",
|
||||
true
|
||||
).visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<AnnotationInfo> getAnnotations(byte[] classBytes) {
|
||||
ClassReader cr = new ClassReader(classBytes);
|
||||
AnnotationCollectingVisitor cv = new AnnotationCollectingVisitor();
|
||||
cr.accept(cv, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||
return cv.getAnnotations();
|
||||
}
|
||||
|
||||
public static class AnnotationInfo {
|
||||
public final String desc;
|
||||
public final Map<String, Object> values = new HashMap<>();
|
||||
|
||||
public AnnotationInfo(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AnnotationCollectingVisitor extends ClassVisitor {
|
||||
|
||||
private final List<AnnotationInfo> annotations = new ArrayList<>();
|
||||
|
||||
public AnnotationCollectingVisitor() {
|
||||
super(Opcodes.ASM9);
|
||||
}
|
||||
|
||||
public List<AnnotationInfo> getAnnotations() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
|
||||
AnnotationInfo info = new AnnotationInfo(descriptor);
|
||||
annotations.add(info);
|
||||
|
||||
return new AnnotationVisitor(Opcodes.ASM9) {
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
info.values.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
List<Object> array = new ArrayList<>();
|
||||
info.values.put(name, array);
|
||||
|
||||
return new AnnotationVisitor(Opcodes.ASM9) {
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
array.add(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.reajason.javaweb.asm;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/12/6
|
||||
*/
|
||||
class ClassAnnotationUtilsTest {
|
||||
@Test
|
||||
@SneakyThrows
|
||||
void test() {
|
||||
String interfaceName = "javax.script.ScriptEngineFactory";
|
||||
byte[] bytes = new ByteBuddy().redefine(ClassInterfaceUtilsTest.EmptyInterface.class).make().getBytes();
|
||||
List<ClassAnnotationUtils.AnnotationInfo> rawAnnotations = ClassAnnotationUtils.getAnnotations(bytes);
|
||||
byte[] newBytes = ClassAnnotationUtils.setAnnotation(bytes, interfaceName);
|
||||
List<ClassAnnotationUtils.AnnotationInfo> annotations = ClassAnnotationUtils.getAnnotations(newBytes);
|
||||
assertEquals(0, rawAnnotations.size());
|
||||
assertEquals(1, annotations.size());
|
||||
assertEquals("Ljavax/script/ScriptEngineFactory;", annotations.get(0).desc);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user