怎樣使Android應用程序獲得root權限


       寫這篇文章前,首先要感謝 Simon_fu ,他的兩篇關於 root 權限的文章對於我的工作起到了很大的幫助,這篇文章能夠說是對他的文章的一個補充。 Simon_fu 的文章能夠參考例如以下兩個網頁:

Android程序的安全系統

Android應用程序獲得 root權限

 

       一般來說, Android 下的應用程序能夠“直接”得到的最大的權限為 system ,可是假設我們須要在程序中運行某些須要 root 權限的命令,如 ifconfig 等,就須要 root 權限了。依照 Simon 的文章中提到的,應用程序有下面兩種辦法暫時獲得 root 權限:

1)        實現一個 init 實現一個 Service ,來幫助 Android 應用程序運行 root 權限的命令。

2)        實現一個虛擬設備,這個設備幫助 Android 應用程序運行 root 權限的命令。

 

另外一種辦法我這里沒有嘗試,臨時也不會。這里講講我在實現第一種辦法的過程和遇到的一些問題。

 

1.       將我們要運行的命令寫成腳本,或者可運行程序。

以下是我的腳本 ifconfig_test.sh

# /system/bin/sh

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 權限。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM