Java字节码-ASM-获取标签偏移量

Java字节码-ASM-获取标签偏移量,java,java-bytecode-asm,bytecode-manipulation,Java,Java Bytecode Asm,Bytecode Manipulation,我试图在一个方法中获得所有标签的偏移量 我尝试使用以下代码: private static ArrayList<Integer> GetLabelOffsets(MethodNode methodNode) { ArrayList<Integer> labelOffsets = new ArrayList<>(); for (AbstractInsnNode instruction : methodNode.instructions.toAr

我试图在一个方法中获得所有标签的偏移量

我尝试使用以下代码:

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;
}
如何解析这些偏移位置?或者,实现这一目标的正确方法是什么

编辑
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
        }
    }
}
publicstatichashmap-ParseJar(JarFile-jar){
HashMap类=新的HashMap();
试一试{
枚举=jar.entries();
while(枚举.hasMoreElements()){
JarEntry=(JarEntry)枚举.nextElement();
if(entry.getName().endsWith(“.class”)){
ClassReader ClassReader=newClassReader(jar.getInputStream(entry));
ClassNode ClassNode=新的ClassNode();
accept(classNode,classReader.SKIP_DEBUG | classReader.SKIP_FRAMES);
class.put(classNode.name,classNode);
}
}
jar.close();
返回类;
}捕获(例外情况除外){
返回null;
}
}
公共静态void main(字符串[]args){
JarFile jar=新的JarFile(文件名);
HashMap classes=JarUtils.ParseJar(jar);
对于(类节点:classes.values()){
for(MethodNode方法节点:classNode.methods){
ArrayList偏移=GetLabelOffsets(methodNode);
//用补偿做更多的事情
}
}
}
来自:

此方法用于属性子类,类生成器或适配器通常不需要此方法

由于该偏移量是以字节为单位定义的,因此在处理指令列表时,它不会有很大帮助,特别是当ASM抽象出字节码中可能具有不同长度的不同形式的指令时

一般的想法是,这个指令列表可以更改,因此
标签
s表示逻辑位置,在写入方法的结果字节码时,将计算偏移量,并且实际的数字是已知的

在说明列表中,应该有与说明相同的
标签的相应引用。

来自:

此方法用于属性子类,类生成器或适配器通常不需要此方法

由于该偏移量是以字节为单位定义的,因此在处理指令列表时,它不会有很大帮助,特别是当ASM抽象出字节码中可能具有不同长度的不同形式的指令时

一般的想法是,这个指令列表可以更改,因此
标签
s表示逻辑位置,在写入方法的结果字节码时,将计算偏移量,并且实际的数字是已知的


在说明书列表中,应该有一个与说明书相同的
标签的相应引用。

您能提供(张贴)一个吗?谢谢更新!什么jar文件应该用作程序输入来重现问题?任何jar文件都应该这样做。只要字节码中包含(非)条件跳转,我就不写方法。我需要这些信息来分析现有的方法。你能提供(发布)一个吗?谢谢更新!什么jar文件应该用作程序输入来重现问题?任何jar文件都应该这样做。只要字节码中包含(非)条件跳转,我就不写方法。我需要这些信息来分析现有的方法。谢谢!看起来我把这个复杂化了。这样做更容易/更干净。谢谢!看起来我把这个复杂化了。这样它工作起来更容易/更干净。
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
        }
    }
}