eco*_*utu 29 java android root
我正在开发我的第一个Android应用程序,我很好奇是否有任何"标准"方法来执行特权shell命令.我只能够找到这样做的一种方式,通过执行su,然后再追加我的命令stdin的的su过程.
DataOutputStream pOut = new DataOutputStream(p.getOutputStream());
DataInputStream pIn = new DataInputStream(p.getInputStream());
String rv = "";
// su must exit before its output can be read
pOut.writeBytes(cmd + "\nexit\n");
pOut.flush();
p.waitFor();
while (pIn.available() > 0)
rv += pIn.readLine() + "\n";
Run Code Online (Sandbox Code Playgroud)
我已经读过关于包装特权(superuser)调用的内容JNI:这可能吗?如果是这样,一个人将如何完成它?除此之外,是否还有其他方式来调用特权指令Java?
Muz*_*ant 32
据我所知,您只能使用root权限运行命令行命令.您可以使用我在代码中包含root访问权限的通用类:http: //muzikant-android.blogspot.com/2011/02/how-to-get-root-access-and-execute.html
您需要做的就是扩展此类并重写该getCommandsToExecute方法以返回要以root身份执行的命令.
public abstract class ExecuteAsRootBase
{
public static boolean canRunRootCommands()
{
boolean retval = false;
Process suProcess;
try
{
suProcess = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
DataInputStream osRes = new DataInputStream(suProcess.getInputStream());
if (null != os && null != osRes)
{
// Getting the id of the current user to check if this is root
os.writeBytes("id\n");
os.flush();
String currUid = osRes.readLine();
boolean exitSu = false;
if (null == currUid)
{
retval = false;
exitSu = false;
Log.d("ROOT", "Can't get root access or denied by user");
}
else if (true == currUid.contains("uid=0"))
{
retval = true;
exitSu = true;
Log.d("ROOT", "Root access granted");
}
else
{
retval = false;
exitSu = true;
Log.d("ROOT", "Root access rejected: " + currUid);
}
if (exitSu)
{
os.writeBytes("exit\n");
os.flush();
}
}
}
catch (Exception e)
{
// Can't get root !
// Probably broken pipe exception on trying to write to output stream (os) after su failed, meaning that the device is not rooted
retval = false;
Log.d("ROOT", "Root access rejected [" + e.getClass().getName() + "] : " + e.getMessage());
}
return retval;
}
public final boolean execute()
{
boolean retval = false;
try
{
ArrayList<String> commands = getCommandsToExecute();
if (null != commands && commands.size() > 0)
{
Process suProcess = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
// Execute commands that require root access
for (String currCommand : commands)
{
os.writeBytes(currCommand + "\n");
os.flush();
}
os.writeBytes("exit\n");
os.flush();
try
{
int suProcessRetval = suProcess.waitFor();
if (255 != suProcessRetval)
{
// Root access granted
retval = true;
}
else
{
// Root access denied
retval = false;
}
}
catch (Exception ex)
{
Log.e("ROOT", "Error executing root action", ex);
}
}
}
catch (IOException ex)
{
Log.w("ROOT", "Can't get root access", ex);
}
catch (SecurityException ex)
{
Log.w("ROOT", "Can't get root access", ex);
}
catch (Exception ex)
{
Log.w("ROOT", "Error executing internal operation", ex);
}
return retval;
}
protected abstract ArrayList<String> getCommandsToExecute();
}
Run Code Online (Sandbox Code Playgroud)
我知道一个可能的解决方案是将您的应用程序签名为系统,据我所知,这与root用户不完全相同:如何使用系统签名签署Android应用程序?.但我想这不是你想要的.
我做的另一件事是创建一个本机应用程序,它可以完成所需的操作,并将其作为外部进程运行.但是,如果分区不是nosuid,则必须为此本机应用程序提供所需的权限和suid位.但我想这不是你需要的.
我想,通过JNI调用的C代码应该受到与生活在同一进程中相同的限制.
如果你有苏二进制用那么你可以像运行在Java命令Runtime.getRuntime().exec("su -c reboot").
我不记得任何其他方式.