Guest User

Untitled

a guest
Apr 19th, 2025
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.35 KB | None | 0 0
  1. package bot.inker.security.asm;
  2.  
  3. import org.objectweb.asm.ClassReader;
  4. import org.objectweb.asm.ClassWriter;
  5. import org.objectweb.asm.Opcodes;
  6.  
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11.  
  12. public final class WithClassLoaderClassWriter extends ClassWriter {
  13.   private final ClassLoader classLoader;
  14.   private final List<String> missingClasses = new ArrayList<>();
  15.  
  16.   public WithClassLoaderClassWriter(int flags) {
  17.     super(flags);
  18.     this.classLoader = ClassLoader.getSystemClassLoader();
  19.   }
  20.  
  21.   public WithClassLoaderClassWriter(ClassLoader classLoader, int flags) {
  22.     super(flags);
  23.     this.classLoader = classLoader;
  24.   }
  25.  
  26.   public WithClassLoaderClassWriter(ClassLoader classLoader, ClassReader classReader, int flags) {
  27.     super(classReader, flags);
  28.     this.classLoader = classLoader;
  29.   }
  30.  
  31.   @Override
  32.   protected String getCommonSuperClass(String type1, String type2) {
  33.     try {
  34.       ClassInfo info1 = typeInfo(type1);
  35.       ClassInfo info2 = typeInfo(type2);
  36.       if ((info1.access() & Opcodes.ACC_INTERFACE) != 0) {
  37.         if (typeImplements(type2, info2, type1)) {
  38.           return type1;
  39.         } else {
  40.           return "java/lang/Object";
  41.         }
  42.       }
  43.       if ((info2.access() & Opcodes.ACC_INTERFACE) != 0) {
  44.         if (typeImplements(type1, info1, type2)) {
  45.           return type2;
  46.         } else {
  47.           return "java/lang/Object";
  48.         }
  49.       }
  50.       StringBuilder b1 = typeAncestors(type1, info1);
  51.       StringBuilder b2 = typeAncestors(type2, info2);
  52.       String result = "java/lang/Object";
  53.       int end1 = b1.length();
  54.       int end2 = b2.length();
  55.       while (true) {
  56.         int start1 = b1.lastIndexOf(";", end1 - 1);
  57.         int start2 = b2.lastIndexOf(";", end2 - 1);
  58.         if (start1 != -1 && start2 != -1
  59.           && end1 - start1 == end2 - start2) {
  60.           String p1 = b1.substring(start1 + 1, end1);
  61.           String p2 = b2.substring(start2 + 1, end2);
  62.           if (p1.equals(p2)) {
  63.             result = p1;
  64.             end1 = start1;
  65.             end2 = start2;
  66.           } else {
  67.             return result;
  68.           }
  69.         } else {
  70.           return result;
  71.         }
  72.       }
  73.     } catch (IOException e) {
  74.       throw new RuntimeException(e.toString());
  75.     }
  76.   }
  77.  
  78.   private StringBuilder typeAncestors(String type, ClassInfo info)
  79.     throws IOException {
  80.     StringBuilder b = new StringBuilder();
  81.     while (!"java/lang/Object".equals(type)) {
  82.       b.append(';').append(type);
  83.       type = info.superName();
  84.       info = typeInfo(type);
  85.     }
  86.     return b;
  87.   }
  88.  
  89.   private boolean typeImplements(String type, ClassInfo info, String itf)
  90.     throws IOException {
  91.     while (!"java/lang/Object".equals(type)) {
  92.       String[] itfs = info.interfaces();
  93.       for (String it : itfs) {
  94.         if (it.equals(itf)) {
  95.           return true;
  96.         }
  97.       }
  98.       for (String it : itfs) {
  99.         if (typeImplements(it, typeInfo(it), itf)) {
  100.           return true;
  101.         }
  102.       }
  103.       type = info.superName();
  104.       info = typeInfo(type);
  105.     }
  106.     return false;
  107.   }
  108.  
  109.   private ClassInfo typeInfo(final String type) throws IOException {
  110.     try (InputStream in = getClassLoader().getResourceAsStream(type + ".class")) {
  111.       if (in == null) {
  112.         try {
  113.           Class<?> clazz = Class.forName(type.replace('/', '.'), false, getClassLoader());
  114.           return new ClassInfoClassInstance(clazz);
  115.         } catch (ClassNotFoundException e) {
  116.           throw new TypeNotPresentException(type, new IOException("Resource not found: " + type + ".class"));
  117.         }
  118.       }
  119.       return new ClassInfoClassReader(new ClassReader(in));
  120.     }
  121.   }
  122.  
  123.   @Override
  124.   protected ClassLoader getClassLoader() {
  125.     return classLoader;
  126.   }
  127.  
  128.   public interface ClassInfo {
  129.     int access();
  130.  
  131.     String name();
  132.  
  133.     String superName();
  134.  
  135.     String[] interfaces();
  136.   }
  137.  
  138.   public static class ClassInfoClassReader implements ClassInfo {
  139.     private final ClassReader classReader;
  140.  
  141.     public ClassInfoClassReader(ClassReader classReader) {
  142.       this.classReader = classReader;
  143.     }
  144.  
  145.     @Override
  146.     public int access() {
  147.       return classReader.getAccess();
  148.     }
  149.  
  150.     @Override
  151.     public String name() {
  152.       return classReader.getClassName();
  153.     }
  154.  
  155.     @Override
  156.     public String superName() {
  157.       return classReader.getSuperName();
  158.     }
  159.  
  160.     @Override
  161.     public String[] interfaces() {
  162.       return classReader.getInterfaces();
  163.     }
  164.   }
  165.  
  166.   public static class ClassInfoClassInstance implements ClassInfo {
  167.     private final Class<?> clazz;
  168.  
  169.     public ClassInfoClassInstance(Class<?> clazz) {
  170.       this.clazz = clazz;
  171.     }
  172.  
  173.     @Override
  174.     public int access() {
  175.       return clazz.getModifiers();
  176.     }
  177.  
  178.     @Override
  179.     public String name() {
  180.       return clazz.getName().replace('.', '/');
  181.     }
  182.  
  183.     @Override
  184.     public String superName() {
  185.       return clazz == Object.class ? null : clazz.getSuperclass().getName().replace('.', '/');
  186.     }
  187.  
  188.     public String[] interfaces() {
  189.       Class<?>[] interfaces = clazz.getInterfaces();
  190.       String[] result = new String[interfaces.length];
  191.       for (int i = 0; i < interfaces.length; i++) {
  192.         result[i] = interfaces[i].getName().replace('.', '/');
  193.       }
  194.       return result;
  195.     }
  196.   }
  197. }
  198.  
Advertisement
Add Comment
Please, Sign In to add comment