最近在回答客戶的問題時,提到怎麼將apk 升級到root權限。
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還是不能訪問。
2.升級到root權限
為了回答客戶的問題,跟同事們交流中發現,有一位同事一直致力於backup/restore 的項目,其中也涉及的到類似的問題,感覺他的方法不錯,在這裡我要感謝我親愛的同事加兄弟,現將這種方法貢獻給大家,具體的描述如下:
一般linux 獲取root權限是通過執行su命令,那能不能在apk程序中也同樣執行一下該命令呢,我們知道在linux編程中,有exec函數族:
int execl(cONst char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
在windows 編程中我以前用到過CreateProcess,具體的例子參見:http://msdn.microsoft.com/zh-cn/site/ms682512
以上這些都是C/ C++ 的編程,但在java中將如何執行呢? 以下就要轉入主題了。
在java中我們可以借助 Runtime.getRuntime().exec(String command)訪問底層Linux下的程序或腳本,這樣就能執行su命令,使apk具有root權限,能夠訪問系統中需要root權限才能執行的程序或腳本了,具體例子:
package com.visit.dialoglog;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class VisitRootfileActivity extends Activity {
private static final String TAG = "VisitRootfileActivity";
Process process = null;
Process process1 = null;
DataOutputStream os = null;
DataInputStream is = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
process = Runtime.getRuntime().exec("/system/xbin/su"); //這裡可能需要修改su的源代碼 (注掉 if (myuid != AID_ROOT && myuid != AID_SHELL) {)
os = new DataOutputStream(process.getOutputStream());
is = new DataInputStream(process.getInputStream());
os.writeBytes("/system/bin/ls" + " \n"); //這裡可以執行具有root 權限的程序了
os.writeBytes(" exit \n");
os.flush();
process.waitFor();
} catch (Exception e) {
Log.e(TAG, "Unexpected error - Here is what I know:" + e.getMessage());
} finally {
try {
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
process.destroy();
} catch (Exception e) {
}
}// get the root privileges
}
}