Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用ASM欺骗HelloWorld.scala?已加载到JVM但未找到?_Java_Scala_Classloader_Java Bytecode Asm - Fatal编程技术网

Java 如何使用ASM欺骗HelloWorld.scala?已加载到JVM但未找到?

Java 如何使用ASM欺骗HelloWorld.scala?已加载到JVM但未找到?,java,scala,classloader,java-bytecode-asm,Java,Scala,Classloader,Java Bytecode Asm,我使用自定义类加载器将ASM与java结合使用,但在scala中做同样的事情有困难。首选的方法是什么 一个HelloScala.scala编译成两个类(HelloScala.class和HelloScala$.class)。我是否需要为这两种代码伪造字节码 我的代码似乎只塞进了一个HelloScala$.class,但没有公共构造函数或方法。我可以使用反射API和构造函数来访问,但有两个问题: 通过忽略HelloScala.class,我是否遗漏了任何有价值的东西 这是危险的还是难闻的 “正确”

我使用自定义类加载器将ASM与java结合使用,但在scala中做同样的事情有困难。首选的方法是什么

一个
HelloScala.scala
编译成两个类(
HelloScala.class
HelloScala$.class
)。我是否需要为这两种代码伪造字节码

我的代码似乎只塞进了一个HelloScala$.class,但没有公共构造函数或方法。我可以使用反射API和构造函数来访问,但有两个问题:

  • 通过忽略
    HelloScala.class
    ,我是否遗漏了任何有价值的东西
  • 这是危险的还是难闻的
  • “正确”的方法可能是调用
    HelloScala
    中的公共静态
    main
    ,但我得到了以下错误:

    [Loaded HelloScala from __JVM_DefineClass__]
    [Loaded scala.ScalaObject from file:/home/julianpeeters/asm-scala-example/lib/scala-library-2.9.1.jar]
    [Loaded HelloScala$ from __JVM_DefineClass__]
    [Loaded sun.reflect.NativeMethodAccessorImpl from /usr/lib/jvm/java-6-openjdk/jre/lib/rt.jar]
    [Loaded sun.reflect.DelegatingMethodAccessorImpl from /usr/lib/jvm/java-6-openjdk/jre/lib/rt.jar]
    [Loaded java.lang.reflect.InvocationTargetException from /usr/lib/jvm/java-6-openjdk/jre/lib/rt.jar]
    Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at HelloScalaDump.main(HelloScalaDump.java:41)
    Caused by: java.lang.NoClassDefFoundError: HelloScala$
        at HelloScala.main(Unknown Source)
        ... 5 more
    Caused by: java.lang.ClassNotFoundException: HelloScala$
        at java.lang.ClassLoader.findClass(ClassLoader.java:373)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
        ... 6 more
    
    似乎正在加载
    HelloScala$
    ,为什么找不到它


    谢谢

    Scala使用许多技巧将其语义映射到JVM。因此,您将在字节码级别看到许多意想不到的事情。我认为您必须了解scala编译器如何使用Java结构


    类由其名称和加载该类的类加载器(调用define方法的加载器)标识。您确定加载HelloScala的加载程序实际上也加载了HelloScala$吗?

    Scala使用了很多技巧将其语义映射到JVM。因此,您将在字节码级别看到许多意想不到的事情。我认为您必须了解scala编译器如何使用Java结构


    类由其名称和加载该类的类加载器(调用define方法的加载器)标识。你确定加载HelloScala的加载程序实际上也加载了HelloScala$吗?

    这对我来说很有效,在每个类的“dump”文件中调用
    dump()
    方法来加载带有上下文的类加载程序而不是自定义类加载程序的类(因此,伪造的类可以访问与项目其余部分相同的类路径):

    import java.lang.reflect.*;
    公共类转储加载程序{
    公共静态void main(字符串[]args)引发异常{
    类c$=loadClass(“HelloScala$”,HelloScala$Dump.Dump());//首先加载“匿名”类
    类c=loadClass(“HelloScala”,HelloScalDump.dump());//然后加载“real”类
    试一试{
    Method mainMethod=c.getMethod(“main”,String[].class);//获取“real”类的main方法
    invoke(null,(Object)新字符串[]{});//并调用它来运行伪造的程序
    }捕获(例外e){
    e、 printStackTrace();
    系统出口(1);
    }
    }
    私有静态类loadClass(字符串类名,字节[]b){
    //重写classDefine(因为它是受保护的)并定义类。
    类clazz=null;
    试一试{
    //ClassLoader=ClassLoader.getSystemClassLoader();
    ClassLoader=Thread.currentThread().getContextClassLoader();
    Class cls=Class.forName(“java.lang.ClassLoader”);
    方法Method=cls.getDeclaredMethod(“defineClass”,新类[]{String.Class,字节[].Class,int.Class,int.Class});
    //受保护的方法invocaton
    方法setAccessible(true);
    试一试{
    Object[]args=new Object[]{className,b,新整数(0),新整数(b.length)};
    clazz=(类)方法.invoke(装入器,参数);
    }最后{
    方法.setAccessible(false);
    }
    }捕获(例外e){
    e、 printStackTrace();
    系统出口(1);
    }
    回击声;
    }
    }
    
    这对我来说很有效,在每个类的“dump”文件中调用
    dump()
    方法来加载带有上下文类加载器的类,而不是自定义类加载器的类(因此受欺骗的类可以访问与项目其余部分相同的类路径):

    import java.lang.reflect.*;
    公共类转储加载程序{
    公共静态void main(字符串[]args)引发异常{
    类c$=loadClass(“HelloScala$”,HelloScala$Dump.Dump());//首先加载“匿名”类
    类c=loadClass(“HelloScala”,HelloScalDump.dump());//然后加载“real”类
    试一试{
    Method mainMethod=c.getMethod(“main”,String[].class);//获取“real”类的main方法
    invoke(null,(Object)新字符串[]{});//并调用它来运行伪造的程序
    }捕获(例外e){
    e、 printStackTrace();
    系统出口(1);
    }
    }
    私有静态类loadClass(字符串类名,字节[]b){
    //重写classDefine(因为它是受保护的)并定义类。
    类clazz=null;
    试一试{
    //ClassLoader=ClassLoader.getSystemClassLoader();
    ClassLoader=Thread.currentThread().getContextClassLoader();
    Class cls=Class.forName(“java.lang.ClassLoader”);
    方法Method=cls.getDeclaredMethod(“defineClass”,新类[]{String.Class,字节[].Class,int.Class,int.Class});
    //受保护的方法invocaton
    方法setAccessible(true);
    试一试{
    Object[]args=new Object[]{className,b,新整数(0),新整数(b.length)};
    clazz=(类)方法.invoke(装入器,参数);
    }最后{
    方法.setAccessible(false);
    }
    }捕获(例外e){
    e、 printStackTrace();
    系统出口(1);
    }
    回击声;
    }
    }
    
    “您确定加载HelloScala的加载程序也加载了HelloScala$吗?”“您确定加载HelloScala的加载程序也加载了HelloScala$吗?”--我有两个不同的DynamicClassLoader类实例。这两个类似乎都已加载(请参见答案中错误消息的前3行)。类是否需要由同一实例加载?使用
    DynamicClassLoader
    的同一实例加载两个类在某种程度上是有效的。。。然后从
    scala库中找不到
    scalaObject
    import java.lang.reflect.*;
    
    public class DumpLoader {
    
      public static void main(String[] args) throws Exception {
         Class<?> c$ = loadClass("HelloScala$", HelloScala$Dump.dump()); //First load the "anonymous" class
         Class<?> c = loadClass("HelloScala", HelloScalaDump.dump());   //Then load the "real" class
         try {
           Method mainMethod = c.getMethod("main", String[].class);  //Get the main method of the "real" class
           mainMethod.invoke(null, (Object) new String[]{});        //and invoke it to run the spoofed program
         } catch (Exception e) {
          e.printStackTrace();
          System.exit(1);
         }
      }
    
      private static Class loadClass(String className, byte[] b) {
        //override classDefine (as it is protected) and define the class.
        Class<?> clazz = null;
        try {
         // ClassLoader loader = ClassLoader.getSystemClassLoader();
          ClassLoader loader = Thread.currentThread().getContextClassLoader();
          Class<?> cls = Class.forName("java.lang.ClassLoader");
          Method method = cls.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class, int.class });
    
          // protected method invocaton
          method.setAccessible(true);
          try {
            Object[] args = new Object[] { className, b, new Integer(0), new Integer(b.length)};
            clazz = (Class) method.invoke(loader, args);
          } finally {
            method.setAccessible(false);
          }
        } catch (Exception e) {
          e.printStackTrace();
          System.exit(1);
        }
        return clazz;
      }
    
    }