package com.psmreborn.nopsmdrm; import android.content.Context; import android.util.Log; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import eu.chainfire.libsuperuser.Shell; public class Root { private static String busyboxBinary = null; private static Context ctx = null; public static boolean fileExistRoot(String filename) throws Shell.ShellDiedException { Log.i("ROOT", "FileExistRoot: " + filename); int res = Shell.Pool.SU.run(new String[] { busyboxBinary + " stat '" + filename +"'" }); return res == 0; } public static void tarRoot(String src, String dst) throws IOException, Shell.ShellDiedException { Log.i("ROOT", "TarRoot: " + src + " : "+ dst); int res = Shell.Pool.SU.run(new String[]{busyboxBinary + " tar c '" + src + "' -f '" + dst +"'"}); if (res != 0) { throw new IOException("Failed to tar " + src); } } public static void remountRo(String foldername) throws IOException, Shell.ShellDiedException { Log.i("ROOT", "Remounting as RO: " + foldername); int res = Shell.Pool.SU.run(new String[] { busyboxBinary +" mount -o ro,remount '"+foldername+"'"} ); if(res != 0){ throw new IOException("Failed to remmount as RO: "+foldername); } } public static void remountRw(String foldername) throws IOException, Shell.ShellDiedException { Log.i("ROOT", "Remounting as RW: " + foldername); int res = Shell.Pool.SU.run(new String[] { busyboxBinary +" mount -o rw,remount '"+foldername+"'"} ); if(res != 0){ throw new IOException("Failed to remmount as RW: "+foldername); } } public static void moveFileRoot(String filename, String destFilename) throws IOException, Shell.ShellDiedException { Log.i("ROOT", "MoveRoot: " + filename + " : "+ destFilename); int res = Shell.Pool.SU.run(new String[] { busyboxBinary +" mv '"+ filename + "' '" +destFilename +"'"}); if(res != 0){ throw new IOException("Failed to rename "+filename+" to "+ destFilename); } } public static void mkdirAndChmodChown(String directory, int chmod, String chown) throws Shell.ShellDiedException { Log.i("ROOT", "MkdirAndChown: " + directory); Shell.Pool.SU.run(new String[]{ busyboxBinary + " mkdir '" + directory +"'", busyboxBinary + " chmod " + String.valueOf(chmod) +" '"+directory+"'", busyboxBinary + " chown " + chown +":"+chown+" '"+directory+"'" }); } public static void copyChmodAndChown(String srcFile, String dstFile, int chmod, String chown) throws IOException, Shell.ShellDiedException { Log.i("ROOT", "CopyAndChown: " + srcFile +" : "+dstFile); int res = Shell.Pool.SU.run(new String[]{ busyboxBinary + " cp '" + srcFile +"' '"+dstFile+"'", busyboxBinary + " chmod " + String.valueOf(chmod) +" '"+dstFile+"'", busyboxBinary + " chown " + chown +":"+chown+" '"+dstFile+"'" }); if(res != 0){ throw new IOException("Failed to copy & change mode."); } } private static void copyTo(InputStream inpStream, OutputStream outStream) throws IOException { int totalRead = 0; byte[] buffer = new byte[0x1000]; do { totalRead = inpStream.read(buffer, 0, buffer.length); outStream.write(buffer, 0, totalRead); } while(totalRead >= buffer.length); outStream.flush(); } public static void unpackResourceToLocationRoot(int resourceId, String outputDir, int chmod, String chown) throws IOException, Shell.ShellDiedException { Log.i("ROOT", "Unpacking resource and root copying to : " + outputDir); File tmpFile = File.createTempFile("tmp", "file", ctx.getCacheDir()); tmpFile.createNewFile(); unpackResource(resourceId, tmpFile); copyChmodAndChown(tmpFile.getAbsolutePath(), outputDir, chmod, chown); tmpFile.delete(); } private static void unpackResource(int resourceId, File outputFile) throws IOException { Log.i("ROOT", "Unpacking resource to : " + outputFile); InputStream resourceStream = ctx.getResources().openRawResource(resourceId); FileOutputStream fs = new FileOutputStream(outputFile, false); copyTo(resourceStream, fs); fs.close(); resourceStream.close(); } public static void writeTxtFile(String txtFile, String txt) throws IOException { Log.i("ROOT", "Writing: " + txtFile); FileWriter txtStream = new FileWriter(txtFile); txtStream.write(txt); txtStream.close(); } private static void setupBusyBox() throws IOException { Log.i("ROOT","Creating busybox binary"); File tmpFile = new File(ctx.getCacheDir(), "busybox"); if(!tmpFile.exists()){ tmpFile.createNewFile(); if(tmpFile.setExecutable(true,false)) { unpackResource(R.raw.busybox, tmpFile); } else { throw new IOException("failed to extract busybox binary."); } } busyboxBinary = tmpFile.getAbsolutePath(); } public static void setContext(Context context) throws IOException { ctx = context; setupBusyBox(); } }