【问题标题】:Instrument all GETSTATIC and PUTSTATIC bytecode instructions检测所有 GETSTATIC 和 PUTSTATIC 字节码指令
【发布时间】:2016-10-26 12:22:33
【问题描述】:

我需要检测某些类中的所有 getstaticputstatic 字节码指令。 我知道 Java 代理的基础知识,我正在寻找的是一个允许在源代码级别添加检测代码的框架。所以我想用纯 java 代码而不是手写字节码来检测指令。 我已经看到 Javassist 具有此功能,但不适用于字节码级别的检测。

谁能帮忙?

【问题讨论】:

  • 只是想知道:您打算解决什么问题?
  • 我正在对静态程序状态进行数据流分析
  • 您如何想象“在源代码级别添加检测代码”应该如何与“字节码级别检测”一起使用?我想,你的实际问题更容易解决。通过注入一个简单的方法调用来检测指令。调用方法的实现可以用纯 Java 源代码完成。
  • 问题是我需要访问 put 和 getstatic 的参数,因为我需要记录它们。这需要复制栈顶之类的东西。我希望有一些高级 api 可以直接访问某个字节码指令的参数(推送到堆栈/从中删除的值)。
  • “高级 API”与“源级 API”不同。但是“堆栈上的价值”概念没有更高级别的附属物,无论如何也没有必要。对于getstatic,堆栈上没有参数。对于putstatic,堆栈上有一个与字段类型匹配的值,但您只需要关心它是“类型2”(longdouble)还是“类型1”(其他所有内容),复制条目时。

标签: java instrumentation java-bytecode-asm javassist


【解决方案1】:

在 Javassist 中,这有点乏味。基本上,您需要做的是迭代方法的代码:

ClassPool classPool = ...
for (Object method : managedCtClass.getClassFile().getMethods()) {
  MethodInfo methodInfo = (MethodInfo) oMethod;
  if (methodInfo.getCodeAttribute() == null) {
    continue;
  }
  CodeIterator iterator = methodInfo.getCodeAttribute().iterator();
  while (iterator.hasNext()) {
    int index = iterator.next();
    int opcode = iterator.byteAt(index);
    if (opcode != Opcode.PUTFIELD && opcode != Opcode.GETFIELD) {
      continue;
    }
    // manually adjust the byte code by itr.writeXXX methods.
  }
  methodInfo.getCodeAttribute().setAttribute(MapMaker.make(classPool, methodInfo));
}

确保一旦你改变了字节码,你需要在完成对所有代码元素的迭代之后替换属性。

【讨论】:

  • 实际上如果使用访问者 API 会容易得多。这也不是我要求的。我要求更高的级别,这样我就不必手动编写字节码了
猜你喜欢
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 2017-09-05
  • 1970-01-01
  • 1970-01-01
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多