标签: java-bytecode-asm

双值和长值的Java字节码交换?

我正在开发一个带有 ASM 的 Java 检测引擎,有一种情况是评估堆栈在顶部有一个特定的,我想在现有之前插入一个ref(这是getstatic的结果)。即考虑只有一个的堆栈: ,然后在getstatic 之后我希望堆栈变成这样:。value ->ref, value ->

要执行此行为,我必须插入以下字节码:getsaticswap。使用 ASM 我会做类似的事情(考虑mv类型MethodVisitor):

mv.visitFieldInsn(Opcodes.GETSTATIC, ...);
mv.visitInsn(Opcodes.SWAP);
Run Code Online (Sandbox Code Playgroud)

问题是交换字节码不支持longdouble值。所以上面的代码适用于单个单词类型,但它不适用于longdouble类型。

是否有任何简单的解决方案可以解决longdouble类型的问题并且不需要辅助本地值?

java jvm java-bytecode-asm

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

Java ASM4:super(ASM4);?

好吧,我正在阅读ASM4字节码库中的PDF教程/文档/书籍(如果你愿意的话).我正在尝试这些例子并通过阅读,实际输入代码,执行,然后从输出中学习来学习.我遇到了这个部分:

   public class ClassPrinter extends ClassVisitor {
      public ClassPrinter() {
      super(ASM4);
   }
Run Code Online (Sandbox Code Playgroud)

链接在这里: http://download.forge.objectweb.org/asm/asm4-guide.pdf

我无法弄清楚在超级中传递什么.我的IDE也不是很有帮助.

java bytecode bytecode-manipulation java-bytecode-asm

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

为什么 ASM 无法找出适合我的生成类的正确最大值?

我正在使用 ASM 3.1 生成一个虚拟类。它只有一个简单的构造函数,没有其他方法:

public class TestAsm {

public static void main(String... args) throws Throwable {
    ClassWriter sw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    sw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, "test/SubCls", null, "test/SuperCls", null);
    sw.visitField(Opcodes.ACC_PUBLIC, "i", "I", null, null);

    MethodVisitor mv = sw.visitMethod(0, "<init>", "()V", null, null);
    // mv.visitMaxs(2, 1);
    mv.visitCode();
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "test/SuperCls", "<init>", "()V");
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitInsn(Opcodes.ICONST_2);
    mv.visitFieldInsn(Opcodes.PUTFIELD, "test/SubCls", "i", "I");
    mv.visitInsn(Opcodes.RETURN);
    mv.visitEnd();

    sw.visitEnd();
    byte[] cls = sw.toByteArray();
    FileOutputStream fos = new FileOutputStream("bin/test/SubCls.class");
    fos.write(cls);
    fos.close();

    SuperCls o = (SuperCls) Class.forName("test.SubCls").newInstance(); …
Run Code Online (Sandbox Code Playgroud)

java bytecode java-bytecode-asm

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

使用ASM跟踪字节码中的方法调用参数

如何检查类的字节码(使用诸如ASM之类的东西)来了解哪些初始值传递给方法?

例如:给定一些将值互相传递的方法:

void m1(Object o) {
  Object v = o;
  m2(v);
  m2("box");
}

void m2(Object o) {
  Object v = o;
  m3(x);
}  

void m3(Object o) {
}
Run Code Online (Sandbox Code Playgroud)

还有一些方法调用,都在同一个类中定义:

{
  Object foo = "foo";
  m1(foo);
  m2("bar");
  m3("baz");
}
Run Code Online (Sandbox Code Playgroud)

我怎么可以检查类的字节码得知m3将与值被称为4倍"foo","box","bar""baz"

java bytecode-manipulation java-bytecode-asm

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

JVM验证错误'常量池中的非法类型'

我目前正在编写自己的编译器,我正在尝试编译以下代码:

List[String] list = List("a", "b", "c", "d")
list stream map((String s) => s.toUpperCase())
System out println list
Run Code Online (Sandbox Code Playgroud)

编译器解析,链接或编译代码没有问题,但是当执行它时,JVM会抛出以下错误:

java.lang.VerifyError: Illegal type at constant pool entry 40 in class dyvil.test.Main
Exception Details:
  Location:
    dyvil/test/Main.main([Ljava/lang/String;)V @29: invokevirtual
  Reason:
    Constant pool index 40 is invalid
  Bytecode:
    ...
Run Code Online (Sandbox Code Playgroud)

我试图用来javap找到问题,这是指令@29:

29: invokevirtual #40 // InterfaceMethod java/util/Collection.stream:()Ljava/util/stream/Stream;
Run Code Online (Sandbox Code Playgroud)

并且常量池中的条目(也使用javap):

#37 = Utf8               stream
#38 = Utf8               ()Ljava/util/stream/Stream;
#39 = NameAndType        #37:#38 // stream:()Ljava/util/stream/Stream;
#40 = InterfaceMethodref #36.#39 // java/util/Collection.stream:()Ljava/util/stream/Stream;
Run Code Online (Sandbox Code Playgroud)

使用Eclipse类文件查看器打开类时, …

java jvm java-bytecode-asm

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

如何使用 ASM 扫描字段和方法注释?

使用ASM 5.0.4,我试图找到具有特定注释的类的字段和方法。我喜欢避免加载类而不用担心依赖关系。到目前为止,我无法弄清楚如何使用这种方法获取字段/方法注释:

class AnnotationScanner extends ClassVisitor{

    public AnnotationVisitor visitAnnotation(String desc, boolean visible){
        System.out.println("visitAnnotation: desc="+desc+" visible="+visible);
        return super.visitAnnotation(desc,visible);
    }

    public void visitAttribute(Attribute attr){
        System.out.println("visitAttribute: attr="+attr);
        super.visitAttribute(attr);
    }

    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value){
        System.out.println("visitField: access="+access+" name="+name+" desc="+desc+" signature="+signature+" value="+value);
        return super.visitField(access,name,desc,signature,value);
    }

    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions){
        System.out.println("visitMethod: access="+access+" name="+name+" desc="+desc+" signature="+signature+" exceptions="+exceptions);
        return super.visitMethod(access,name,desc,signature,exceptions);
    }

    public static void main(String[] args) throws Exception{
        for (String arg : …
Run Code Online (Sandbox Code Playgroud)

java java-bytecode-asm

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

使用ASM选择和修改`if`语句

我想if在特定行上更新现有类中的语句而不更改整个方法.

这是目标代码(类,方法和一些代码的名称已更改,因为它们不相关):

public class Target extends Something {
   public Target(){
        super();
        //some code...
   }

    public Result targetMethod(Data firstPar, Data secondPar){
        if(someStatement()) {
            return Result.FAIL;
        } else {
            if(firstPar.check()){ //here is the line I want to change
                 firstPar.doSomething()
            }
            secondPar.doSomething();
            return Result.SUCCESS;
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

在这段代码中我想改成if(firstPar.check())这样的东西:

if(firstPar.check() && !Utilities.someOtherCheck(firstPar, secondPar))
Run Code Online (Sandbox Code Playgroud)

这是我试图解决这个问题的方法:

ClassNode node = new ClassNode();
ClassReader reader = new ClassReader(bytes); //bytes - original target class
reader.accept(node, 0);
ClassWriter cw = new ClassWriter(0);
node.accept(cw);
MethodVisitor visitor = …
Run Code Online (Sandbox Code Playgroud)

java bytecode-manipulation java-bytecode-asm

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

ASM的问题getMergedType和getCommonSuperClass

我使用ASM更新类堆栈映射,但是当asm时getMergedType,发生以下异常:

java.lang.RuntimeException:
java.io.IOException:找不到IntefaceImplA的资源。

如果在没有asm的情况下修改class方法,则效果很好。
我定义了两个接口A和B:IntefaceImplAIntefaceImplB

我的环境源代码:

IntefaceA.java

public interface IntefaceA {
    void inteface();
}
Run Code Online (Sandbox Code Playgroud)

IntefaceImplA.java

public class IntefaceImplA implements IntefaceA {
@Override
public void inteface() {

}
}
Run Code Online (Sandbox Code Playgroud)

IntefaceImplB.java

public class IntefaceImplB implements IntefaceA {
@Override
public void inteface() {

}
}
Run Code Online (Sandbox Code Playgroud)

Test.java

public class Test {
public IntefaceA getImpl(boolean b) {
    IntefaceA a = b ? new IntefaceImplA() : new IntefaceImplB();
    return a;
}
Run Code Online (Sandbox Code Playgroud)

}

Main.java

public class Main {
public static void …
Run Code Online (Sandbox Code Playgroud)

java java-bytecode-asm spring-boot

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

有什么办法可以从字节码中重新生成堆栈图?

我有一个旧库(大约 2005 年),它执行字节码操作,但不涉及堆栈图。因此,我的 jvm (java 8) 抱怨它们是无效的类。规避错误的唯一方法是使用-noverify. 但这对我来说不是一个长期的解决方案。

在类已经生成之后,有什么办法可以重新生成堆栈映射吗?我看到ClassWriter该类有一个选项来重新生成堆栈映射,但我不确定如何读取字节类并重写一个新的。那可行吗?

java bytecode bytecode-manipulation java-bytecode-asm

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

#invokevirtual之后做什么

例如,如果将int变量a和b存储在局部变量1和2中,则此代码将进行计算this.f(3+b*a)。(此指针存储在变量0中)

iload_1
aload_0
icons_3
iload_1
iload_1
imul
iadd
invokevirtual #4
Run Code Online (Sandbox Code Playgroud)

#4站在这里代表什么?

java-bytecode-asm invokevirtual

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