I am trying to write a file, generated by my app, onto the system partition. As I can not create an FileOutputStream inside my app I create the file in the data directory of my app, correct the permissions and then move it to the system partition.
At the moment the code below misses the writable remount of /system - for testing purposes I have performed this step successfully via adb remount
- therefore this should not be the problem.
The app also gets successfully root permissions.
But the code below does not work. It only creates the file but does not move it to the system partition. What's my mistake?
FileOutputStream out = openFileOutput("myfile.test", MODE_WORLD_READABLE);
File f = getFileStreamPath("myfile.test");
writeDataToOutputStream(out);
out.close();
String filename = f.getAbsolutePath();
Runtime r = Runtime.getRuntime();
r.exec("su");
// Waiting here some seconds does not make any difference
r.exec(new String[] { "chown", "root.root", filename });
r.exec(new String[] { "chmod", "644", filename });
r.exec(new String[] { "mv", filename, "/system/myfile.test" });
My guess is that only the first call to Runtime.exec()
:
r.exec("su");
acheives root. The docs for Runtime.exec()
say that each invocation runs as a separate process. So all of the subsequent calls to exec
, for chown
, chmod
, mv
all run with the permissions of the current app process - and hence fail.
You might be able to write a small shell script, then pass the shell script as an argument to su
. Then all the commands would get run with root permission.
OK, I found how to execute multiple commands with root permissions. The trick is to send all commands to the one su process:
FileOutputStream out = openFileOutput("myfile.test", MODE_WORLD_READABLE);
File f = getFileStreamPath("myfile.test");
writeDataToOutputStream(out);
out.close();
String filename = f.getAbsolutePath();
Runtime r = Runtime.getRuntime();
Process suProcess = r.exec("su");
DataOutputStream dos = new DataOutputStream(suProcess.getOutputStream());
dos.writeBytes("chown 0.0 " + filename + "\n");
dos.flush();
dos.writeBytes("chmod 644 " + filename + "\n");
dos.flush();
dos.writeBytes("mv " + filename + " /system/myfile.test\n");
dos.flush();
The only thing left (not include din the code above) is to make /system
writable.
May be one additional command like mount -o rw,remount /system
is sufficient - will test that.