您好,登錄后才能下訂單哦!
TaintDroid是一個多粒度Android的污點跟蹤方法。TaintDroid使用變量級的跟蹤VM解釋器。多個污點標記被存儲為一個污點標簽。當應用程序執行本地方法的時候,各種的污點標記被作為返回值返回。最后,最后污點標記被分配給包通過Binder機制進行傳播。注意在技術報告中對于這部分執行細節有更詳細的解釋。
圖 2描述了TaintDroid的系統架構。信息被標記為可信任的應用程序當有充足的上下文時。污點接口調用了本地的方法和Dalvik虛擬機進行交互,存儲精確的污點標記在虛擬的污點集中。Dalvik VM傳播污點標簽根據數據流規則作為可信任的應用程序使用污點信息。每一個的解釋器實例同時傳播污點標記。當可信任的APP使用污點信息在IPC中進行傳播,修改后的Binder庫確保了包裹有污點標記反射出合并后的污點標記包含了所有的數據。包裹傳輸完全通過內核并且被遠程的不可信任程序接受。注意僅有解釋代碼是不可信的。修改后的Binder庫檢索來自包的污點標記并將它分配給所有的值從其中讀取。Dalvik VM實例的遠程傳播將完全相同的污點標記為不可信應用程序。當不可信任的應用程序調用調用一個特定的程序作為一個污點池。e.g.網絡發送數據,庫來檢索污點標記數據問題并且報告事件。
執行這個架構需要解決幾個系統的挑戰:
a) 污點的存儲
b) 解釋代碼污點傳播
c) 原生代碼污點傳播
d) IPC污點傳播
e) 二級存儲污染
剩余的部分將會描述我們的設計。
對于怎樣選擇存儲標記直接影響了執行和存儲的效率。動態污點跟蹤系統通常存儲每個字節或標簽。跟蹤內存是結構化的,沒有內容的語義。常用的污點標記被存儲在不相鄰的單元和標記地圖上。TaintDroid使用了解釋器里的語義變量。我們存儲相鄰的污點標記在內存當中,提供空間位置。
Dalvik有五種類型的變量要求存儲:局部方法變量,方法的參數,類的靜態變量,類實例的字段值和數組。在所有的情況下,我們存儲了一個32位的位向量對于每一個污點標記每個變量進行編碼,允許存儲32種不同的污點標記。
Dalvik存儲方法的本地變量值還有參數在內部棧。當應用程序調用一個方法的時候,一個新的堆棧幀分配給所有的局部變量。方法參數的傳遞也通過內部棧。在調用方法之前,被調用的函數的參數的地方在堆棧的頂部,這樣它們成為了高編號被登記在被調用的函數的堆棧幀。我們給污點存儲分配增加一倍大小的存儲空間。污點標簽值之間的交叉例如寄存器Vi最初訪問的變量是fp[i]當被修改之后訪問的是fp[2·i]。注意Dalvik存儲一個64位的變量是通過兩個相鄰的32位內部寄存器完成的。然而字節碼解釋這些相鄰的寄存器作為一個單獨的64位的值,解釋器管理這些寄存器作為單獨的值。因此,我們對棧的修改是透明的并且檢索64位的值對于分開的寄存器。最后,本機方法的目標要求一個稍微不同的堆棧框架便是基于以上原因。
圖3修改后的棧的格式
污點標記是交錯在寄存器之間的來解釋方法目標和附加的本地方法。深灰色的盒子代表的是污點標記。
詳細的討論在4.3節。修改的棧格式如圖 3所示。
污點標記存儲在相鄰的類字段和數組在VM解釋器的內部的數據結構。為了使存儲開銷最小化TaintDroid存儲的僅僅是每個數組的一個污點標簽。對于Java字符串對象來說每個污染值的存儲是極其低效的。作為所有的特征都有相同的標簽。不幸的是,對于每個數組只存儲一個污點標簽可能導致假陽性污染傳播。例如,如果一個沒有被標記污點的值u存儲的數組A下標索引為0(A[0])的位置并且污點變量t存儲在A[1],此時數組A是被標記為污染的。之后,如果變量v被分配給A[0],v將會被標記,即使u是未被標記的。不幸的是,Java頻繁的使用對象,并且對象之間的引用是被頻繁的標記的(見4.2節),因此編碼實踐將會呈現出更少的假陽性。
污點跟蹤的粒度和流的語義直接影響了性能和準確性。TaintDroid執行變量級的污點跟蹤使用了Dalvik VM解釋器。變量提供有價值的語義污點傳播,從標量值區分數據指針。TaintDroid最原始的跟蹤是基本類型變量(e.g.int,float,etc);但是,在一些情況下對象的引用必須成為受污染的以確保污點傳播的正確性;這一節描述了為什么這些例子是存在的。但是,首先我們呈現出污點跟蹤在Dalvik機器語言是作為正常的邏輯。
Dalvik VM運行唯一的DEX機器語言指令集,因此我們必須設計一個合適的傳播邏輯。我們使用了數據流邏輯,作為跟蹤隱式流要求的靜態分析和引起顯著的
性能開銷和高估的跟蹤(見第8節)。我們開始定義了污點標記,污點標簽,變量以及污點傳播。我們呈現了我們對于DEX的邏輯。
設集合L是對一個特定集合的一般情況下的污點標記。一個污點標記是這個集合中的一個元素,t L。每一個變量都有一個相關聯的污點標記。一個變量是在4.1節中描述的5個類型中的一種。對于每一種類型我們采用了不同的表示。局部變量和參數變量我們對應于相應的虛擬寄存器,使用VX。類的字段變量我們使用fx來表示用X來表示類的下標。字段的實例要有一個對象的實例來指示被標記為Vy(fx),其中Vy是實例對象的引用(包括對象的直接引用和間接引用),靜態字段也是用fx來標記,速記為S(fx),其中S()表示的是靜態的取值范圍。最終,Vx[·]代表的是一個數組,Vx代表的是數組變量的引用。
我們的污點函數集使用的是τ(·)。τ(v)返回的是污點標記變量。檢索和復制是不同我們使用符號←來區分。當τ(v)出現在←的右邊表示的是檢索污點標記的變量值v。當τ(v)出現在←的左邊表示的對變量值v賦值。例如,τ(v1)← τ (v2)將污點標記V2的值賦給V1。
表 1展示的是我們傳播邏輯。該表列舉了抽象的DEX字節碼指令的詳細說明。寄存器變量和類的字段分別使用Vx和fx代替。R表示的返回E表示的是異常。大寫的A,B,C代表的是不變的字節碼。表中沒有列出清除污點寄存器的目的寄存器。
表1TaintDroid的傳播邏輯
例如我們不考慮指令數組的長度對于返回一個污點值即使這個數組是受污染的。注意數組的長度有助于直接控制流的傳播。
在表 1中的傳播規則有兩個例外。其一,污點傳播邏輯包括污點標記數組的索引中查找處理轉換表(e.g. ASCII/UNICODE的大小寫轉換)。例如,考慮從小寫轉換到大寫字母的情況:如果一個污點值“a”是數組的一個索引,由此導致“A”也是被污點標記的即使“A”在數組中不是。因此,污點邏輯aget-op既使用數組和數組索引污點。第二,當這個數組包含對象索引(e.g.一個證型數組),這個污點索引標記傳播的是對象的引用而不是對象的值。因此,我們包含對象引用污點標記在實例中得到了(iget-op)規則。
圖 4列出的代碼展示出了一個實際的實例對象引用污點的必要性。在這里,ValueOf()返回一個整數對象傳遞int。如果整型參數在-128到127之間,ValueOf()返回引用靜態定義的整型對象。ValueOf()對象隱式的轉換為一個對象。考慮下列方法的定義:
Object intProxy(int val) { return val; }
int out = (Integer) intProxy(tVal);
考慮一下這樣一種情況tVal的值是int為1并且是被標記的。當intProxy()傳遞tVal的時候最后返回的值是val。在這種情之下,Integer.valueOf()獲得一個整數實例對應val標量的變量。在這種情況下,Integer.valueOf()返回一個引用靜態對象其值為1。這個變量字段(整型類)對應的對象標記為;然而,因為aget-op傳播規則包括污點的索引寄存器,這個對象的索引有一個污點標記。因此,僅僅只包含對象的污點標記當字段讀取來自整型,正確的污點標記將會被賦值。
圖4摘自Android整數類說明需要對象引用的污點傳播
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。