對Android系統權限的認識

Android系統是運行在Linux內核上的,Android與Linux分別有本身的一套嚴格的安全及權限機制java

Android系統權限相關的內容

(一)linux文件系統上的權限linux

-rwxr-x--x system   system       4156 2012-06-30 16:12 test.apk.

表明的是相應的用戶/用戶組及其餘人對此文件的訪問權限,與此文件運行起來具備的權限徹底不相關。android

好比上面的例子只能說明system用戶擁有對此文件的讀寫執行權限;system組的用戶對此文件擁有讀、執行權限;其餘人對此文件只具備執行權限。而test.apk運行起來後能夠幹哪些事情,跟這個就不相關了。
千萬不要看apk文件系統上屬於system/system用戶及用戶組,或者root/root用戶及用戶組,就認爲apk具備system或root權限。apk程序是運行在虛擬機上的,對應的是Android獨特的權限機制,只有體現到文件系統上時才使用linux的權限設置。安全

(二)Android的權限規則app

(1)Android中的apk必須簽名
這種簽名不是基於權威證書的,不會決定某個應用允不容許安裝,而是一種自簽名證書。
重要的是,android系統有的權限是基於簽名的。好比:system等級的權限有專門對應的簽名,簽名不對,權限也就獲取不到。eclipse

默認生成的APK文件是debug簽名的。獲取system權限時用到的簽名見後面描述。ide

(2)基於UserID的進程級別的安全機制
進程有獨立的地址空間,進程與進程間默認是不能互相訪問的,Android經過爲每個apk分配惟一的linux userID來實現,名稱爲"app_"加一個數字,好比app_43不一樣的UserID,運行在不一樣的進程,因此apk之間默認便不能相互訪問。函數

Android提供了以下的一種機制,可使兩個apk打破前面講的這種壁壘。
在AndroidManifest.xml中利用sharedUserId屬性給不一樣的package分配相同的userID,經過這樣作,兩個package能夠被當作同一個程序,系統會分配給兩個程序相同的UserID。固然,基於安全考慮,兩個apk須要相同的簽名,不然沒有驗證也就沒有意義了。工具

(3)默認apk生成的數據對外是不可見的
實現方法是:Android會爲程序存儲的數據分配該程序的UserID
藉助於Linux嚴格的文件系統訪問權限,便實現了apk之間不能相互訪問似有數據的機制。
例:個人應用建立的一個文件,默認權限以下,能夠看到只有UserID爲app_21的程序才能讀寫該文件。ui

-rw------- app_21   app_21      87650 2000-01-01 09:48 test.txt

如何對外開放?

<1> 使用MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE標記。
When creating a new file with getSharedPreferences(String, int), openFileOutput(String, int), or openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory), you can use the MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE flags to allow any other package to read/write the file. When setting these flags, the file is still owned by your application, but its global read and/or write permissions have been set appropriately so any other application can see it.


(4)AndroidManifest.xml中的顯式權限聲明
Android默認應用是沒有任何權限去操做其餘應用或系統相關特性的,應用在進行某些操做時都須要顯式地去申請相應的權限。
通常如下動做時都須要申請相應的權限:

A particular permission may be enforced at a number of places during your program's operation:

At the time of a call into the system, to prevent an application from executing certain functions.When starting an activity, to prevent applications from launching activities of other applications.Both sending and receiving broadcasts, to control who can receive your broadcast or who can send a broadcast to you.When accessing and operating on a content provider.Binding or starting a service.

在應用安裝的時候,package installer會檢測該應用請求的權限,根據該應用的簽名或者提示用戶來分配相應的權限。
在程序運行期間是不檢測權限的。若是安裝時權限獲取失敗,那執行就會出錯,不會提示用戶權限不夠。
大多數狀況下,權限不足致使的失敗會引起一個 SecurityException,會在系統log(system log)中有相關記錄。

(5)權限繼承/UserID繼承
當咱們遇到apk權限不足時,咱們有時會考慮寫一個linux程序,而後由apk調用它去完成某個它沒有權限完成的事情,很遺憾,這種方法是行不通的。
前面講過,android權限是在進程層面的,也就是說一個apk應用啓動的子進程的權限不可能超越其父進程的權限(即apk的權限)
即便單獨運行某個應用有權限作某事,但若是它是由一個apk調用的,那權限就會被限制。
實際上,android是經過給子進程分配父進程的UserID實現這一機制的。

(三)常見權限不足問題分析

首先要知道,普通apk程序是運行在非root、非system層級的,也就是說看要訪問的文件的權限時,看的是最後三位。
另外,經過system/app安裝的apk的權限通常比直接安裝或adb install安裝的apk的權限要高一些。

言歸正傳,運行一個android應用程序過程當中遇到權限不足,通常分爲兩種狀況:
(1)Log中可明顯看到權限不足的提示。
此種狀況通常是AndroidManifest.xml中缺乏相應的權限設置,好好查找一番權限列表,應該就可解決,是最易處理的狀況。

有時權限都加上了,但仍是報權限不足,是什麼狀況呢?
Android系統有一些API及權限是須要apk具備必定的等級才能運行的。
好比 SystemClock.setCurrentTimeMillis()修改系統時間,WRITE_SECURE_SETTINGS權限好像都是須要有system級的權限才行。
也就是說UserID是system.

(2)Log裏沒有報權限不足,而是一些其餘Exception的提示,這也有多是權限不足形成的。
好比:咱們常會想讀/寫一個配置文件或其餘一些不是本身建立的文件,常會報java.io.FileNotFoundException錯誤。
系統認爲比較重要的文件通常權限設置的也會比較嚴格,特別是一些很重要的(配置)文件或目錄。

-r--r----- bluetooth bluetooth      935 2010-07-09 20:21 dbus.conf
drwxrwx--x system   system            2010-07-07 02:05 data 

dbus.conf好像是藍牙的配置文件,從權限上來看,根本就不可能改動,非bluetooth用戶連讀的權利都沒有。

/data目錄下存的是全部程序的私有數據,默認狀況下android是不容許普通apk訪問/data目錄下內容的,經過data目錄的權限設置可知,其餘用戶沒有讀的權限。
因此adb普通權限下在data目錄下敲ls命令,會獲得opendir failed, Permission denied的錯誤,經過代碼file.listfiles()也沒法得到data目錄下的內容。

上面兩種狀況,通常都須要提高apk的權限,目前我所知的apk能提高到的權限就是system(具體方法見:如何使Android應用程序獲取系統權限),

android apk 獲取system權限 

1.通常權限的添加

通常狀況下,設定apk的權限,可在AndroidManifest.xml中添加android:sharedUserId="android.uid.xxx>

例如: 給apk添加system權限

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ... ... 
  android:sharedUserId="android.uid.system">

同時還須要在對應的Android.mk中添加LOCAL_CERTIFICATE := platform這一項。即用系統的簽名,經過這種方式只能使apk的權限升級到system級別,系統中要求root權限才能訪問的文件,apk仍是不能訪問

好比在android 的API中有提供 SystemClock.setCurrentTimeMillis()函數來修改系統時間,這個函數須要root權限或者運行於系統進程中才能夠用。

        第一個方法簡單點,不過須要在Android系統源碼的環境下用make來編譯:        

1. 在應用程序的AndroidManifest.xml中的manifest節點中加入android:sharedUserId="android.uid.system"這個屬性。

2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform這一行

3. 使用mm命令來編譯,生成的apk就有修改系統時間的權限了。

        第二個方法是直接把eclipse編出來的apk用系統的簽名文件簽名        

1. 加入android:sharedUserId="android.uid.system"這個屬性。

2. 使用eclipse編譯出apk文件。

3. 使用目標系統的platform密鑰來從新給apk文件簽名。首先找到密鑰文件,在android源碼目錄中的位置是"build/target/product/security",
下面的platform.pk8和platform.x509.pem兩個文件。而後用Android提供的Signapk工具來簽名,signapk的源代碼是在"build/tools/signapk"下,
編譯後在out/host/linux-x86/framework下,用法爲java -jar signapk.jar platform.x509.pem platform.pk8 input.apk output.apk"。

        加入android:sharedUserId="android.uid.system"這個屬性。經過Shared User id,擁有同一個User id的多個APK能夠配置成運行在同一個進程中。那麼把程序的UID配成android.uid.system,也就是要讓程序運行在系統進程中,這樣就有權限來修改系統時間了。

        只是加入UID還不夠,若是這時候安裝APK的話發現沒法安裝,提示簽名不符,緣由是程序想要運行在系統進程中還要有目標系統的platform key,就是上面第二個方法提到的platform.pk8和platform.x509.pem兩個文件。用這兩個key簽名後apk才真正能夠放入系統進程中。第一個方法中加入LOCAL_CERTIFICATE := platform其實就是用這兩個key來簽名。

        這也有一個問題,就是這樣生成的程序只有在原始的Android系統或者是本身編譯的系統中才能夠用,由於這樣的系統才能夠拿到platform.pk8和platform.x509.pem兩個文件。要是別家公司作的Android上連安裝都安裝不了。試試原始的Android中的key來簽名,程序在模擬器上運行OK,不過放到G3上安裝直接提示"Package ... has no signatures that match those in shared user android.uid.system",這樣也是保護了系統的安全。
---------------------
做者:koozxcv
來源:CSDN
原文:https://blog.csdn.net/koozxcv/article/details/50835601

相關文章
相關標籤/搜索