mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
feat: support scriptEngineJar packer
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
package com.reajason.javaweb.asm;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/11/16
|
||||
*/
|
||||
public class ClassInterfaceUtils {
|
||||
|
||||
public static byte[] addInterface(byte[] bytes, String interfaceName) {
|
||||
ClassReader cr = new ClassReader(bytes);
|
||||
ClassWriter cw = new ClassWriter(cr, 0);
|
||||
ClassVisitor cv = new AddInterfaceClassAdapter(cw, interfaceName.replace('.', '/'));
|
||||
cr.accept(cv, 0);
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
static class AddInterfaceClassAdapter extends ClassVisitor {
|
||||
|
||||
private final String interfaceToAdd;
|
||||
|
||||
public AddInterfaceClassAdapter(ClassVisitor cv, String interfaceToAdd) {
|
||||
super(Opcodes.ASM9, cv);
|
||||
this.interfaceToAdd = interfaceToAdd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name,
|
||||
String signature, String superName, String[] interfaces) {
|
||||
for (String itf : interfaces) {
|
||||
if (itf.equals(interfaceToAdd)) {
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
return;
|
||||
}
|
||||
}
|
||||
String[] newInterfaces = new String[interfaces.length + 1];
|
||||
System.arraycopy(interfaces, 0, newInterfaces, 0, interfaces.length);
|
||||
newInterfaces[interfaces.length] = interfaceToAdd;
|
||||
super.visit(version, access, name, signature, superName, newInterfaces);
|
||||
}
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
package com.reajason.javaweb.asm;
|
||||
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author ReaJason
|
||||
* @since 2025/11/16
|
||||
*/
|
||||
class ClassInterfaceUtilsTest {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
String interfaceName = "javax.script.ScriptEngineFactory";
|
||||
byte[] bytes = new ByteBuddy().redefine(EmptyInterface.class).make().getBytes();
|
||||
byte[] newBytes = ClassInterfaceUtils.addInterface(bytes, interfaceName);
|
||||
String[] interfaces = new ClassReader(newBytes).getInterfaces();
|
||||
assertEquals(1, interfaces.length);
|
||||
assertEquals(interfaceName.replace(".", "/"), interfaces[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void skipAdd(){
|
||||
String interfaceName = "javax.script.ScriptEngineFactory";
|
||||
byte[] bytes = new ByteBuddy().redefine(ScriptEngineFactoryClass.class).make().getBytes();
|
||||
byte[] newBytes = ClassInterfaceUtils.addInterface(bytes, interfaceName);
|
||||
String[] interfaces = new ClassReader(newBytes).getInterfaces();
|
||||
assertEquals(1, interfaces.length);
|
||||
assertEquals(interfaceName.replace(".", "/"), interfaces[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void addNewInterface(){
|
||||
String interfaceName = "javax.script.ScriptEngineFactory";
|
||||
byte[] bytes = new ByteBuddy().redefine(Entity.class).make().getBytes();
|
||||
byte[] newBytes = ClassInterfaceUtils.addInterface(bytes, interfaceName);
|
||||
String[] interfaces = new ClassReader(newBytes).getInterfaces();
|
||||
assertEquals(2, interfaces.length);
|
||||
assertEquals("java/io/Serializable", interfaces[0]);
|
||||
assertEquals(interfaceName.replace(".", "/"), interfaces[1]);
|
||||
}
|
||||
|
||||
static class EmptyInterface {
|
||||
}
|
||||
|
||||
static class ScriptEngineFactoryClass implements ScriptEngineFactory {
|
||||
@Override
|
||||
public String getEngineName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEngineVersion() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getExtensions() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMimeTypes() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNames() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLanguageName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLanguageVersion() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getParameter(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodCallSyntax(String obj, String m, String... args) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutputStatement(String toDisplay) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProgram(String... statements) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class Entity implements Serializable {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user