soot基础 — 解析java文件

soot基础 — 解析java文件问题 soot 如何接受 java 文件 并且将其解析出来 1 首先我构建了一个测试类 publicclassT publicstatic String args C 1 publicstatic System out println insideA publics

问题:

      soot如何接受java文件,并且将其解析出来?

      这里主要说明两种解析方式,通过调用soot接口的方式,以及以类似于命令行的方式向soot传递参数的方式。

两种方式本质上是相同的,看读者更容易接受哪一种。

一、通过soot提供的接口来实现soot的使用。

1.首先我构建了一个测试类:

public class TestMain { public static void main(String[] args) { C(1); } public static void A(){ System.out.println("inside A"); } public static void B(){ System.out.println("inside B"); } public static void C(int i ){ if(i > 1){ A(); }else{ B(); } } } 

2.接下来我要用soot来识别出这个java类。

  • 路径的设置十分重要,路径不正确可能导致无法识别。
  • Options是全局的参数设置,并且是只有一个(单例)。

public class TestFileInput { public static final String path = "test/javaTest"; public static void main(String args[]) { initial(path); SootClass appclass = Scene.v().loadClassAndSupport("TestMain");//若无法找到,则生成一个。 System.out.println("the main class is :" + appclass.getName()); //获取类中的相关的方法 Iterator<SootMethod> methodIt = appclass.getMethods().iterator(); while(methodIt.hasNext()){ System.out.println("the function member is : " + methodIt.next().getName()); } } private static void initial(String apkPath) { soot.G.reset(); Options.v().set_allow_phantom_refs(true); Options.v().set_prepend_classpath(true); Options.v().set_validate(true); Options.v().set_output_format(Options.output_format_jimple); Options.v().set_src_prec(Options.src_prec_java); Options.v().set_process_dir(Collections.singletonList(apkPath));//路径应为文件夹 Options.v().set_keep_line_number(true); // Options.v().set_whole_program(true); Options.v().set_no_bodies_for_excluded(true); Options.v().set_app(true); // Scene.v().setMainClass(appclass); // how to make it work ? Scene.v().addBasicClass("java.io.PrintStream", SootClass.SIGNATURES); Scene.v().addBasicClass("java.lang.System", SootClass.SIGNATURES); Scene.v().addBasicClass("java.lang.Thread", SootClass.SIGNATURES); Scene.v().loadNecessaryClasses(); } } 

3.结果如下:

the main class is :TestMain
the function member is : main
the function member is : A
the function member is : B
the function member is : C
the function member is : <init>






二、 以类似于命令行的方式向soot传递参数

       这次我们通过构建查看call graph(函数调用关系图)相关的一些内容。

1.待检测的类如下:

  • 该文件所在的路径: 项目 / test / testCallGraph / testers
  • Call graph的生成是必须得有入口函数(main)的。
  • 注意从main 开始追踪调用的结构。

package testers; public class CallGraphs { public static void main(String[] args) { doStuff(); } public static void doStuff() { new A().foo(); } } class A { public void foo() { bar(); } public void bar() { } }

2.通过soot解析上面这个类的call graph.

代码如下:

  • soot.Main.main(args) 相当于命令行处理。main会将传递的数组进行解析,对于命令解析成soot可以识别的东西。
  • 命令参数以类似于数组的方式传递给main().

public class CallGraphExample { public static void main(String[] args) { List<String> argsList = new ArrayList<String>(Arrays.asList(args)); //相当于传入命令行参数。cmd上操作命令。 argsList.addAll(Arrays.asList(new String[]{ "-w", // "-v", "-process-path", "test/testCallGraph", "-main-class", "testers.CallGraphs",//main-class "testers.CallGraphs",//argument classes "testers.A" // })); PackManager.v().getPack("wjtp").add(new Transform("wjtp.myTrans", new SceneTransformer() { @Override protected void internalTransform(String phaseName, Map options) { CHATransformer.v().transform(); SootClass a = Scene.v().getSootClass("testers.A"); SootMethod src = Scene.v().getMainClass().getMethodByName("doStuff"); CallGraph cg = Scene.v().getCallGraph(); Iterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src)); while (targets.hasNext()) { SootMethod tgt = (SootMethod)targets.next(); System.out.println(src + " may call " + tgt);//这里说的是可能,并不是一定就正确。 } } })); args = argsList.toArray(new String[0]); soot.Main.main(args); } } 

分析的结果

  • 只关注doStuff()所可能调用的方法。(这里说可能,是因为call graph的构造,并不是绝对的准确的事情

<testers.CallGraphs: void doStuff()> may call <java.lang.Object: void <clinit>()> <testers.CallGraphs: void doStuff()> may call <testers.A: void foo()> <testers.CallGraphs: void doStuff()> may call <testers.A: void <init>()>

三、Soot输出中间代码

  • Main.java】在Soot中有个Main.java类,这个类主要是负责解析命令行的,在这里面可以找到命令  与 程序类的方法 之间的对应关系(尤其注意Main中的run()方法)。
  • PackManager】PackMananger是负责进行阶段处理的,它控制着各种执行的运行,不启动则不会运行相应的阶段。(将类的加载类的分析运行相区别,见文章:soot — 常见参数配置)

 soot.G.reset(); Options.v().set_allow_phantom_refs(true); Options.v().set_prepend_classpath(true); Options.v().set_validate(true); Options.v().set_output_format(Options.output_format_jimple);//1.输出的形式 Options.v().set_output_dir("sootOutput"); //2.输出的文件目录   Options.v().set_src_prec(Options.src_prec_java); Options.v().set_process_dir(Collections.singletonList(apkPath));  Options.v().set_whole_program(true); Options.v().set_no_bodies_for_excluded(true); Scene.v().addBasicClass("java.io.PrintStream", SootClass.SIGNATURES); Scene.v().addBasicClass("java.lang.System", SootClass.SIGNATURES); Scene.v().addBasicClass("java.lang.Thread", SootClass.SIGNATURES); Scene.v().loadNecessaryClasses(); PackManager.v().writeOutput(); //关键:启动输出。(不运行此语句不会进行输出) 








版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233479.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • leetcode-84柱状图中最大的矩形(单调栈)「建议收藏」

    leetcode-84柱状图中最大的矩形(单调栈)「建议收藏」原题链接给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。示例:输入: [2,1,5,6,2,3]输出: 10题解对于每一个长方体,找出左边比他小的第一个长方体和右边比他小的第一个长方体,然后遍历求结即可class Solution {public

    2022年8月8日
    5
  • linux查看并杀死进程_ubuntu查看进程命令

    linux查看并杀死进程_ubuntu查看进程命令今天在netbeans中关闭webrick时,发现没有关闭掉,打入localhost:3000依然显示页面,发现无法从nb中再次关闭只有进入ubuntu的进程下关闭查看进程:1,ps-e命令2,feng@feng:~$sudonetstat-antupActiveInternetconnections(serversandestablished)ProtoRecv-QSe…

    2022年9月21日
    3
  • python ==和is_python中isdigit函数

    python ==和is_python中isdigit函数前置知识点当我们创建一个对象时,我们要知道它内部干了些什么1.创建了一个随机id,开辟了一片内存地址2.自动声明了这个对象的类型type3.给这个对象赋值value小例子a=1pri

    2022年7月31日
    6
  • CareerCup它1.8 串移包括问题

    CareerCup它1.8 串移包括问题

    2022年1月2日
    47
  • C C T V 1_win10安装vs2019系统不支持

    C C T V 1_win10安装vs2019系统不支持EmguCv是在.net平台上对OpenCV的封装,便于OpenCV的跨平台开发使用。

    2025年10月20日
    5
  • 30 个重要数据结构和算法完整介绍建议保存

    30 个重要数据结构和算法完整介绍建议保存数据结构和算法(DSA)通常被认为是一个令人生畏的话题——一种常见的误解。它们是技术领域最具创新性概念的基础,对于工作/实习申请者和有经验的程序员的职业发展都至关重要。话虽如此,我决定在CSDN新星计划挑战期间将我所了解的数据结构和算法集中起来。本文旨在使DSA看起来不像人们认为的那样令人生畏。它包括15个最有用的数据结构和15个最重要的算法,可以帮助您在学习中和面试中取得好成绩并提高您的编程竞争力。后面等我还会继续对这些数据结构和算法进行进一步详细地研究讲解。

    2022年5月23日
    33

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号