寫這篇文章前,首先要感謝 Simon_fu ,他的兩篇關於 root 權限的文章對於個人工做起到了很是大的幫助,這篇文章能夠說是對他的文章的一個補充。 Simon_fu 的文章能夠參考以下兩個網頁:android
通常來講, Android 下的應用程序能夠「直接」獲得的最大的權限爲 system ,可是若是咱們須要在程序中執行某些須要 root 權限的命令,如 ifconfig 等,就須要 root 權限了。按照 Simon 的文章中提到的,應用程序有如下兩種辦法臨時得到 root 權限:函數
1) 實現一個 init 實現一個 Service ,來幫助 Android 應用程序執行 root 權限的命令。url
2) 實現一個虛擬設備,這個設備幫助 Android 應用程序執行 root 權限的命令。spa
第二種辦法我這裏沒有嘗試,暫時也不會。這裏講講我在實現第一種辦法的過程和遇到的一些問題。.net
1. 將咱們要執行的命令寫成腳本,或者可執行程序。命令行
下面是個人腳本 ifconfig_test.sh :unix
# ! /system/bin/shorm
ifconfig
注意: 腳本的第一行必須爲 # ! /system/bin/sh ,不然沒法執行,經過 dmesg 能夠查看到信息內容爲cannot execve ./ifconfig_test.sh: Exec format error
也能夠採用 C/C++ 編寫須要執行的命令或者程序,並在編譯 image 的時候編譯成可執行程序。
2. 在 init.rc 中註冊 service
Android 中的 service 須要在 init.rc 中註冊, Init.rc 中定義的 Service 將會被 init 進程建立,這樣將能夠得到root 權限。當獲得相應的通知(經過屬性設置)後, init 進程會啓動該 service 。
本文中註冊的內容以下:
service ifconfig_test /system/etc/ifconfig_test.sh
oneshot
disabled
其中, oneshot 表示程序退出後再也不從新啓動, disabled 表示不在系統啓動時啓動。
注意: 這裏 service name 不能超過 16 個字符。我以前的 service name 因爲定義的比較長, 18 個字符,設置屬性通知 service 啓動後查看 dmesg 能夠看到提示: init: no such service 。查看 /system/core/init/parser.c的源代碼,在 parse_service->valid_name 函數中能夠看到以下內容: if (strlen(name) > 16) { return 0; } ,證實service 的名字的確不能超過 16 個字符。
3. 將 Android 應用程序提高爲 system 權限
既然應用程序能夠經過啓動 service 得到 root 權限,那麼豈不是很不安全。 Android 考慮到了這點,規定只有 system 權限的應用程序才能設置屬性,通知 service 啓動。關於提高 system 權限的文章網上已有不少,這裏就再也不細說,能夠參考以下兩篇文章:
http://blog.csdn.net/liujian885/archive/2010/03/22/5404834.aspx
http://labs.chinamobile.com/mblog/532767_73183
4. 在應用程序中添加屬性設置代碼
前面已經提到,對於 Android 來講,應用程序通知 init 啓動 service 是經過設置系統屬性來完成的,具體爲設置 System 系統屬性 「ctl.start」 爲 「ifconfig_test」 ,這樣 Android 系統將會幫咱們運行 ifconfig_test 這個service 了。
對該系統屬性的設置有三種方法,分別對應三種不一樣的應用程序:
1) Java 代碼
Android 在 Java 庫中提供 System.getProperty 和 System.setProperty 方法, Java 程序能夠經過他們來設置和得到屬性。代碼以下:
SystemProperties.set("ctl.start", "ifconfig_test");
上面的代碼是通知 Android 執行 ifconfig_test service ,若是須要查詢當前 service 執行的狀態,如是否執行完畢,能夠經過以下代碼查詢:
ret = SystemProperties.get("init.svc. ifconfig_test ", "");
if(ret != null && ret.equals("stopped"))
{
return true;
}
2) JNI 代碼
當編寫 NDK 的程序時,可使用 property_get 和 property_set 這兩個 API 來得到和設置屬性。使用這兩個API 必需要包含頭文件 cutils/properties.h 和連接 libcutil 庫。
3) Shell 腳本
Android 提供了命令行 setprop 和 getprop 來設置和獲取屬性,他們能夠在腳本中被使用。
因爲個人程序是在 JNI 中調用腳本,腳本中又執行 ifconfig ,所以我將設置屬性的部分放在了腳本中完成,代碼以下:
setprop ctl.start ifconfig_test
#wait for the service until it stops
ret=1
while [ $ret -ne 0 ]
do
getprop | grep "$ENABLE_MAPPER_SRV" | grep stopped
ret=$?
done
經過上面 4 個步驟, Android 應用程序就得到了 root 權限,更具體的說,是在執行咱們須要執行的命令時臨時得到了 root 權限。