簡體   English   中英

使用ASM進行字節碼分析

[英]Using ASM for bytecode analysis

我正在評估使用ASM作為實現某些字節碼分析的框架的可能性。 到目前為止,我一直在玩一些示例,但是有一些事情我需要整理:1)我看不到如何用MethodVisitor類檢測完全簽名的方法(完整的參數類型名稱和形式參數)名稱)。

2)如果正在分析的.class文件具有關聯的Java源,如何將字節碼指令與源中的行號鏈接

3)如何區分ClassVisitor中的實例字段和靜態字段

1)我看不到如何用MethodVisitor類(完整的參數類型名稱和形式名稱)檢測方法的完全簽名。

你不能 ClassVisitor收到類似的呼叫

public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) 

在返回MethodVistor之前,您需要從您感興趣的參數中捕獲信息。

如果代碼是使用調試信息編譯的,則可以使用visitLocalVariable獲取參數和局部變量名稱

2)如果正在分析的.class文件具有關聯的Java源,如何將字節碼指令與源中的行號鏈接

該方法中的代碼將具有visitLabel形式的源信息“指令”

3)如何區分ClassVisitor中的實例字段和靜態字段

通過access修飾符。 使用Modifier.isStatic(access)

1)實際上,我設法提取了詳細的方法簽名(參數類型,名稱和返回類型),作為MethodVisitor實現的一部分。 備注:僅當編譯包含調試信息的類文件時,此方法才有效。

@Override
public MethodVisitor visitMethod(int access, String name,
        String desc, String signature, String[] exceptions) {



    try {
        final LinkedList<String> parameters;
        final boolean isStaticMethod;

        Type[] args = Type.getArgumentTypes(desc);
        Type ret = Type.getReturnType(desc);

        parameters = new LinkedList<String>();            
        isStaticMethod = Modifier.isStatic(access);

        return new MethodVisitor(Opcodes.ASM5) {
            // assume static method until we get a first parameter name
            public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
                if (isStaticMethod && parameters.size() < args.length) {
                    parameters.add(args[index].getClassName()+" " +name);
                } else if (index > 0 && parameters.size() < args.length) {
                    // for non-static the 0th arg is "this" so we need to offset by -1
                    parameters.add(args[index-1].getClassName() +" " +name);
                }
            }

            @Override
            public void visitEnd() {
                 System.out.println("Method: "+ret.getClassName()+" "+name+"("+String.join(", ", parameters)+")");
                super.visitEnd();
            }
        };
    } catch (Exception e) {
        throw e;
    }     

它將為標准主電源產生以下輸出:

方法:void main(java.lang.String [] args)

2)參數Label startLabel end包含有關相應源的信息,只要在進行編譯時就包含了源即可。

3) 參見@Peter Lawrey的回復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM