我正试图获取方法中所有标签的偏移量。
我尝试使用以下代码:
private static ArrayList<Integer> GetLabelOffsets(MethodNode methodNode) {
ArrayList<Integer> labelOffsets = new ArrayList<>();
for (AbstractInsnNode instruction : methodNode.instructions.toArray()) {
if (instruction instanceof JumpInsnNode) {
JumpInsnNode jumpInsnNode = (JumpInsnNode) instruction;
labelOffsets.add(jumpInsnNode.label.getLabel().getOffset());.
}
}
return labelOffsets;
}
但getOffset()
方法会抛出Exception
:
java.lang.IllegalStateException: Label offset position has not been resolved yet
如何解决这些偏移位置?或者实现这个目标的正确方法是什么?
MethodNode
是来自Java ASM库的org.objectweb.asm.tree.MethodNode
对象
根据要求添加了更多代码:
public static HashMap<String, ClassNode> ParseJar(JarFile jar) {
HashMap<String, ClassNode> classes = new HashMap<>();
try {
Enumeration<?> enumeration = jar.entries();
while (enumeration.hasMoreElements()) {
JarEntry entry = (JarEntry) enumeration.nextElement();
if (entry.getName().endsWith(".class")) {
ClassReader classReader = new ClassReader(jar.getInputStream(entry));
ClassNode classNode = new ClassNode();
classReader.accept(classNode, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
classes.put(classNode.name, classNode);
}
}
jar.close();
return classes;
} catch (Exception ex) {
return null;
}
}
public static void main(String[] args) {
JarFile jar = new JarFile(fileName);
HashMap<String, ClassNode> classes = JarUtils.ParseJar(jar);
for (ClassNode classNode : classes.values()) {
for (MethodNode methodNode : classNode.methods) {
ArrayList<Integer> offsets = GetLabelOffsets(methodNode);
// do more stuff with offsets
}
}
}
答案 0 :(得分:4)
来自documentation of getOffset()
:
此方法适用于属性子类,类生成器或适配器通常不需要。
由于此偏移量是根据 bytes 定义的,因此在处理指令列表时不会非常有用,特别是当ASM抽象出不同形式的指令时在字节码中可能有不同的长度。
一般的想法是可以更改此指令列表,因此Label
表示逻辑位置,并且在编写方法的结果字节码时将计算偏移量,并且实际数字是已知的。
在指令列表中,应该有一个对应的LabelNode
引用与指令相同的Label
。