Tag: java bytecode asm

Java ASM GeneratorAdapter变量命名

我正在生成一个简单的类,无法注入适当的变量名称。 ASM版本是5.2 。 这是代码: package com.test; import org.objectweb.asm.*; import org.objectweb.asm.commons.GeneratorAdapter; import org.objectweb.asm.commons.Method; import java.nio.file.Files; import java.nio.file.Paths; public class Main { public static void main(String[] args) throws Exception { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); String name = “com.test.Sub”; cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name.replace(‘.’, ‘/’), null, “java/lang/Object”, null); Method ctor = Method.getMethod(“void ()”); GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, ctor, […]

最好的选择? 在编译之前编辑字节码(asm)或编辑java文件

目标 检测变量之间的比较和变量的复制 在操作发生的行附近注入代码 代码的目的:每次运行类都会使计数器增加 通用:计算执行后使用某些参数进行的比较和复制的数量 2个选项 注意:我总是有一个.java文件 1)编辑java文件 找到与正则表达式的比较并在行附近注入代码片段然后编译该类(我的应用程序使用JavaCompiler) 2)使用ASM字节码工程 还检测我想跟踪的事件的位置并将片段注入字节码然后使用(已经编译但已修改)的类 我的问题 什么是最好/最干净的方式? 有一个更好的方法吗?

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

前段时间,我在try-finally块中嵌入了一个方法的现有代码,如何使用ASM将方法的主体包装在try-finally块中。 解决方案是在visitCode()中visitCode()方法体开头的try块的标签,并在visitCode()访问带有返回操作码的指令时完成try-finally块。 我知道如果方法没有返回指令,如果方法总是离开并且exception,则解决方案将不起作用。 虽然,我发现前一种解决方案有时也不适用于带有返回指令的方法。 如果方法有多个返回指令,它将无法工作。 原因是它生成了无效的字节码,因为在方法的开头添加了一个try-finally块,但是完成了多个try-finally块。 通常(但可能取决于javac编译器),字节码方法包含单个返回指令,并且所有返回路径通过跳转在该指令处结束。 但是,使用Eclipse编译以下代码将导致字节代码带有两个返回指令: public boolean isEven(int x) { return x % 2 == 0; } 用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 因此,我想知道包装方法代码的整个代码的正确方法是什么。

使用Asm字节码生成器生成具有generics类型的方法(ClassWriter)

使用Asm很容易定义简单的getter和setter(幸运的是,甚至在他们的FAQ中也有解释)。 但有一件事未提及,而我无法找到文档,是如何使用generics类型信息来实现这些。 我实际上能够很容易地确定generics类型信息(因为代码将采用现有的字段和/或方法,并且存在完整的generics类型处理和解析)。 我只需要为包含generics类型的类型生成generics版本。 我希望这就像修改签名的Asm ClassWriter / MethodVisitor调用一样容易,但文档中的一些注释表明它可能不那么容易(因为generics信息存储在与常规信息不同的位置)。 编辑 :看起来入口点是“ClassWriter.visitField / Method(….,String signature) – 请注意,它的”描述“包含正常的非generics类信息,但术语”签名“(在JLS中)具体指的是到generics – 包括类型信息。

运行时是“最终”决赛吗?

我一直在玩ASM ,我相信我成功地将final修饰符添加到了类的实例字段中; 然后我继续实例化所述类并在其上调用一个setter,它成功地改变了now-final字段的值。 我的字节码更改有问题,还是仅由Java编译器最终强制执行? 更新: (7月31日)这里有一些代码供您使用。 主要部分是 一个带有private int x和private final int y的简单POJO, MakeFieldsFinalClassAdapter,它使得它访问的每个字段都是final,除非它已经是, 和AddSetYMethodVisitor,它导致POJO的setX()方法也将y设置为它设置为x的相同值。 换句话说,我们从一个带有一个final(x)和一个非final(y)字段的类开始。 我们做x决赛。 除了设置x之外,我们使setX()设置为y。 我们跑。 x和y都设置为没有错误。 代码在github上 。 你可以用以下方法克隆它: git clone git://github.com/zzantozz/testbed.git tmp cd tmp/asm-playground 有两点需要注意:我首先提出这个问题的原因是:我做了最后一个字段和一个已经是最终字段的字段都可以设置为我认为是正常的字节码指令。 另一个更新: (8月1日)使用1.6.0_26-b03和1.7.0-b147进行测试,结果相同。 也就是说,JVM在运行时愉快地修改了最终字段。 最终(?)更新: (9月19日)我正在从这篇文章中删除完整的源代码,因为它相当冗长,但它仍然可以在github上看到(见上文)。 我相信我已经最终certificateJDK7 JVM违反了规范 。 (请参阅Stephen的回答摘录 。)如前所述,在使用ASM修改字节码后,我将其写回到类文件中。 使用优秀的JD-GUI ,这个类文件反编译为以下代码: package rds.asm; import java.io.PrintStream; public class TestPojo { private final int x; private […]

Java ASM字节码修改 – 更改方法体

我在jar子里有一个类的方法,我想用自己的身体交换它。 在这种情况下,我只想让方法打印出“GOT IT”到控制台并返回true; 我正在使用系统加载程序来加载jar的类。 我使用reflection使系统类加载器能够通过字节码加载类。 这部分似乎工作正常。 我按照这里找到的方法替换示例:asm.ow2.org/current/asm-transformations.pdf。 我的代码如下: public class Main { public static void main(String[] args) { URL[] url = new URL[1]; try { url[0] = new URL(“file:////C://Users//emist//workspace//tmloader//bin//runtime//tmgames.jar”); verifyValidPath(url[0]); } catch (Exception ex) { System.out.println(“URL error”); } Loader l = new Loader(); l.loadobjection(url); } public static void verifyValidPath(URL url) throws FileNotFoundException { File filePath […]

如何在Java上重新定义已定义的类

我希望在下面的代码中调用newTarget.a()和newTarget.b()时应用调制的ASM类,使它看起来像这样 当我使用Modified ASM Class调用newTarget.a()和newTarget.b()时,如何获得以下结果? 码: package asm; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import static org.objectweb.asm.Opcodes.ASM5; public class Main { public static void main(String[] args) throws Exception { Target target = new Target(); target.a(); target.b(); ClassReader reader = new ClassReader(“asm.Main$Target”); ClassWriter writer = new ClassWriter(0); ClassVisitor visitor = new TestClassVisitor(ASM5, writer); […]

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 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())); } […]

方法代码太大了! 使用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”

查找方法的字节码大小

我试图找出一个方法的字节码大小,因为我想确保它足够小,可以通过编译器优化来内联。 我看到内联方法的默认最大大小是35,所以如果方法大于那个,我将修改代码或将其分解为多个方法。 我有一个方法生成下面的字节码(通过IntelliJ IDEA的ASM字节码大纲插件反汇编)。 如何判断该方法的字节码大小? LINENUMBER似乎引用了原始源代码的行号。 TIA public static mergeNativeArrays([Ljava/lang/Object;[Ljava/lang/Object;IZ)[Ljava/lang/Object; L0 LINENUMBER 865 L0 ALOAD 0 ASTORE 4 L1 LINENUMBER 867 L1 ILOAD 2 IFGE L2 L3 LINENUMBER 868 L3 ALOAD 0 ARRAYLENGTH ISTORE 2 L2 LINENUMBER 870 L2 FRAME APPEND [[Ljava/lang/Object;] ILOAD 2 ALOAD 1 ARRAYLENGTH IADD ISTORE 5 L4 LINENUMBER 872 L4 ALOAD […]