标签: java-bytecode-asm

使用 ASM 的 JVM INVOKESPECIAL 私有构造函数

我正在使用 ASM 生成一些字节码并动态执行它。但在某些情况下,我需要调用私有构造函数,但我不知道如何调用。我知道可以通过反射(setAccessible)调用私有构造函数,但是我如何直接在字节码/jvm中执行此操作?

mv.visitMethodInsn(
        INVOKESPECIAL, target.byteCodeName(), "<init>", "()V", false
    )
Run Code Online (Sandbox Code Playgroud)

当 JVM 执行此代码时,它会抛出 java.lang.IllegalAccessError。

java jvm bytecode java-bytecode-asm jvm-bytecode

3
推荐指数
1
解决办法
953
查看次数

字节码操作/增强和 Java Instrumentation API

我很难理解字节码操作/增强和 Java Instrumentation API 之间的依赖关系。

根据我的理解,要进行任何字节码操作/增强,我们有两种选择

  • 构建时 - Java 类被编译,*.class然后应该执行一些其他库/应用程序来进行操作。
  • 加载时 - 只能使用 Java Instrumentation API,这意味着必须提供特定的 javaagent。

我不确定的事情:

  • 是否有诸如构建时字节码操作之类的东西以及支持该操作的框架/库是什么(例如 Javassist、ASM)它们是否使用某种通用方法或只是读取和解析字节码,然后为您提供修改它的方法?

  • 加载时操作是否仅依赖于 Java Instrumentation API?意味着所有可用的框架/库(例如 Javassist、ASM)都使用 javaagent 来进行操作?

请注意,我对这个主题的经验非常少,因此我有可能误解或错过了一些概念。我试图将这个复杂的主题归结为一些简单的解释,即使它非常笼统或使用类比来演示。

java java-bytecode-asm

3
推荐指数
1
解决办法
523
查看次数

如何使用ASM访问者检查堆栈?

我试图使用Java字节码工程库ASM来执行静态分析.我有这种情况,我想检查分配给字段的变量.

我有MethodVisitor实现该visitFieldInsn()方法.我特意找这个putfield命令.那没问题.问题是,当我遇到时putfield,我希望能够访问将分配给该字段的变量.具体来说,我想访问有关变量类型的信息.

目前我真的只需要查看堆栈顶部的内容,但如果有更通用的方法来检查它,那就更好了.

有没有办法使用ASM来检查堆栈上的变量?

java assembly bytecode java-bytecode-asm

2
推荐指数
1
解决办法
1092
查看次数

Java ASM需要帮助

我使用Java ASM编写一个简单的程序来生成通过编译以下类生成的字节代码.

public class Main {
    public static void main(String[] args) {
        System.out.println("Test");
    }
}
Run Code Online (Sandbox Code Playgroud)

我编写的用于生成此类的字节码的代码如下所示.

public class CodeGenerator {

    public void generateClass()
    {
        ClassWriter cw=new ClassWriter(Opcodes.NULL);
        FieldVisitor fv;
        MethodVisitor mv;
        cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "Main", null, "java/lang/Object", null);
        mv=cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitVarInsn(Opcodes.AALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
        mv=cw.visitMethod(Opcodes.ACC_PUBLIC+ Opcodes.ACC_STATIC, "Main", "([Ljava/lang/String;)V", null, null);
        mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream");
        mv.visitLdcInsn("Test");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
        cw.visitEnd();
        this.WriteClass(cw);
    }
    public void WriteClass(ClassWriter cw){
        FileOutputStream fos; …
Run Code Online (Sandbox Code Playgroud)

java java-bytecode-asm

2
推荐指数
1
解决办法
3793
查看次数

ASM:输出java字节码和操作码

我正在尝试编写一个带有.class文件的程序,并收集.class文件的所有方法以及每个方法的内容.这是我的代码

public class ClassReaderTest1 {

    public static void main(String[] args) throws Exception{
        InputStream in = new FileInputStream("*.class");
        ClassReader reader = new ClassReader(in);
        ClassNode classNode = new ClassNode();
        reader.accept(classNode,0);
        @SuppressWarnings("unchecked")
        final List<MethodNode> methods = classNode.methods;

        for(MethodNode m: methods){
             InsnList inList = m.instructions;
             System.out.println(m.name);
             for(int i = 0; i< inList.size(); i++){
                 System.out.println("     " +     Integer.toHexString(inList.get(i).getOpcode()));
             }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的输出

init>
     ffffffff
     ffffffff
     19
     b7
     b1
     ffffffff
main
     ffffffff
     ffffffff
     b2
     12
     b6
     ffffffff
     ffffffff
     3
     36
     ffffffff
     ffffffff
     b1
     ffffffff
Run Code Online (Sandbox Code Playgroud)

最终我不想打印这些值,我只是希望能够在我的程序中引用它们(我正在尝试检查我是否得到了正确的值).我按预期得到方法,但方法的内容对我没有意义.我认为这些不是操作码; …

java opcode bytecode-manipulation java-bytecode-asm

2
推荐指数
1
解决办法
3657
查看次数

包私有方法似乎没有被覆盖

我使用ASM基于类生成超类ToOverride.我想覆盖它的ToOverride::getValue方法.上面提到的类看起来像:

public abstract class ToOverride {

   Object getValue(String str, Object arg) throws Exception {
     throw new IllegalStateException("PARENT!");
   }

   Object justMethod() {
     return "test";
   }
}
Run Code Online (Sandbox Code Playgroud)

在普通的java中,期望的类看起来像这样:

public class GeneratedInheritor extends ToOverride {
  @Override
  Object getValue(String str, Object arg) throws Exception {
    return str + arg;
  }
}
Run Code Online (Sandbox Code Playgroud)

我生成了后一个类,导致后面的字节码.

// class version 49.0 (49)
// access flags 0x21
public class com/example/GeneratedInheritor extends com/example/ToOverride {

    // access flags 0x1
    public <init>()V
        ALOAD 0
        INVOKESPECIAL com/example/ToOverride.<init> ()V
        RETURN
        MAXSTACK …
Run Code Online (Sandbox Code Playgroud)

java overriding classloader java-bytecode-asm

2
推荐指数
1
解决办法
433
查看次数

如何在ASM中读取最终字符串值?

假设某人给了我以下源代码的Java字节码:

class MyClass {
  public static void foo() {
     final String bar = "Hello";         
  }
}
Run Code Online (Sandbox Code Playgroud)

我想扫描这个类中的所有方法MyClass.如果任何方法包含一个final String被调用的变量bar,我需要输出变量的文字值.在这种情况下,Hello.

我设法得到bar方法中调用的变量如下:

// Scala code
import scala.collection.JavaConversions._
import org.objectweb.asm._
import org.objectweb.asm.tree._

def processClass(is:java.io.InputStream) = {
  val cn = new ClassNode
  val cr = new ClassReader(is)
  cr.accept(cn, 0)
  is.close
  val methods = cn.methods.asInstanceOf[java.util.List[MethodNode]]
  val m = methods(0)  // get first method as an example
  val vars = m.localVariables.asInstanceOf[java.util.List[LocalVariableNode]];
  val bar = vars.find(_.name == "bar").find(v …
Run Code Online (Sandbox Code Playgroud)

java scala bytecode java-bytecode-asm

2
推荐指数
1
解决办法
405
查看次数

AspectJ和ASM有什么区别?

据我了解,这两个框架都是静态的,可将监视代码注入类代码。那么区别是什么呢?

hook aspectj inject java-bytecode-asm

2
推荐指数
1
解决办法
637
查看次数

如何使用ASM 5.2在运行时删除方法体

我正在尝试删除test()以下程序中的方法主体,以便不向控制台打印任何内容.我正在使用ASM 5.2,但我尝试的一切似乎都没有任何影响.

有人可以解释我做错了什么,并指出了一些关于ASM的最新教程或文档吗?我在Stackoverflow和ASM网站上发现的几乎所有内容都显得过时和/或无用.

public class BytecodeMods {

    public static void main(String[] args) throws Exception {
        disableMethod(BytecodeMods.class.getMethod("test"));
        test();
    }

    public static void test() {
        System.out.println("This is a test");
    }

    private static void disableMethod(Method method) {
        new MethodReplacer()
                .visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, method.getName(), Type.getMethodDescriptor(method), null, null);
    }

    public static class MethodReplacer extends ClassVisitor {

        public MethodReplacer() {
            super(Opcodes.ASM5);
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            return null;
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

java bytecode-manipulation java-bytecode-asm

2
推荐指数
1
解决办法
1384
查看次数

ASM从堆栈帧中获取精确值

我有一些方法,其中包含像ILOAD这样的内容,我希望以某种方式在此指令之后获取堆栈的值.不只是打字,而是确切的价值.我知道我需要模拟方法执行才能做到这一点,但我不知道如何正确地做到这一点.
我有这样的测试方法叫main:

sipush          15649
istore_0        /* c */
getstatic       java/lang/System.out:Ljava/io/PrintStream;
bipush          45
bipush          11
iload_0         /* c */
...
Run Code Online (Sandbox Code Playgroud)

我希望得到价值,加载iload_0.我试图制作分析器,然后看到帧值,但它们只包含值的类型,而不是我想要的.

ClassReader cr = new ClassReader(new FileInputStream(new File("input.class")));
ClassNode cn = new ClassNode(Opcodes.ASM5);
cr.accept(cn, 0);

Iterator<MethodNode> methods = cn.methods.iterator();
while (methods.hasNext()) {
    MethodNode mn = methods.next();
    if (!mn.name.equals("main")) continue;
    AbstractInsnNode[] nodes = mn.instructions.toArray();
    Analyzer analyzer = new Analyzer(new BasicInterpreter());
    analyzer.analyze(cn.name, mn);
    int i = -1;
    for (Frame frame : analyzer.getFrames()) {
        i++;
        if (frame == null) continue; …
Run Code Online (Sandbox Code Playgroud)

java bytecode java-bytecode-asm

2
推荐指数
1
解决办法
654
查看次数