标签: java-bytecode-asm

是否可以在运行时指定System ClassLoader加载.class文件?

我正在编写一个用于赋值的静态分析工具,它使用ASM库分析Java字节码.我们使用的ASM的一个部分需要(或者至少似乎要求)从ClassLoader加载该类.

我们希望该工具能够分析.class文件,而不需要它们在类路径上.我们已经在运行时从指定目录加载.classes并使用InputStream读取它们.在大多数情况下,这对于ASM是可接受的.有些类,例如SimpleVerifier,尝试加载类.

在这种情况下,是否可以注册要加载的.class文件,以便调用Class.forName()将加载它们?或者是否有一种简单的方法来扩展ClassLoader以允许它?


编辑:URLClassLoader有用的信息.不幸的是,使用Thread.currentThread().setContextClassLoader()它的实例在这种情况下不起作用.我正在调用的库代码使用它在实例初始化时检索的加载器getClass().getClassLoader().

当我设置URLClassLoader时,该类尚未初始化,所以我猜contextClassLoader不加载该类.

我是否正确理解了答案?是否可以使用URLClassLoader加载第三方类?

java bytecode classpath classloader java-bytecode-asm

5
推荐指数
2
解决办法
9263
查看次数

字节代码检测 - 实现本机代理还是java代理?

如果我想使用字节码检测实现分析器,我应该使用JVMTI编写本机代理还是应该使用该包编写java代理java.lang.instrument

如果我想使用像ASM这样的库- 如果你想创建一个严肃的探查器似乎是强制性的 - 我必须使用java代理.这使我感到困惑,因为我认为本机代理可以完成Java代理可以做的所有事情.但对我来说,编写java代理似乎更容易.

还有替代品吗?是否应该使用java代理和本地代理组合?

bytecode-manipulation jvmti java-bytecode-asm

5
推荐指数
1
解决办法
1733
查看次数

使用Java中的ASM监视对象创建

我正在使用ASM来监视Java中的对象创建.目前,我将调用init作为创建新对象的指示器并从中调整程序

invoke XXX.init
Run Code Online (Sandbox Code Playgroud)

dup;  
invoke XXX.init;  
call_my_method(Object)
Run Code Online (Sandbox Code Playgroud)

我的想法是复制newObjectReference的副本,并且在此对象的init之后,我调用我的方法来保留此对象.

但是,在运行时期间,有一个例外:

java.lang.VerifyError, Expecting to find unitialized object on stack.
Run Code Online (Sandbox Code Playgroud)

当我使用"-noverify"选项时,在运行时,如果有一个线程实例,则抛出第二个异常:

Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at test.ThreadTest.test
Run Code Online (Sandbox Code Playgroud)

对于第二种情况,我确信除了原始程序之外,没有调用线程的start().

有没有更好的方法来监控新对象的创建?

非常感谢.

java instrumentation java-bytecode-asm

5
推荐指数
1
解决办法
709
查看次数

Dalvik 字节码中的“抛出”和“异常注释”

为什么字节码生成为

 .annotation system Ldalvik/annotation/Throws;
        value = {
            Ljava/io/FileNotFoundException;
        }
 .end annotation
Run Code Online (Sandbox Code Playgroud)

而不是.throws Ljava/io/FileNotFoundException

throws FileNotFoundException如果一个方法在java代码的标头中声明?

android dalvik jasmin java-bytecode-asm jvm-bytecode

5
推荐指数
1
解决办法
807
查看次数

可以在编译时操作JVM字节码吗?

是否可以在编译时使用像ASM这样的字节码操作库?

具体来说,我想使用Java的注释处理API在带注释的类上实现样板重的方法.实现注释处理器很简单,但运行时似乎.class文件尚不存在Processor.还有另外一种方法吗?

java bytecode compilation java-bytecode-asm

5
推荐指数
1
解决办法
1455
查看次数

方法代码太大!使用 ASM 的异常

我正在使用 ASM 代码迭代一个类而不操作任何字节代码。但是当我将 classwriter 转换为 bytearray(cw.toByteArray()) 时,我得到的方法代码太大了!例外。

谁能告诉我这是什么时候发生的..

我的代码片段如下---

InputStream in= new FileInputStream("D:/AshiqWorkspace/RandD/ByteCodeStudy/temp/GameManager.class");
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS|ClassWriter.COMPUTE_FRAMES);
ClassVisitor ca = null;
ca = new CustomClassNode(cw);  // CustomClassNode class extends ClassNode implements Opcodes
cr.accept(ca, 0);   
File outputDir=new File("D:/AshiqWorkspace/RandD/ByteCodeStudy/out");
outputDir.mkdirs();
DataOutputStream dout=new DataOutputStream(new FileOutputStream(new File(outputDir,"GameManager.class")));
dout.write(cw.toByteArray()); // on this line "method code too large exception coming"
Run Code Online (Sandbox Code Playgroud)

java java-bytecode-asm

5
推荐指数
1
解决办法
2641
查看次数

在 try-finally 块中嵌入方法的现有代码 (2)

前段时间,我在将方法的现有代码嵌入 try-finally 块中询问如何使用 ASM 将方法的主体包装在 try-finally 块中。解决方案是访问 in 方法体开头的 try 块的标签,visitCode()并在访问具有返回操作码 in 的指令时完成 try-finally 块visitInsn()。我知道如果一个方法没有返回指令,则该解决方案将不起作用,如果该方法总是以异常情况离开则适用。

不过,我发现前一种解决方案有时也不适用于带有返回指令的方法。如果一个方法有多个返回指令,它将不起作用。原因是它生成了无效的字节码,因为在方法的开头添加了一个 try-finally 块,但完成了不止一个 try-finally 块。

通常(但可能取决于 javac 编译器),字节码方法包含单个返回指令,并且所有返回路径通过跳转到该指令结束。但是,使用 Eclipse 编译以下代码将导致带有两个返回指令的字节码:

public boolean isEven(int x) {
  return x % 2 == 0;
}
Run Code Online (Sandbox Code Playgroud)

用Eclipse编译的字节码:

   0: iload_1
   1: iconst_2
   2: irem
   3: ifne          8
   6: iconst_1
   7: ireturn       // javac compilation: goto 9
   8: iconst_0
   9: ireturn
Run Code Online (Sandbox Code Playgroud)

因此,我想知道包装方法代码的整个代码的正确方法是什么。

java instrumentation bytecode bytecode-manipulation java-bytecode-asm

5
推荐指数
1
解决办法
1122
查看次数

ifeq / ifne JVM操作码总是分支

[TL; DR:以下JVM字节码指令似乎不起作用:

iconst_0
istore 6
...sequential
iinc 6 1
jsr L42
...
; L42
iload 6
ifeq L53 ; Always branches!!!
astore 8
iinc 6 -1
; L53
LDC 100
ISUB     ; ERROR, returnAddress is at the top of the stack
Run Code Online (Sandbox Code Playgroud)

可以在此处找到测试.class (具有稍微复杂的逻辑)。如果您想进一步了解为什么我会看到这些说明,请继续阅读。]

我正在编写针对JVM字节码的Whitespace编译器。尽管是一种深奥的语言,但是Whitespace向堆栈计算机描述了一组有趣的汇编指令,该堆栈计算机很好地映射到了JVM。

空格具有标签,它们都是跳转(goto / jump-if-zero / jump-if-negative)和函数调用的目标。相关说明(由我给定的名称,在规范中以空格,制表符和换行符的组合形式给出)为:

  • mark <label>:为以下说明设置标签
  • jump[-if-neg|-if-zero] <label>:无条件或有条件地跳转到给定标签
  • call <label>:调用标签所指向的函数
  • end <label>:结束功能,返回到调用方。

我的编译器以类的main方法输出整个Whitespace程序。实现call和的最简单方法end是使用JSRRET操作码,用于实现子例程。JSR操作完成后,堆栈将包含一个returnAddress引用,该引用应存储在变量中,以供以后在中使用end

但是,mark …

java jvm java-bytecode-asm whitespace-language

5
推荐指数
1
解决办法
1120
查看次数

如何在Java中加载修改后的超类?

  • 我的班级A延伸到B。
  • 我创建了一个CustomClassLoader,扩展了ClassLoader来使用defineClass(className, byte[], offset, length)
  • 我已经实例化了new CustomClassLoader(Thread.currentThread().getContextClassLoader())。因此,CustomClassLoader的父级是当前线程中的ClassLoader。
  • 我已经使用ASM框架修改了B类。我已经在.class文件中编写了修改后的类,并使用反编译器来确保它可以工作。而且有效。
  • 我已将修改后的B类添加到CustomClassLoader中
  • 我已经Thread.currentThread().setContextClassLoader()用CustomClassLoader 设置了。
  • 我使用过负载A Class.forName(String, true, the CustomClassLoader)
  • 但是加载的B类似乎是原始类。

我怎么了?如果您需要更多信息,请在我的GitHub上找到详细的主题。

java classloader superclass java-bytecode-asm

5
推荐指数
1
解决办法
304
查看次数

jvm dup 指令的使用案例

Java字节码指令集提供了多种形式的dup指令。我无法理解这些说明和swap说明如何有用。编译时,哪些 Java 代码会使用这些指令生成字节码?

java jvm bytecode java-bytecode-asm

5
推荐指数
1
解决办法
989
查看次数