标签: bytecode-manipulation

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之类的东西)来了解哪些初始值传递给方法?

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

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
查看次数

ASM Java替换方法调用指令

背景

我想在一些耗时的方法上做一些工具,比如 org/json/JSONObject.toString()使用ASM Java框架.

原始调用方法

public class JSONUsage {
    public void callToString() {
        JSONObject jsonObject = new JSONObject();
        String a = jsonObject.toString();//original call
        System.out.println(a);
    }
}
Run Code Online (Sandbox Code Playgroud)

仪表后

public class JSONUsage {
    public void callToString() {
        JSONObject jsonObject = new JSONObject();
        // **important!**
        //pass the instance as an param, replace the call to a static method
        String a = JSONReplacement.jsonToString(jsonObject);
        System.out.println(a);
    }
}

public class JSONReplacement {

    public static String jsonToString(JSONObject jsonObject) {
        //do the time caculation
        long before …
Run Code Online (Sandbox Code Playgroud)

java bytecode-manipulation java-bytecode-asm

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

使用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
查看次数

如何使用ByteBuddy创建动态代理

在Java中,可以使用实现来创建动态代理InvocationHandler.尽管进行了JVM优化,但使用反射总是会有一些调用方法的开销.

为了尝试解决这个问题,我尝试使用ByteBuddy在运行时创建代理类,但文档在这方面似乎不够清晰.

如何创建一个MethodCallProxy方法以将方法调用转发到某个类实例?

编辑:

为了更好地澄清我的问题,我提供了一个我想要实现的例子:

我正在构建一个RPC系统.在方法调用的每一侧,我都有一个定义契约的接口(当调用者/被调用者都在JVM下运行时).

@Contract
interface ISomeService {
    fun someMethod(arg0: String, arg1: SomePojo): PojoResult
}
Run Code Online (Sandbox Code Playgroud)

在调用站点,我注入一个代理,拦截所有方法调用并将它们转发给被调用者.

ByteBuddy()
    .subclass(Any::class.java)
    .implement(serviceClass)

    // Service contract method delegation
    .method(isDeclaredBy(serviceClass)).intercept(
      MethodDelegation
          .to(ServiceProxyInterceptor())
          .filter(not(isDeclaredBy(Any::class.java)))
    )

    .make()
    .load(this)
    .loaded as Class<T>
Run Code Online (Sandbox Code Playgroud)

最后,在被调用者,我有几个处理程序,每个服务方法一个,负责解组调用参数并将它们转发到服务实现.

@Service
class SomeServiceImpl {
    fun someMethod(arg0: String, arg1: SomePojo): PojoResult {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以使用代码生成来解决这个问题,但生成的jar文件会变得非常大.因此,我想创建这些处理程序的通用版本,并在每个实例中附加一个代理,该代理拦截每个方法调用ISomeService并转发它们SomeServiceImpl.

java proxy bytecode-manipulation byte-buddy jvm-bytecode

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

如何从Perl中的coderef获取语法树?

我想在Perl中检查和操作任意Perl程序的代码(由coderefs获取).有没有工具/模块/库?类似于B :: Concise的东西,除了B :: Concise在输出上打印代码,但我想以编程方式检查它.

我想像这样使用它.给定一个coderef F,例如.有10个参数:

$ret = &$F(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10);
Run Code Online (Sandbox Code Playgroud)

我想创建一个函数F1,st.

&$F(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) == 
  &$F1(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)*
  &$C(x2, x3, x4, x5, x6, x7, x8, x9, x10)
Run Code Online (Sandbox Code Playgroud)

那就是把它"分解"成两部分,第二部分不依赖于x1第一部分,第一部分尽可能简单(我假设它F是一个巨大的产品).

我想要的应用是Metropolis采样算法的优化 - 假设我正在对分布进行采样p(x1 | x2 = X1, x3 = X3, ...) = f(x1, x2, x3, ...).算法本身是不变的.乘法常数因子和其他变量不会通过算法改变,因此不依赖于x1 …

perl code-analysis abstract-syntax-tree bytecode-manipulation

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

字节码注入在哪里发生?

动机

我有一个SomeObject.java文件:

class SomeObject {
   String name;
}
Run Code Online (Sandbox Code Playgroud)

编译它会创建一个包含字节码的SomeObject.class文件.

0xCAFEBABE...
Run Code Online (Sandbox Code Playgroud)

如果我们在JVM上使用SomeObject,它将由当前的类加载器加载,并且一切正常.

现在让我们假设我想要一些动态代码生成.我可以写我的自定义注释

@Target(ElementType.TYPE)
public @interface Data {
   ...
}
Run Code Online (Sandbox Code Playgroud)

并将其作为修饰符添加到类声明中:

@Data
class SomeObject {
   String name;
}
Run Code Online (Sandbox Code Playgroud)

我也可以在运行时保留它@Retention(RetentionPolicy.RUNTIME):

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Data {
   ...
}
Run Code Online (Sandbox Code Playgroud)

用于字节码注入的注释在哪里?在使用适当的运行时保留注释加载类时,类加载器是否会注入字节码,如下图所示:

source -(compile)-> bytecode -(classloader bytecode injection)-> injected bytecode -(classloading)-> JVM loaded bytecode   
Run Code Online (Sandbox Code Playgroud)

annotations bytecode classloader bytecode-manipulation

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

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
查看次数

有没有一个python函数可以生成python代码字符串的字节码?

例如我可以做这样的事情吗

pythonCode = "print 'hello world'"
pyc = generate_bytecode(pythonCode)
Run Code Online (Sandbox Code Playgroud)

其中 pyc 将包含 pythonCode 的字节码?

编辑:我的目标本质上是准确获取将写入文件中的 .pyc 的内容到变量中。幻数、时间戳、十六进制版本的代码等等

python bytecode built-in bytecode-manipulation

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

如何检查java方法的字节码长度

目前,我参与了一个大型遗留项目,其中包含许多巨大的类和生成的代码。我希望找到所有字节码长度大于 8000 字节的方法(因为 OOTB java 不会优化它)。

我找到了这样的手动方式:How much bytes of bytecode has a certain method in Java? ,但是我的目标是自动扫描许多文件。

我尝试使用 jboss-javassist,但据我所知,获取字节码长度仅在类级别可用。

java bytecode bytecode-manipulation jvm-bytecode

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