为何SOOT无法检测到动态加载类中的方法调用?
SOOT调用图无法识别实例方法调用的解决方案
问题场景
作为SOOT初学者,创建Calculator类实例后,其add方法的调用关系始终无法在生成的调用图中找到,即使打印所有调用边也看不到该方法的调用记录。
待分析源码
package com.example.hello; public class TestInputMain { public static void main(String[] args) { Calculator calc = new Calculator(); // 同包下自定义的类 int result = calc.add(10, 20); // 无法在调用图中找到该调用! System.out.println("The result of adding 10 and 20 is " + result); } }
使用的SOOT配置代码
// 设置调用图 String[] sootArgs = { "-pp", "-process-dir", jarFilePath, // 已打包为jar,不打包结果一致 "-allow-phantom-refs", "-no-bodies-for-excluded", "-whole-program", "-verbose", "-p", "cg.cha", "enabled:true", "-dynamic-dir", jarFilePath, }; Options.v().parse(sootArgs); String sootClassPath = jarFilePath; Options.v().set_soot_classpath(sootClassPath); Scene.v().loadNecessaryClasses(); PackManager.v().getPack("wjtp").add(new Transform("wjtp.myTransform", new SceneTransformer() { @Override protected void internalTransform(String phaseName, Map<String, String> options) { CallGraph cg = Scene.v().getCallGraph(); // 打印调用图中所有边 CallGraph callgraph = Scene.v().getCallGraph(); Iterator<Edge> edgesdebug = callgraph.iterator(); while (edgesdebug.hasNext()) { Edge it = edgesdebug.next(); System.out.println("??????" + it.src() + " =>> " + it.tgt()); } } }));
排查与解决步骤
确保目标类被SOOT完整加载:
确认Calculator的class文件在jarFilePath指向的资源中,且手动强制加载该类(避免SOOT自动加载时遗漏),在Scene.v().loadNecessaryClasses()后添加:Scene.v().loadClass("com.example.hello.Calculator", SootClass.BODIES);该操作会强制SOOT加载类的方法体,为调用图分析提供必要的代码信息。
更换调用图分析算法:
CHA(类层次分析)属于保守型算法,对直接实例化的类调用可能识别不足。可以替换为更精确的RTA或Spark算法:- 启用RTA:将sootArgs中的
"-p", "cg.cha", "enabled:true"替换为"-p", "cg.rta", "enabled:true" - 启用Spark:替换为
"-p", "cg.spark", "enabled:true"
- 启用RTA:将sootArgs中的
确认阶段执行顺序:
调用图构建属于cg阶段,若自定义Transform的执行时机过早,可能访问到未完成构建的调用图。可以在访问调用图前强制触发调用图构建:PackManager.v().getPack("cg").apply();完善全程序模式配置:
启用-whole-program时,添加-include-all参数强制SOOT处理类路径下所有相关类,避免遗漏目标类:String[] sootArgs = { // 原有参数 "-include-all", };
验证方式
修改配置后重新运行SOOT,检查打印的调用边是否包含TestInputMain.main到Calculator.add的调用关系。若仍未找到,可通过-verbose日志确认Calculator类是否被SOOT正确加载。
内容的提问来源于stack exchange,提问作者Chenyang Zhu
相关产品推荐
相关产品推荐

