标签: java-bytecode-asm

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

我在罐子里有一个类的方法,我想用自己的身体交换它.在这种情况下,我只想让方法将"GOT IT"打印到控制台并返回true;

我正在使用系统加载器来加载jar的类.我使用反射使系统类加载器能够通过字节码加载类.这部分似乎工作正常.

我按照这里找到的方法替换示例: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 = new File(url.getFile());
        if (!filePath.exists()) 
        {
          throw new FileNotFoundException(filePath.getPath());
        }
    }
}

class Loader
{
    private static final Class[] parameters = new Class[] {URL.class};

    public static void addURL(URL …
Run Code Online (Sandbox Code Playgroud)

java bytecode code-injection classloader java-bytecode-asm

9
推荐指数
1
解决办法
1万
查看次数

ASM中的Java方法参数值

我试图获取Java程序的方法参数的值.我正在使用ASM来检测字节码并获取这些值.但是,我遇到了一些麻烦.

这是用于检测代码的visitCode()方法.它正在做的是:

  1. 创建一个空数组以存储收集的参数.
  2. 对于每个参数,将其值加载到数组中.
  3. 将此数组发送到我的代理的OnMethodEntry方法(将使用其值).

.

@Override
public void visitCode() {
    int paramLength = paramTypes.length;

    // Create array with length equal to number of parameters
    mv.visitIntInsn(Opcodes.BIPUSH, paramLength);
    mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
    mv.visitVarInsn(Opcodes.ASTORE, paramLength);

    // Fill the created array with method parameters
    int i = 0;
    for (Type tp : paramTypes) {
        mv.visitVarInsn(Opcodes.ALOAD, paramLength);
        mv.visitIntInsn(Opcodes.BIPUSH, i);

        if (tp.equals(Type.BOOLEAN_TYPE) || tp.equals(Type.BYTE_TYPE) || tp.equals(Type.CHAR_TYPE) || tp.equals(Type.SHORT_TYPE) || tp.equals(Type.INT_TYPE))
            mv.visitVarInsn(Opcodes.ILOAD, i);
        else if (tp.equals(Type.LONG_TYPE)) {
            mv.visitVarInsn(Opcodes.LLOAD, i);
            i++;
        }
        else if (tp.equals(Type.FLOAT_TYPE))
            mv.visitVarInsn(Opcodes.FLOAD, i);
        else if …
Run Code Online (Sandbox Code Playgroud)

java jvm bytecode bytecode-manipulation java-bytecode-asm

9
推荐指数
1
解决办法
5040
查看次数

如何在每次返回之前将消息添加到消息中?

我目前正在尝试通过精心设计的java-asm库(版本4)生成代码.更具体地说,我想在每次返回调用之前将代码附加到方法的末尾.我成功地能够在方法代码之前添加代码.但是目前我不知道如何进行上述转换.我真的很感激指出如何实现这一目标.

MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
mv.visitCode();
mv.visitVarInsn(Opcodes.ALOAD, 42);
return mv;
Run Code Online (Sandbox Code Playgroud)

java java-bytecode-asm

9
推荐指数
2
解决办法
2411
查看次数

使用ASM Java库进行拆箱

我正在使用ASM Java库来替换一些反射.我生成了这个方法的主体:

void set(Object object, int fieldIndex, Object value);
Run Code Online (Sandbox Code Playgroud)

使用此生成的方法,我可以在运行时在不使用反射的情况下在对象上设置字段.它很棒.但是,我发现原始字段失败了.这是我的set方法的相关部分:

for (int i = 0, n = cachedFields.length; i < n; i++) {
    mv.visitLabel(labels[i]);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, targetClassName);
    mv.visitVarInsn(ALOAD, 3);
    Field field = cachedFields[i].field;
    Type fieldType = Type.getType(field.getType());
    mv.visitFieldInsn(PUTFIELD, targetClassName, field.getName(), fieldType.getDescriptor());
    mv.visitInsn(RETURN);
}
Run Code Online (Sandbox Code Playgroud)

此代码为选择生成案例标签.它适用于对象,但对于原语,我收到此错误:

期待在堆栈上找到浮动

好的,这是有道理的,我需要自己进行拆箱.我实现了以下内容:

for (int i = 0, n = cachedFields.length; i < n; i++) {
    mv.visitLabel(labels[i]);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, targetClassName);
    mv.visitVarInsn(ALOAD, 3);

    Field field = …
Run Code Online (Sandbox Code Playgroud)

java bytecode bytecode-manipulation java-bytecode-asm

8
推荐指数
1
解决办法
2759
查看次数

如何在asm代码中正确使用Instrumentation.retransformClasses()?

我正在使用asm库来执行一些Java字节码修改 - 专门用于修改我的类以实现新的接口和相关方法.我目前的方法是通过javaagent使用核心asm API.我想保留这种动态方法,而不是静态修改.class文件.

在更高的层次上,我的问题是,如果我选择修改从B扩展的A类,我还需要修改B.(鉴于我对如何在JVM中加载类的理解,我相信B类将永远是在A级之前交给变压器.(如果我错了,请纠正我.)鉴于这个假设,我认为我需要返回并重新转换 B.我的方法在这段代码中被捕获:

public byte[] transform(ClassLoader l, String name, Class<?> clazz, ProtectionDomain d, byte[] b) {
      throws IllegalClassFormatException {
    // **1**
    System.out.println("--->>> " + name);

    if (interestingClass(name)) {
        try {
            ClassReader cr = new ClassReader(b);
            ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
            PyClassVisitorAdapter pv = new PyClassVisitorAdapter(cw, name);
            cr.accept(pv, 0);

            // **2** Retrieve the superclass and try to transform that
            if (! "Ljava/lang/Object;".equals(pv.getSuperName())) {
                String cName = classJvmToCanonical(pv.getSuperName());
                Class[] classes = inst.getAllLoadedClasses();
                for (Class c …
Run Code Online (Sandbox Code Playgroud)

java bytecode java-bytecode-asm

8
推荐指数
1
解决办法
1506
查看次数

8
推荐指数
1
解决办法
493
查看次数

查找方法的字节码大小

我试图弄清楚方法的字节码大小,因为我想确保它足够小,以便通过编译器优化来内联.

我看到内联方法的默认最大大小为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 4
  ARRAYLENGTH
  ILOAD 5
  IF_ICMPGE L5
 L6
  LINENUMBER 874 L6
  ILOAD 3
  IFEQ L7
 L8
  LINENUMBER 875 L8
  ILOAD 5
  INVOKESTATIC railo/commons/math/MathUtil.nextPowerOf2 (I)I
  ISTORE 5
 L7 …
Run Code Online (Sandbox Code Playgroud)

java bytecode compiler-optimization java-bytecode-asm

8
推荐指数
1
解决办法
2105
查看次数

在ASM的字节码方法内联期间重新映射变量

我正在使用ASM进行在线字节码方法内联优化.我的更改基于示例3.2.6 Inline Method(http://asm.ow2.org/current/asm-transformations.pdf).测试示例(在Caller :: test中内联被调用者的计算(int,int))是:

public class Caller {
    final Callee _callee;

    public Caller(Callee callee){
        _callee = callee;
    }
    public static void main(String[] args) {
        new Caller(new Callee("xu", "shijie")).test(5, 100);
    }

    public void test(int a, int b){
        int t = a;
        int p = b;
        int r = t+p-_callee.calculate(a, b);
        int m = t-p;
        System.out.println(t);
    }
}
public class Callee {

    final String _a;
    final String _b;
    public Callee(String a, String b){
        _a = a;
        _b …
Run Code Online (Sandbox Code Playgroud)

java bytecode inline bytecode-manipulation java-bytecode-asm

8
推荐指数
1
解决办法
1147
查看次数

编译错误:computeFrames选项不支持JSR/RET

编译java文件时在IntelliJ项目上出现此错误.没有列出特定的源文件,但它失败并出现此错误.

删除以下编译器标志可修复错误:

-source 1.5 -target 1.5
Run Code Online (Sandbox Code Playgroud)

但是,由于我们的目标是Java 5,因此需要将它们放在那里.是否存在try/catch导致此错误的特定代码(可能是块)?

2013-10-15 16:21:50,556 [26947209]   INFO - ompiler.BackendCompilerWrapper - JSR/RET are not supported with computeFrames option 
java.lang.RuntimeException: JSR/RET are not supported with computeFrames option
    at org.objectweb.asm.Frame.a(Unknown Source)
    at org.objectweb.asm.MethodWriter.visitJumpInsn(Unknown Source)
    at org.objectweb.asm.MethodAdapter.visitJumpInsn(Unknown Source)
    at org.objectweb.asm.ClassReader.accept(Unknown Source)
    at org.objectweb.asm.ClassReader.accept(Unknown Source)
    at com.intellij.compiler.impl.javaCompiler.BackendCompilerWrapper$ClassParsingThread.a(BackendCompilerWrapper.java:893)
    at com.intellij.compiler.impl.javaCompiler.BackendCompilerWrapper$ClassParsingThread.run(BackendCompilerWrapper.java:846)
    at com.intellij.openapi.application.impl.ApplicationImpl$7.run(ApplicationImpl.java:386)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:680)
    at com.intellij.openapi.application.impl.ApplicationImpl$1$1.run(ApplicationImpl.java:130)
Run Code Online (Sandbox Code Playgroud)

java compiler-errors intellij-idea jsr java-bytecode-asm

7
推荐指数
1
解决办法
5491
查看次数

如何使用ASM 4.0修改Java字节码

我是ASM框架的新手.我已经在这个ASM框架上工作了一个星期.我在网上看过关于解析类和从头开始生成.class文件的教程.但我无法遵循如何修改ASM中的现有类.

请帮助我.

我无法遵循ClassVisitor,ClassWriter和ClassReader之间的执行流程.

请通过为我提供以下代码的ASM示例来解决我的问题.

public class ClassName {


public void showOne()
{
    System.out.println("Show One Method");
}

public static void main(String[] args) {

    ClassName c=new ClassName();
    c.showOne();

}

}
Run Code Online (Sandbox Code Playgroud)

上述类应修改为:

public class ClassName {


public void showOne()
{
    System.out.println("Show One Method");
}


public void showTwo()
{
    System.out.println("Show Two Method");
}

public static void main(String[] args) {

    ClassName c=new ClassName();
    c.showOne();
    c.showTwo();

}

}
Run Code Online (Sandbox Code Playgroud)

什么应该是ASM代码来修改它?

我使用ASMifier工具生成代码.但我不知道在哪里应用它.

请帮我.+

java bytecode java-bytecode-asm

7
推荐指数
1
解决办法
3482
查看次数