FlowDroid工具的构建与运行

来源:互联网 发布:电玩巴士淘宝店靠谱吗 编辑:程序博客网 时间:2024/06/05 05:57

今天早上Aaron收到一封邮件,从我的博客联系到我,问我如何运行flowdroid,着实感到开心。这是我博客搭建起来之后第一次有人联系到我,感觉自己可以做一点事情很开心。本文是以我对该邮件的回复为基础加以整理,总结了FlowDroid工具的构建和运行的方法。

回复邮件正文

您好。

我是从读了这篇论文才开始接触android的,所以对android基础知识、运行机制乃至环境搭建认识非常浅薄。

但我确实把flowdroid运行起来了。

参考资料是官方文档:https://github.com/secure-software-engineering/soot-infoflow-android/wiki

该文档对flowdroid的构建分为两节,Obtaining the nightly builds和Building FlowDroid From Source。我都进行了尝试。前者是使用事先构建好的flowdroid运行所必须的jar包,后者是从源码层面自行构建。

采用Obtaining the nightly builds方法时我遇到了android SDK某特定版本找不到的错误,由于对android了解甚少,再者我想从代码层面了解flowdroid,因而我直接放弃了这种方式。

Building FlowDroid From Source。首先从google下载android SDK。然后根据该小节所说的,把JasminHerosSootsoot-infoflowsoot-infoflow-android源码下载下来放在同一个目录下。用eclipse导入已有工程,选择工程的根目录。

导入后效果如下图:

import project

然后,你可以在/soot-infoflow-android/test包下找到对droidBench、insecureBank的Junit测试。例如可以尝试运行soot.jimple.infoflow.android.test.droidBench.CallbackTests.runTestAnonymousClass1()方法来测试flowdroid在droidbench上的运行效果。

但运行会报错。1是找不到android sdk,2是找不到droidbench所在目录,3找不到EasyTaintWrapperSource.txt。通过查看soot.jimple.infoflow.android.test.droidBench.JUnitTests.analyzeAPKFile(String, boolean)方法的源码可以找到我们需要配置两个环境变量:ANDROID_JARSDROIDBENCH。前者是android.jar所在的目录,该目录在android sdk下,目录结构大概是Android/sdk/platforms/android-23/android.jar这样的。后者是droidbench测试工程集的目录。我是OS X Yosemite系统,在家目录下的.bash_profile下做相应配置并使之生效。其他系统的环境变量配置也不难。至于EasyTaintWrapperSource.txt文件,我发现soot-infoflow项目中存在这个文件,硬拷贝到soot-infoflow-android工程中的,不知道有没有更好的方法。

environment

至此,我已经可以运行flowdroid了。

除了官方给的一些测试集合,也可以用我们自己写的一些apk来测试flowdroid。例如我将论文里的示例代码进行了完善,并用flowdroid进行了测试。主体代码如下:

package com.example.wangdongwei.myapplication;import android.app.Activity;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.telephony.SmsManager;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.EditText;public class LeakageApp extends Activity {    private User user = null;    @Override    protected void onRestart(){        super.onRestart();        EditText usernameText =                (EditText)findViewById(R.id.username);        EditText passwordText =                (EditText)findViewById(R.id.pwdString);        String uname = usernameText.toString();        String pwd = passwordText.toString();        if(!uname.isEmpty() && !pwd.isEmpty())            this.user = new User(uname, pwd);    }    //Callback method in xml file    public void sendMessage(View view){        if(user == null) return;        Password pwd = user.getpwd();        String pwdString = pwd.getPassword();        String obfPwd = "";        //must track primitives        for(char c : pwdString.toCharArray())            obfPwd += c + "_";        String message = "User: " +                user.getName() + " | PWD: " + obfPwd;        SmsManager sms = SmsManager.getDefault();        sms.sendTextMessage("+44 020 7321 0905",                null, message, null, null);    }        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_leakage_app);    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_leakage_app, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        int id = item.getItemId();        //noinspection SimplifiableIfStatement        if (id == R.id.action_settings) {            return true;        }        return super.onOptionsItemSelected(item);    }}

然后打包成leakageapp.apk,放在/soot-infoflow-android/testAPKs包下。在/soot-infoflow-android/test/soot/jimple/infoflow/android/test/otherAPKs/OtherAPKTests.java中写了Junit测试方法:

@Testpublic void runTest3() throws IOException, XmlPullParserException {  InfoflowResults res = analyzeAPKFile  ("testAPKs/leakageapp.apk", false, false, false);  Assert.assertNotNull(res);  Assert.assertTrue(res.size() > 0);}

方法上右键->Run As->JUnit Test进行单元测试。结果如下:

[main] INFO soot.jimple.infoflow.entryPointCreators.AndroidEntryPointCreator - Generated main method:    public static void dummyMainMethod(java.lang.String[])    {        java.lang.String[] $r0;        int $i0;        com.example.wangdongwei.myapplication.LeakageApp $r1;        android.os.Bundle $r2;        boolean $z0, $z1;        android.view.View $r3;        $r0 := @parameter0: java.lang.String[];        $i0 = 0;     label1:        if $i0 == 0 goto label8;        $r1 = new com.example.wangdongwei.myapplication.LeakageApp;        specialinvoke $r1.<com.example.wangdongwei.myapplication.LeakageApp: void <init>()>();        if $i0 == 1 goto label8;        $r2 = new android.os.Bundle;        specialinvoke $r2.<android.os.Bundle: void <init>()>();        virtualinvoke $r1.<com.example.wangdongwei.myapplication.LeakageApp: void onCreate(android.os.Bundle)>($r2);        $r2 = null;     label2:        if $i0 == 2 goto label7;     label3:        if $i0 == 3 goto label4;        $z0 = virtualinvoke $r1.<com.example.wangdongwei.myapplication.LeakageApp: boolean onCreateOptionsMenu(android.view.Menu)>(null);     label4:        if $i0 == 4 goto label5;        $z1 = virtualinvoke $r1.<com.example.wangdongwei.myapplication.LeakageApp: boolean onOptionsItemSelected(android.view.MenuItem)>(null);     label5:        if $i0 == 5 goto label6;        $r3 = new android.view.View;        specialinvoke $r3.<android.view.View: void <init>(android.content.Context)>($r1);        virtualinvoke $r1.<com.example.wangdongwei.myapplication.LeakageApp: void sendMessage(android.view.View)>($r3);        $r3 = null;     label6:        if $i0 == 6 goto label3;     label7:        if $i0 == 7 goto label2;        if $i0 == 8 goto label8;        virtualinvoke $r1.<com.example.wangdongwei.myapplication.LeakageApp: void onRestart()>();        if $i0 == 9 goto label2;     label8:        if $i0 == 11 goto label1;        return;    }[Call Graph] For information on where the call graph may be incomplete, use the verbose option to the cg phase.[Spark] Pointer Assignment Graph in 0.0 seconds.[Spark] Type masks in 0.0 seconds.[Spark] Pointer Graph simplified in 0.0 seconds.[Spark] Propagation in 0.0 seconds.[Spark] Solution found in 0.0 seconds.[main] INFO soot.jimple.infoflow.codeOptimization.InterproceduralConstantValuePropagator - Removing side-effect free methods is disabled[main] INFO soot.jimple.infoflow.Infoflow - Dead code elimination took 0.028132 seconds[main] INFO soot.jimple.infoflow.Infoflow - Callgraph has 112 edges[main] WARN soot.jimple.infoflow.android.InfoflowAndroidConfiguration - Static field tracking is disabled, results may be incomplete[main] WARN soot.jimple.infoflow.android.InfoflowAndroidConfiguration - Using flow-insensitive alias tracking, results may be imprecise[main] INFO soot.jimple.infoflow.android.InfoflowAndroidConfiguration - Implicit flow tracking is NOT enabled[main] INFO soot.jimple.infoflow.android.InfoflowAndroidConfiguration - Exceptional flow tracking is enabled[main] INFO soot.jimple.infoflow.android.InfoflowAndroidConfiguration - Running with a maximum access path length of 5[main] INFO soot.jimple.infoflow.android.InfoflowAndroidConfiguration - Using path-agnostic result collection[main] INFO soot.jimple.infoflow.android.InfoflowAndroidConfiguration - Recursive access path shortening is enabled[main] INFO soot.jimple.infoflow.Infoflow - Looking for sources and sinks...[main] INFO soot.jimple.infoflow.Infoflow - Source lookup done, found 5 sources and 1 sinks.[main] INFO soot.jimple.infoflow.Infoflow - Taint wrapper hits: 52[main] INFO soot.jimple.infoflow.Infoflow - Taint wrapper misses: 61[main] INFO soot.jimple.infoflow.Infoflow - IFDS problem with 452 forward and 30 backward edges solved, processing 1 results...[main] INFO soot.jimple.infoflow.data.pathBuilders.ContextInsensitiveSourceFinder - Obtainted 1 connections between sources and sinks[main] INFO soot.jimple.infoflow.data.pathBuilders.ContextInsensitiveSourceFinder - Building path 1[main] INFO soot.jimple.infoflow.data.pathBuilders.ContextInsensitiveSourceFinder - Path processing took 0.003869 seconds in total[main] INFO soot.jimple.infoflow.Infoflow - The sink virtualinvoke $r8.<android.telephony.SmsManager: void sendTextMessage(java.lang.String,java.lang.String,java.lang.String,android.app.PendingIntent,android.app.PendingIntent)>("+44 020 7321 0905", null, $r5, null, null) on line 38 in method <com.example.wangdongwei.myapplication.LeakageApp: void sendMessage(android.view.View)> was called with values from the following sources:[main] INFO soot.jimple.infoflow.Infoflow - - $r1 = virtualinvoke $r0.<com.example.wangdongwei.myapplication.LeakageApp: android.view.View findViewById(int)>(2131492871) on line 19 in method <com.example.wangdongwei.myapplication.LeakageApp: void onRestart()>Maximum memory consumption: 526.43924 MB

仔细看一下,该结果是说从findViewById到sendTextMessage的source-sink关系使该程序存在taint的风险。

但其实,对于EditText的对象passwordText,直接调用toString是无法得到其文本内容的(正确方式应该是passwordText.getText().toString()),所以这算不算是一个误报呢?这是我没有搞明白的一个点。


原文地址:http://aaronmoment.cn/run-flowdroid/

阅读全文
0 0
原创粉丝点击