Android ROOT System权限 设备管理器
申明:本文部分內容為網絡相關資料整理,并結合本人實際工作總結而成。請引用或者轉載注明出處,對于文章內容有疑問請留言。
一、Android ROOT
1.ROOT原理
ROOT也叫系統管理員用戶,該賬戶擁有整個系統的最高權限,他可以訪問和修改手機幾乎所有的文件。只有ROOT才能具備最該級別的管理員權限,我們ROOT手機就是獲取手機最高權限的過程。同時為了防止不良軟件也取得ROOT用戶的權限,當我們在ROOT手機的過程中會給系統安裝一個叫做Superuser.apk的APP。當某些程序執行su指令時想去的系統最高權限時,Superuser就會自動啟動,攔截該動作并作出詢問,當用戶認為該程序可以安全使用時,那就選擇允許,程序就可以獲取到ROOT權限。否則,可以禁止該程序繼續取得最高權限。Root的過程其實就是把su文件放到/system/bin/ Superuser.apk?放到system/app下面,還需要設置/system/bin/su可以讓任意用戶可運行,有set uid和set gid的權限。即要在android機器上運行命令:adb shell chmod 4755 /system/bin/su。而通常,廠商是不會允許我們隨便這么去做的,我們就需要利用操作系統的各種漏洞,來完成這個過程。2.對于ROOT的思考(轉自:http://www.zhihu.com/question/21074979)
你想在Linux下獲取root權限的時候就是執行sudo或者su,接下來系統會提示你輸入root用戶的密碼,密碼正確就獲得root權限了。Android本身就不想讓你獲得Root權限,大部分手機出廠的時候根本就沒有su這個程序。所以你想獲得Android的root權限,第一步就是要把編譯好的su文件拷貝到Android手機的/system/bin或者/system/xbin/目錄下。我們先假設你可以把su放在xbin下,接下來你可以在Android手機的adb shell或者串口下輸入su了。Linux下su以后輸入密碼就可以root了,但Android里的su和Linux里的su是不一樣的,Android里的su不是靠驗證密碼的,而是看你原來的權限是什么。意思就是如果你是root,那你可以通過su切換到別的用戶,比如說shell,wifi,audio什么的。但如果你是root之外的其他用戶,就不能切換回root了,會提示你permission denied。也就說用root運行su才有用,但我這個時候還沒有root怎么辦呢?這就涉及到另外個問題。
一般我們在Linux的console下輸入 ls -l 會列出所有文件的權限。比如:-rwxr-xr-x,用過Linux的人都知道r代表該文件可讀,w代表可寫,x代表可執行,- 就代表沒有該權限。第一個rwx代表文件所有者的權限,第二個rwx代表和所有者同組人的權限,第三個rwx代表其他用戶對該文件的權限。但下面這個文件就比較特殊。
rws,它的執行權限標志位是一個s,s代表當任何一個用戶執行該文件的時候都擁有文件所有者的權限,這文件的所有者是root,簡單點說就是不管誰執行這個文件,他執行的時候都是以root身份執行的。也就說即使我不是root也有可能以root身份來執行程序,那么我就把一個所有者是root的su程序權限標志位置成-rwsr-xr-x,那么不管誰執行它,都是root身份執行,su就可以順利執行成功了,執行成功之后我就是root身份了。
問題都清楚了,就是你需要把一個所有者是root的su拷貝到Android手機上,并且把su的權限標志位置成-rwsr-xr-x。能把這個事情搞定你就成功root了一個手機。
大概意思就是兩行代碼
cp /data/tmp/su /system/bin/ #copy su 到/system/分區
chown root:root su #su的所有者置成root
chmod 4775 /system/bin/su #把su置成-rwsr-xr-x
熟悉Android的同學都知道,執行上面的每一行代碼都需要root權限才能成功。意思就是說,你只有有root權限的情況下才能執行上面兩行代碼,而這兩行代碼就是為了讓你獲得root權限的,這是一個邏輯閉環,那么如何打破這個邏輯閉環呢?一個辦法就是找一個本身已經有root權限的進程來啟動我上面的兩行代碼,那我這兩行代碼一啟動就是root權限,就可以順利執行了。但是已經有root權限的進程都是出廠時候就裝到手機上的,代碼寫死了,你沒法控制它執行你自己的代碼啊。這個時候就需要你找漏洞了,比如用來破解Android2.3 root權限的zergRush漏洞就是利用一個擁有root權限的進程棧溢出漏洞。
為什么su一定要放到/system/bin/或者/system/xbin/ ?su不能放在data分區原因是因為data分區在mount時就指定了不能給可執行程序加s位。你在adb shell里執行mount就可以看到,或者看下面的截圖。
下面有下劃線的部分是原作者的解釋:
/*
* 首先,你當然可以把su這個程序copy到/data/分區,但你adb push進去的時候,su有這個程序的所
* 有者肯定不是root,一般是shell什么的(記不清了,應該是和adbd這個進程的所有者一樣),這個時
* 候即使你把它權限置為-rwsr-xr-x,哪你運行它的時候也是shell身份運行的,su會提示你輸入密碼
* 的。
* 第二我們root手機的目的是為了運行需要root權限的APP,比如goagent或者什么的。這些APP里代
* 碼需要獲得root的時候是這么寫的:
* Process p = Runtime.getRuntime().exec("su");
* 也就是它們在代碼里調用了一下su這個程序,哪可以寫成下面這個樣子嗎?
* Process p = Runtime.getRuntime().exec("./data/tmp/su");
* 我沒寫過APP,不太清楚,估計是不行的。換句話說你必須把su放到環境變量PATH所有的目錄
* 里,APP才能調用到它。如果你不想放到bin或者xbin下,你就必須給PATH增加一個目錄。PATH是
* root權限才能修改的,你如果能修改PATH,說明你已經有root權限了,修改PATH就沒必要了,還
* 不如直接放到bin下面。
*/
3.APP獲取ROOT權限(轉自:http://blog.csdn.net/jingwen3699/article/details/8175937)
A.要讓Android應用獲取ROOT權限,首先Android設備需要具有ROOT權限。下面代碼為判斷設備是否具有ROOT權限 <span style="font-size:18px;"> public static boolean runRootCommand(String command) {Process process = null;DataOutputStream os = null;try {process = Runtime.getRuntime().exec("su");os = new DataOutputStream(process.getOutputStream());os.writeBytes(command+"\n");\\os.writeBytes("echo \"Do I have root?\" >/system/sd/temporary.txt\n");os.writeBytes("exit\n");os.flush();process.waitFor();} catch (Exception e) {Log.d(TAG, "the device is not rooted, error message: " + e.getMessage());return false;} finally {try {if (os != null) {os.close();}if(process != null) {process.destroy();}} catch (Exception e) {e.printStackTrace();}}return true;}</span><pre name="code" class="java"><span style="font-size:18px;"> </span><span style="font-size:18px;">或者:/*** 判斷當前手機是否有ROOT權限* @return*/public boolean isRoot(){boolean bool = false;try{ if ((!new File("/system/bin/su").exists()) && (!new File("/system/xbin/su").exists())){bool = false;} else {bool = true;}Log.d(TAG, "bool = " + bool);} catch (Exception e) {} return bool;}</span>B.在設備具有ROOT權限的前提下,執行su命令,這時會提示用戶進行授權。 <span style="font-size:18px;">import java.io.DataOutputStream; import android.app.Activity; import android.util.Log;/*** 應用程序運行命令獲取 Root權限,設備必須已破解(獲得ROOT權限)* @param command 命令:String apkRoot="chmod 777 "+getPackageCodePath(); RootCommand(apkRoot);* @return 應用程序是/否獲取Root權限*/public boolean RootCommand(String command){Process process = null;DataOutputStream os = null;try{process = Runtime.getRuntime().exec("su");os = new DataOutputStream(process.getOutputStream());os.writeBytes(command + "\n");os.writeBytes("exit\n");os.flush();process.waitFor();} catch (Exception e){Log.d("*** DEBUG ***", "ROOT REE" + e.getMessage());return false;} finally{try{if (os != null){os.close();}process.destroy();} catch (Exception e){}}Log.d("*** DEBUG ***", "Root SUC ");return true;} }</span>C.對上述代碼進行調用 <span style="font-size:18px;">public class MainActivity extends Activity {public void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);String apkRoot="chmod 777 "+getPackageCodePath();</span><pre name="code" class="cpp"><span style="font-size:18px;"> //讀、寫、運行三項權限可以用數字表示,就是r=4,w=2,x=1。所以,上面的例子中的rw-r--r--用數字表示成644。//反過來說777就是rwxrwxrwx,意思是該登錄用戶(可以用命令id查看)、他所在的組和其他人都有最高權限。//getPackageCodePath():獲取自身APK路徑SystemManager.RootCommand(apkRoot);</span><pre name="code" class="java"><span style="font-size:18px;">}</span>
二、System權限
1.System權限介紹(目前沒有深入研究,待以后補充)
在linux系統中是只有ROOT權限和普通權限的,Android包裝了一套自己的權限體系,有platform、media、shared等的權限。ROOT權限是超級權限,如果得到ROOT權限則可以對系統進行任意操作。Android系統肯定不會讓APK獲得這種權限,但是提供了訪問system目錄的權限,即system權限,對應Android的權限體系為platform。?一般情況下system用戶可以在系統中創建和刪除文件,訪問設備等等。但是有些情況下system權限還是不夠的。比如:設置網卡IP地址,ifconfig命令是需要ROOT權限的。安卓系統并不像windows,system權限(uid1000)并不是最高權限,僅僅比普通用戶擁有少量的特殊權限,比如安裝軟件無需彈窗。而系統中最高權限是root權限(uid0)。所以綜上:ROOT權限高于System權限。2.如何獲取System權限(下述方法未親自驗證)
A.一般權限的添加一般情況下,設定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級別,系統中要求權限才能訪問的文件,apk還是不能訪問。比如在android 的API中有提供 SystemClock.setCurrentTimeMillis()函數來修改系統時間,這個函數需要root權限或者運行與系統進程中才可以用。第一個方法簡單點,不過需要在Android系統源碼的環境下用make來編譯,綜上:
a. 在應用程序的AndroidManifest.xml中的manifest節點中加入android:sharedUserId="android.uid.system"這個屬性。
b. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform這一行 c. 使用mm命令來編譯,生成的apk就有修改系統時間的權限了。
B.修改密鑰
a.在代碼中,AndroidManifest.xml文件的manifest項中,添加android:sharedUserId="android.uid.system"
b.編譯程序,得到APK文件,如src.apk
c.將APK文件用壓縮軟件打開,刪除META-INF目錄里面的CERT.SF和CERT.RSA兩個文件
d.給*.apk文件簽名
這步需要在android源碼中進行
cd build/tools/signapk
javac signapk.java(這里產生*.class) mkdir test/com/android/signapk cp *.class test/com/android/signapk jar cvfm signapk.jar SignApk.mf -C test/ .(這里產生signapk.jar)e.運行命令(其中signapk.jar platform.x509.pem platform.pk8這3個文件在源碼的build目錄下可以找到)
mkdir SignApk 步驟4中產生的signapk.jar拷貝到SignApk文件夾中 cp build/target/product/security/{platform.x509.pem,platform.pk8} SignApkjava -jar signapk.jar platform.x509.pem platform.pk8 src.apk dst.apk
f.dst.apk安裝后就有system權限,就可以訪問設備
C.直接把eclipse編出來的apk用系統的簽名文件簽名
a. 加入android:sharedUserId="android.uid.system"這個屬性。
b. 使用eclipse編譯出apk文件。
c. 使用目標系統的platform密鑰來重新給apk文件簽名。首先找到密鑰文件,在我ndroid源碼目錄中的位置是"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",這樣也是保護了系統的安全。
注:將APP安裝到system/app目錄下可以用于防卸載,以后會出一個Android防卸載專題。
三、設備管理器
1.關于設備管理器
Android2.2后提供了設備管理器,通過API可以對Android設備進行更多權限的管理和操作,如清除所有數據、更改屏幕解鎖密碼及規則、鎖定屏幕、設置存儲設備加密、停用相機、鎖屏時禁用某些功能等等,而且相同功能的程序之間的權限互不沖突。2.代碼示例(轉自:http://blog.csdn.net/etzmico/article/details/6848061)
第一步,注冊一個廣播類,用于監聽權限的變化:
[java]?view plaincopyandroid:permission?表示此功能需要的權限。
android:name="android.app.action.DEVICE_ADMIN_ENABLED"表示此動作的跳轉界面。
<meta-data?android:name="android.app.device_admin"android:resource="@xml/device_admin"?/>表示這個應用可以管理的權限清單。
?
XML清單:
[java]?view plaincopy?第二步,廣播服務類的JAVA代碼,重寫一些必要的實現函數:
廣播類deviceAdminReceiver 繼承DeviceAdminReceiver
[java]?view plaincopy?第三步,也就是最關鍵的操作代碼了
激活相關
[java]?view plaincopy代碼中的自定義區域2是可以輸入一些自己想說的話,和廣播類中的android:description="@string/description"一樣。
這個是系統提供的兩個自定義區域。
[java]?view plaincopy?鎖屏相關
[java]?view plaincopy鎖屏操作,由于是模擬器不能做到真正錯屏,只能停到初始模擬器進來需要解鎖的狀態,屏幕不會變暗。
?
設置屏幕燈光變暗時間相關
[java]?view plaincopyet是定義的一個EditText,用于進行時間的輸入
屏幕變暗最小時間為5秒
?
恢復出廠設置相關
[java]?view plaincopy恢復出廠設置只能通過真機去操作,模擬器操作后會停留在正在關機的dialog畫面
恢復后數據會被清空,因此要做好備份操作。
注:激活設備管理器也可以用于防卸載,只是到Android5.0以上版本,可能會失靈。
總結
以上是生活随笔為你收集整理的Android ROOT System权限 设备管理器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: XS GPU系统产品亮相:专注汽车行业的
- 下一篇: 大学计算机案例实验教程文件,大学计算机实