android面試3

12. 請解釋下Android程序運行時權限與文件系統權限的區別

要區分apk運行時的擁有的權限與在文件系統上被訪問(讀寫執行)的權限兩個概念。
apk程序是運行在虛擬機上的,對應的是Android獨特的權限機制,只有體現到文件系統上時才使用linux的權限設置。
(一)linux文件系統上的權限
-rwxr-x--x system   system       4156 2010-04-30 16:13 test.apk
代表的是相應的用戶/用戶組及其他人對此文件的訪問權限,與此文件運行起來具有的權限完全不相關。
比如上面的例子只能說明system用戶擁有對此文件的讀寫執行權限;system組的用戶對此文件擁有讀、執行權限;其他人對此文件只具有執行權限。
而test.apk運行起來後可以幹哪些事情,跟這個就不相關了。
千萬不要看apk文件系統上屬於system/system用戶及用戶組,或者root/root用戶及用戶組,就認爲apk具有system或root權限
(二)Android的權限規則

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

默認生成的APK文件是debug簽名的。
獲取system權限時用到的簽名,見:如何使Android應用程序獲取系統權限


(2)基於UserID的進程級別的安全機制
大家都知道,進程有獨立的地址空間,進程與進程間默認是不能互相訪問的,是一種很可靠的保護機制。
Android通過爲每一個安裝在設備上的包(apk)分配唯一的linux userID來實現,名稱爲"app_"加一個數字,比如app_43
不同的UserID,運行在不同的進程,所以apk之間默認便不能相互訪問。

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

(這裏補充一點:並不是說分配了同樣的UserID,兩程序就運行在同一進程, 下面爲PS指令摘取的,
顯然,system、app_2分別對應的兩個進程的PID都不同,不知Android到底是怎樣實現它的機制的)

User   PID PPID
system    953   883   187340 55052 ffffffff afe0cbcc S system_server
app_2     1072 883   100264 19564 ffffffff afe0dcc4 S com.android.inputmethod.
system    1083 883   111808 23192 ffffffff afe0dcc4 S android.process.omsservi
app_2     1088 883   156464 45720 ffffffff afe0dcc4 S android.process.acore

(3)默認apk生成的數據對外是不可見的
實現方法是:Android會爲程序存儲的數據分配該程序的UserID。
藉助於Linux嚴格的文件系統訪問權限,便實現了apk之間不能相互訪問似有數據的機制。
例:我的應用創建的一個文件,默認權限如下,可以看到只有UserID爲app_21的程序才能讀寫該文件。
-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應用程序獲取系統權限),
至於是否有root級的,如何提升至root級不得而知,知道的朋友勞煩告知,感激不盡。

轉載自

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章