Java 字节码 - ASM - 获取标签偏移量
Java Bytecode - ASM - Get Label Offset
我正在尝试获取方法中所有标签的偏移量。
我尝试使用以下代码:
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
}
}
}
来自documentation of getOffset()
:
This method is intended for Attribute sub classes, and is normally not needed by class generators or adapters.
由于此偏移量是根据 字节 定义的,因此在处理 指令 列表时不会很有帮助,尤其是因为 ASM 抽象出不同形式的指令,这些指令的字节码长度可能不同。
大意是这个指令列表是可以改变的,所以Label
s代表逻辑位置,在写一个方法的结果字节码时会计算偏移量,实际数字是已知的。
在指令列表中,应该有一个相应的 LabelNode
引用与指令相同的 Label
。
我正在尝试获取方法中所有标签的偏移量。
我尝试使用以下代码:
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
}
}
}
来自documentation of getOffset()
:
This method is intended for Attribute sub classes, and is normally not needed by class generators or adapters.
由于此偏移量是根据 字节 定义的,因此在处理 指令 列表时不会很有帮助,尤其是因为 ASM 抽象出不同形式的指令,这些指令的字节码长度可能不同。
大意是这个指令列表是可以改变的,所以Label
s代表逻辑位置,在写一个方法的结果字节码时会计算偏移量,实际数字是已知的。
在指令列表中,应该有一个相应的 LabelNode
引用与指令相同的 Label
。