Android系統權限及簽名

Android權限及簽名

引子

現象:系統中的一個定製Service,服務是對外開放的,使用系統簽名

LOCAL_CERTIFICATE := platform

應用層調用這個系統服務,獲取底層的一些信息。如果在IDE裏進行開發,普通簽名,無法調用到該服務,
改成在系統編譯環境裏編譯,並在Android.mk中加入如下語句:

LOCAL_CERTIFICATE := platform

android:sharedUserId="android.uid.system“
android:process="com.android.phone"

就可以順利的獲取到系統服務。其內在的原因是什麼?

Linux權限

說起Android的權限和簽名,就要先從Linux的權限說起,我們都知道Linux的文件系統是有權限限制的,對於每一個文件或者目錄,我們執行
ls -l 指令都會看到類似如下的顯示:
-rw-r–r– 1 xxxxx xxxxx 681 2013-05-24 09:16 Android.mk
分別代表:文件種類和權限;硬鏈接個數;User;Group;大小;最後訪問/修改時間;文件/目錄名
文件權限代表是否對對應用戶,用戶組,其他用戶開放讀或者寫權限。而User;Group則是代表了該文件是屬於誰的,比如用戶ABC創建的一個文件,該文件的User則爲ABC。linux就是通過文件權限和用戶用戶組這種方式來保證安全的。
而文件權限是通過進程來體現的,用戶訪問一個文件,總是要通過進程來訪問,即便是打開一個終端界面,也是打開了一個bash進程來查看文件的。
就如下圖所示:
圖1
這裏寫圖片描述

對於Android而言,啓動一個Application,一般同樣要啓動一個單獨的進程來運行,就像這樣:

drwxr-x--x u0_a49   u0_a49            2013-01-01 08:00 com.example.test
drwxr-x--x radio    radio                  2013-01-03 06:35 com.android.phone

上面的test應用啓動了一個單獨的進程,它的用戶的用戶組都是u0_a49。這樣如果沒有意外的話,其只能訪問到該應用自己的data數據。
問題來了,如果我想訪問其他不適自己data的文件及目錄該怎麼辦呢?首先想到的就是能不能把自定義的應用的用戶組改成和其他某應用一樣呢?比如User改成radio。

答案是可以的。不過Android爲了保證系統安全,還有個規定:
必須在AndroidManifest.xml具有相同簽名+相同shareUserId屬性的兩個App,纔可以分配相同的用戶ID。因爲com.android.phone是系統應用,其簽名是LOCAL_CERTIFICATE := platform 系統簽名,所以我必須同樣採用LOCAL_CERTIFICATE := platform系統簽名,並且android:sharedUserId=”android.uid.radio” 纔可以讓這個自定義的App和phone應用具有相同的UID。(當然如果只是想訪問,android:sharedUserId可以設爲更高權限的用戶也可以實現)。

AndroidManifest.xml中還有一個標籤android:process,比如:android:process=”com.android.phone”,它可以單獨應用於某個Activity或者Service,也可以直接應用於Application。作用就是將對應的Activity或者Service放在com.android.phone這個進程中運行。而使用這個標籤的前提就是前一段所說的:具有相同簽名+相同shareUserId屬性。
標籤android:process的作用比如phone應用中運行的某個動態庫或者持有的某個單例對象,如果另外一個app想要使用或者說調用的話,是沒法使用,或者拿到的是另外一個單例—因爲是另一個進程了。這個時候通過android:process將對於的Activity讓其在phone進程中運行。這樣就可以很方便的使用phone應用中的資源了。
圖2
這裏寫圖片描述

簽名和APK的關係:通常APK對於的是Linux中的User和Process。APK的運行,就代表一個獨特的進程的運行,而該進程又屬於某個User。具有相同簽名和相同shareUserId屬性的兩個APK,纔會屬於同一個User.(APK安裝時,PackageManagerService會檢查)
簽名和權限的關係:簽名是爲了讓系統識別是不是同一個作者,除了前面提到的系統簽名外,每個作者都可以自定義自己的簽名。對於簽名級的權限,比如一個作者的應用定義了一個權限。並設置權限的android:protectionLevel 爲”signature”。那麼只有該作者使用同樣簽名的另一個應用,纔可以使用該權限。

Root後的手機呢

爲什麼root後就可以無視那些權限呢?
拿一個root過得手機,執行如下代碼:

Process process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());  
os.writeBytes(“echo 1500000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq" + "\n"); 

su程序的權限如下所示:

System/bin/su
-rwsr-xr-x root root 

關鍵就是那個執行權限標誌位S,代表當任何用戶執行該文件時,都擁有該文件所有者的權限—–root。
當然這裏說的比較簡略,其實在應用執行root權限操作的時候,向Superuser.apk申請超級用戶請求,
Superuser.apk利用系統漏洞,執行類似如下的操作。讓su程序居然這些功能。

cp /data/tmp/su /system/bin/
chown root:root su 
chmod 4775 /system/bin/su 

這樣上面修改cpu頻率的語句就可以順利執行。

Q&A

Q:android:sharedUserId和android:process的關係?
A:sharedUserId是對整個apk而言, android:process則是對某一個activity或者servicce而言,很多時候sharedUserId是android:process的前提
Q:android:sharedUserId和android:process分別對應用來說有什麼作用。
A:sharedUserId可以讓應用的uid變成類似system,phone,雖然沒有root用戶權限高,但是也可以做很多事了,具體要看其需求。具有phone的uid,然後纔可以設定應用內的activity的android:process屬性。
使用android:process的原因很多:
a)比如Stk應用,想要使用CatService(單例模式),於是它調用CatService.getInstance(),調用時如果已經存在CatService實例纔會正確返回,該實例還沒有建立,是拿不到的。而這個CatService是在Phone應用中,使用CommandsInterface 對象(Ril)作爲參數建立。這是就需要把Stk應用放在Phone進程裏,纔可以拿到CatService實例。
b)又或者想要設計一個系統應用,想要調用Phone  phone = PhoneFactory.getDefaultPhone()獲得Phone對象,但是這個調用只能運行在phone進程中(原因見該函數源碼)。這就必須把調用該語句的activity設爲android:process=“com.android.phone“——如Setting裏的IccLockSettings。

發佈了88 篇原創文章 · 獲贊 5 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章