在不同的方法调用中跟踪相同的对象

时间:2021-05-10 05:40:42

标签: java jvm bytecode bytecode-manipulation bcel

我最近开始使用 BCEL 库来实现我自己的 FindBugs 插件。我有一个 Intent 对象(它是一个 Android 静态分析插件)。我想检查是否在我的方法中声明了一个 Intent 对象,它的 ACTION 设置为“android.media.action.VIDEO_CAPTURE”。如果满足此条件,我还想检查这是否与作为参数传递给 startActivityForResult 的意图对象相同。现在,我只是在检查我的方法内部是否有一个意图在自身上调用 setAction,以及该方法稍后是否调用了 startActivityForResult。

示例 Android 代码:

protected void onCreate(Bundle savedInstanceState) {
        android.content.Intent intent = new android.content.Intent();
        intent.setAction("android.media.action.VIDEO_CAPTURE");
        Uri uri = Uri.fromFile(file);
        intent.putExtra("output", uri);
        startActivityForResult(intent, 105);
        }
    }

插件代码:

private void analyzeMethod(Method m, ClassContext classContext) throws CFGBuilderException, DataflowAnalysisException {
        boolean isStartActivityForResult = false;
        boolean isIntentWithPickUri = false;
        
        MethodGen methodGen = classContext.getMethodGen(m);
        ConstantPoolGen cpg = classContext.getConstantPoolGen();
        CFG cfg = classContext.getCFG(m);

        if (methodGen == null || methodGen.getInstructionList() == null) {
            return;
        }

        for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) {
            Location location = i.next();
            Instruction inst = location.getHandle().getInstruction();
            
            if (inst instanceof INVOKEVIRTUAL) {
                InvokeInstruction invoke = (InvokeInstruction) inst;
                if ("setAction".equals(invoke.getMethodName(cpg))) {
                    LDC loadConst = ByteCode.getPrevInstruction(location.getHandle(), LDC.class);
                    if (loadConst != null) {
                        if ("android.media.action.VIDEO_CAPTURE".equals(loadConst.getValue(cpg)) || "android.media.action.IMAGE_CAPTURE".equals(loadConst.getValue(cpg))
                            || "android.media.action.STILL_IMAGE_CAMERA".equals(loadConst.getValue(cpg)) || "android.media.action.VIDEO_CAMERA".equals(loadConst.getValue(cpg))){
                            isIntentWithPickUri = true;
                        }
                    }
                }
            } else if (inst instanceof INVOKEVIRTUAL) {
                InvokeInstruction invoke = (InvokeInstruction) inst;
                if ("startActivityForResult".equals(invoke.getMethodName(cpg))) {
                    isStartActivityForResult = true;
                }
            }
        }
        if (isStartActivityForResult && isIntentWithPickUri) {
            bugReporter.reportBug(new BugInstance(this, INTERCEPT_FILE_INTENT, Priorities.NORMAL_PRIORITY) 
                    .addClass(classContext.getJavaClass()).addMethod(classContext.getJavaClass(), m));
        } else if ((isStartActivityForResult && !isIntentWithPickUri) || (!isStartActivityForResult && isIntentWithPickUri)) {
            bugReporter.reportBug(new BugInstance(this, INTERCEPT_FILE_INTENT, Priorities.LOW_PRIORITY) 
                    .addClass(classContext.getJavaClass()).addMethod(classContext.getJavaClass(), m));
        }
    }

如您所见,我无法判断是否将其操作设置为给定操作的相同意图发送到 startActivityForResult。它很可能是一个不同的意图,没有任何传递给 startActivityForResult 的动作。

我想我可以使用该方法的局部变量表来实现这一点,但我不知道如何实现。

谢谢

0 个答案:

没有答案
相关问题