Android Binder IPC機制

之前有很多人問過我TaintDroid的內容,所以一點點吧涉及的思路整理一下。

今天又看瞭一遍,確實需要很多的技術支持以及紮實的功底,不管是Java的還是Android,從系統底層一直到頂層,涉及的知識點比較多。

以後會陸陸續續更新TaintDroid中涉及的知識點和實現的技術詳解,當然瞭,是我個人的理解,未必是人傢就這麼實現的吧。

隻是感覺可行。

在TaintDroid中涉及到Binder HOOK,雖然沒有詳解,但是原理感覺應該差不多吧。

首先Binder IPC這個是在C層的,也就是Native 層進行HOOK,為什麼要進行BinderHOOK,這一層的監控是對信息流進行污點標記的。

因為使用變量級進行標記的話當遇到比較變態的接收器(Receiver)時就會發現溢出變量,使得已經被污點標記的變量被移除,因此需要使用信息層(message-level)來做保障。

兩個運用程序之間的通信是通過Binder IPC來完成的。

之後的TaintDroid詳解中會詳細分析,現在先給出信息層實現原理。就是Binder HOOK。

1.Android Binder IPC機制

Android系統中大量使用瞭基於C/S模式的通信方式。諸如短信操作,電話操作,視頻音頻捕獲,傳感器等都以服務(Service)的形式提供,並由相應的Server負責管理,

應用程序作為Client隻需要與這些Server建立連接並發送請求便能使用這些服務。因此,開發者完全不必關心Service的實現細節,直接與Server建立連接然後使用其提供的接

口即可。Client和Server一般是運行在不同的進程中的,這就涉及到進程間通信(IPC,Inter-Process Communication)。為瞭保證系統安全性,提高通信效率以及提供對C/S

模式的支持,Android采用瞭一種基於共享內存的IPC機制——Binder機制。

2.Binder機制實現

為瞭實現Binder IPC機制,Android在Linux內核掛載瞭一個虛擬的設備/dev/binder。Client和Server進程運行在用戶空間,使用Binder機制進行進程間通信時,雙方看起來是“直接”通信的,

實際上通過/dev/binder的驅動程序即Binder驅動進行瞭數據的中轉,如圖1所示。Binder機制的本質是共享內存,共享內存區的管理完全由Binder驅動來完成,對應用層的Client和Server

來說是完全透明的。

圖 1 Binder進程間通信模型

Client和Server均通過函數ioctl與Binder驅動進行數據交互。ioctl是Linux中用於控制I/O設備的函數,提供瞭一種同時向設備發送控制參數和數據的手段。它是一個可變參數的函數,原型為:

vcD4KPHByZSBjbGFzcz0=”brush:java;”>int ioctl(int fd, int cmd, …);

fd是打開/dev/binder設備後得到的文件描述符,cmd是對設備的控制命令。該函數執行成功返回0,否則返回-1。

3.相關數據結構

當函數ioctl的第二個參數cmd為BINDER_WRITE_READ時,表示向Binder驅動發送一條讀取或者寫入/dev/binder設備的命令,Binder驅動會將對設備的讀寫“翻譯”為對共享

內存區的讀寫。這條命令是Client和Server進行進程間通信時最重要、使用最頻繁的控制命令。

傳入BINDER_WRITE_READ的同時,會傳入一個binder_write_read結構體的指針作為ioctl的第三個參數,該結構中的read_buffer和write_buffer字段分別指向將要讀取或者寫入的緩沖區。這兩個緩沖區中的數據都是以“數據類型+數據內容”的格式順序存放的,而且多條不同類型的數據連續存放,如圖2所示。write_buffer中數據類型以“BC_”開頭,而read_buffer中數據類型以“BR_”開頭,圖2中以write_buffer中的數據為例。在所有的數據類型中,又以BC(R)_REPLY和BC(R)_TRANSACTION最為重要:通過BC_TRANSACTION/BC_REPLY這對命令,發送方將數據發往接受方;通過BR_TRANSACTION/BR_REPLY,接收方讀取發送方發來的數據。

數據的內容是一個binder_transaction_data結構。

圖2 Binder IPC中各數據結構的關系

binder_transaction_data結構是對進程間通信數據的封裝,可以看作網絡通信中的一個數據包。其中的sender_uid,sender_pid成員變量指明瞭此數據發送方的用戶ID和進程ID,buffer成員變量指向進程間通信最核心的有效負載數據,data_size是有效負載數據的長度。在Binder機制中,sender_uid和sender_pid是在內核中由Binder驅動填入的,無法被偽造,保證瞭身份標記的可靠性,由此可見Binder進程間通信機制進行是安全的。

4.Binder之間的數據行為關系

Client和Server使用Binder機制進行進程間通信時,通過分析Client發往Server的數據或者分析Server讀取的Client的請求數據,便可以識別出Client的具體行為。

例如,當Client想要得到定位信息,請求LocationServer獲取定位數據時,會訪問LocationServer的ILocationManager接口,發往LocationServer中的有效負載數

據中包含“android.location.ILocationManager”字符串。所以我們分析LocationServer讀取的Client發來的請求數據,判斷其中是否包含“android.location.ILocationManager”,

我們就可以知道Client是否正在試圖訪問用戶的地理位置信息。

由於Android系統中每個應用程序都有自己唯一的UID,因此根據binder_transaction_data中的sender_uid,我們就可以獲取Client具體代表的應用程序。這樣

就獲得瞭具體軟件的具體行為。

通過對Android系統的分析,我們發現:雖然系統提供的服務多達幾十種,但是實際上隻有三個Server進程負責管理

Android系統Server進程與管理的服務

服務進程

管理的服務

com.android.phone

與通信功能相關的短信、電話服務

mediaserver

與媒體功能相關的視頻、音頻服務

system_server

其他服務,如地理位置、藍牙、網絡連接、程序安裝卸載等

發佈留言