这里指的是app能利用Runtime.getRuntime().exec("su")或者ProcessBuilder()等创建一个新的具有root权限的shell终端进程,而不是app本身拥有root权限。使得app自身具有root权限这个我没有研究过,但使得app自身具有system权限则可以使用签名,在Android Framework 之HelloWorld(三)里有描述。
我是参考了[九鼎RK3399Pro] Android 8.1 系统定制给用户root权限这篇文章,对NanoPC-T4开发板进行修改的,不过还要修改system/core/adb/set_verity_enable_state_service.cpp->set_verity_enabled_state_service(),这样运行adb disable-verity才正常,adb remount后也能读写/system和/vendor分区了,有点投机取巧,调试阶段应该还有其他办法直接让/system和/vendor在系统起来时就挂载成可读写分区,毕竟adb disable-verity需要重启生效:
if (!android::base::GetBoolProperty("ro.secure", false)) {
WriteFdFmt(fd, "verity not enabled - ENG buildn");
//return; //不返回
}
下面是修改后su程序的other用户权限是x,能够执行。在root和shell用户下能临时修改到其他用户去,譬如 su u0_a58等。文章中还屏蔽了SElinux,同时把一些工具(如su和adb等)的判断自身是否具有相应权限的代码注释掉了。
su工具修改前
ls -l /system/xbin/su
-rwsr-x--- 1 root shell 11064 2020-08-07 10:42 /system/xbin/su
su工具修改后
ls -l /system/xbin/su
-rwsr-sr-x 1 root root 11064 2020-08-20 13:17 /system/xbin/su
所以,无论当前app运行在哪个用户(如u0_a58之类的)里,都能在app上运行root权限的命令。
private void rootRun(String cmd)
{
try {
// 申请获取root权限
Process process = Runtime.getRuntime().exec("su"); //"/system/xbin/su"
// 获取输出流
OutputStream outputStream = process.getOutputStream();
InputStream is = process.getInputStream();
InputStream es = process.getErrorStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeBytes(cmd);
dataOutputStream.flush();
dataOutputStream.close();
outputStream.close();
int code = process.waitFor();
Log.d("TAG", "Run:"" + cmd +"", "+"process.waitFor() = " + code);
String line;
BufferedReader br;
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
while ((line = br.readLine()) != null) {
Log.d("TAG", line);
}
br = new BufferedReader(new InputStreamReader(es, "UTF-8"));
while ((line = br.readLine()) != null) {
Log.e("TAG", line);
}
} catch (Throwable t) {
Log.e("TAG", "Throwable = " + t.getMessage());
t.printStackTrace();
}
}
...
...
rootRun("reboot"); //运行shell命令,在app里重启android系统
这里指的是app能利用Runtime.getRuntime().exec("su")或者ProcessBuilder()等创建一个新的具有root权限的shell终端进程,而不是app本身拥有root权限。使得app自身具有root权限这个我没有研究过,但使得app自身具有system权限则可以使用签名,在Android Framework 之HelloWorld(三)里有描述。
我是参考了[九鼎RK3399Pro] Android 8.1 系统定制给用户root权限这篇文章,对NanoPC-T4开发板进行修改的,不过还要修改system/core/adb/set_verity_enable_state_service.cpp->set_verity_enabled_state_service(),这样运行adb disable-verity才正常,adb remount后也能读写/system和/vendor分区了,有点投机取巧,调试阶段应该还有其他办法直接让/system和/vendor在系统起来时就挂载成可读写分区,毕竟adb disable-verity需要重启生效:
if (!android::base::GetBoolProperty("ro.secure", false)) {
WriteFdFmt(fd, "verity not enabled - ENG buildn");
//return; //不返回
}
下面是修改后su程序的other用户权限是x,能够执行。在root和shell用户下能临时修改到其他用户去,譬如 su u0_a58等。文章中还屏蔽了SElinux,同时把一些工具(如su和adb等)的判断自身是否具有相应权限的代码注释掉了。
su工具修改前
ls -l /system/xbin/su
-rwsr-x--- 1 root shell 11064 2020-08-07 10:42 /system/xbin/su
su工具修改后
ls -l /system/xbin/su
-rwsr-sr-x 1 root root 11064 2020-08-20 13:17 /system/xbin/su
所以,无论当前app运行在哪个用户(如u0_a58之类的)里,都能在app上运行root权限的命令。
private void rootRun(String cmd)
{
try {
// 申请获取root权限
Process process = Runtime.getRuntime().exec("su"); //"/system/xbin/su"
// 获取输出流
OutputStream outputStream = process.getOutputStream();
InputStream is = process.getInputStream();
InputStream es = process.getErrorStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeBytes(cmd);
dataOutputStream.flush();
dataOutputStream.close();
outputStream.close();
int code = process.waitFor();
Log.d("TAG", "Run:"" + cmd +"", "+"process.waitFor() = " + code);
String line;
BufferedReader br;
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
while ((line = br.readLine()) != null) {
Log.d("TAG", line);
}
br = new BufferedReader(new InputStreamReader(es, "UTF-8"));
while ((line = br.readLine()) != null) {
Log.e("TAG", line);
}
} catch (Throwable t) {
Log.e("TAG", "Throwable = " + t.getMessage());
t.printStackTrace();
}
}
...
...
rootRun("reboot"); //运行shell命令,在app里重启android系统
举报