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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • PID控制原理详解(一)[通俗易懂]

    PID控制原理详解(一)[通俗易懂]PID的理解       关于理解PID控制算法最典型的一个例子就是一个漏水的水缸的问题。网上有很多讲解PID的帖子会讲到这个例子。这里我也把我自己对于PID的理解用这个例子阐述一遍。       有个漏水的水缸,而且漏水的速度还不是恒定的。然后我们还有个水桶,我们可以控制往水缸里面加水或者从水缸里面舀水出来。另外我们可以检测水平面。现在我们的目的就是要控制水平面稳定在我们想要的任何一个平面上…

    2022年5月20日
    36
  • java如何实现换行_网页换行代码

    java如何实现换行_网页换行代码在taxtarea中输入的文本。如果含有回车或空格。在界面上显示的时候则不哪么正常。回车消失了,空格变短了。如何解决这个问题呢。有2种方法。1.使用标签w3c对pre元素是这样定义的:pre元素可定义预格式化的文本。被包围在pre元素中的文本通常会保留空格和换行符。而文本也会呈现为等宽字体。更详细的内容请参考http://www.w3school.com.cn/tags/tag_pre.a…

    2025年6月8日
    1
  • so文件格式详解_文件xls文件怎么打开

    so文件格式详解_文件xls文件怎么打开可执行链接格式(ExecutableandLinkingFormat)最初是由UNIX系统实验室(UNIXSystemLaboratories,USL)开发并发布,作为应用程序二进制接口(ApplicationBinaryInterface,ABI)的一部分,它是一种常用的目标文件格式,主要包含以下三种类型1、可重定位文件:可与其它目标文件一起创建可执行文件和共

    2022年9月15日
    0
  • 单片机流水单C语言程序,51单片机流水灯C语言源程序

    单片机流水单C语言程序,51单片机流水灯C语言源程序**************************************************************文件名称:flash_led.c文件说明:流水灯C程序编写日期:2006年10月5日程序说明:MCU采用AT89S51,外接12M晶振,P1口输出*************************************************************/#in…

    2022年5月5日
    35
  • tree命令使用

    tree命令使用aliastree=”find.-print|sed-e’s;[^/]*/;|____;g;s;____|;|;g'”

    2022年7月24日
    5
  • JWT的权限控制与Shiro入门

    JWT的权限控制与Shiro入门

    2021年11月12日
    46

发表回复

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

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