protected boolean returnPath() { File tmpDir = new File("/data/local/tmp"); if (!tmpDir.exists()) { doExec(new String[] {"mkdir /data/local/tmp"}); } try { InternalVariables.path = new HashSet<String>(); // Try to read from the file. LineNumberReader lnr = null; doExec( new String[] { "dd if=/init.rc of=/data/local/tmp/init.rc", "chmod 0777 /data/local/tmp/init.rc" }); lnr = new LineNumberReader(new FileReader("/data/local/tmp/init.rc")); String line; while ((line = lnr.readLine()) != null) { RootTools.log(line); if (line.contains("export PATH")) { int tmp = line.indexOf("/"); InternalVariables.path = new HashSet<String>(Arrays.asList(line.substring(tmp).split(":"))); return true; } } return false; } catch (Exception e) { if (RootTools.debugMode) { RootTools.log("Error: " + e.getMessage()); e.printStackTrace(); } return false; } }
/** * Sends several shell command as su (attempts to) * * @param commands array of commands to send to the shell * @param sleepTime time to sleep between each command, delay. * @param result injected result object that implements the Result class * @return a <code>LinkedList</code> containing each line that was returned by the shell after * executing or while trying to execute the given commands. You must iterate over this list, * it does not allow random access, so no specifying an index of an item you want, not like * you're going to know that anyways. * @throws InterruptedException * @throws IOException * @throws TimeoutException */ synchronized List<String> sendShell( String[] commands, int sleepTime, Result result, boolean useRoot, int timeout) throws IOException, RootToolsException, TimeoutException { RootTools.log( "Sending " + commands.length + " shell command" + (commands.length > 1 ? "s" : "")); Worker worker = new Worker(this, commands, sleepTime, result, useRoot); worker.start(); try { if (timeout == -1) { timeout = 300000; } worker.join(timeout); // small pause, let things catch up Thread.sleep(RootTools.shellDelay); if (worker.exit != -911) return worker.finalResponse; else throw new TimeoutException(); } catch (InterruptedException ex) { worker.interrupt(); Thread.currentThread().interrupt(); throw new TimeoutException(); } }
public String exec(String command) { final StringBuffer radare_output = new StringBuffer(); Command command_out = new Command(0, command) { @Override public void output(int id, String line) { radare_output.append(line); } }; try { RootTools.getShell(RootTools.useRoot); RootTools.getShell(RootTools.useRoot).add(command_out).waitForFinish(); } catch (Exception e) { e.printStackTrace(); } return radare_output.toString(); }
public boolean checkRoot() { boolean result = true; // No need to do more shell calls if we already did the checks if (CHECKED_ROOT && !ROOT_AVAILABLE) // We already checked root and it wasn't available return false; if (!ROOT_AVAILABLE) { if (!RootTools.isRootAvailable()) { // TODO: Make a new dialog class that explains root access RootTools.log("Root access isn't available"); result = false; } else if (!RootTools.isAccessGiven()) { RootTools.log("Root access denied by user"); result = false; } else { ROOT_AVAILABLE = true; } } CHECKED_ROOT = true; return result; }
public boolean checkBusybox() { boolean result = false; // No need to do more shell calls if we already did the checks if (CHECKED_BUSYBOX && !BUSYBOX_INSTALLED) // TODO: Open up a market instance for the busybox installer return false; if (BUSYBOX_INSTALLED || (checkRoot() && RootTools.isBusyboxAvailable())) { result = true; BUSYBOX_INSTALLED = true; } else { // TODO: Make a new dialog class that offers busybox here } CHECKED_BUSYBOX = true; return result; }
private Mount findMountPointRecursive(String file) { try { ArrayList<Mount> mounts = RootTools.getMounts(); for (File path = new File(file); path != null; ) { for (Mount mount : mounts) { if (mount.getMountPoint().equals(path)) { return mount; } } } return null; } catch (IOException e) { throw new RuntimeException(e); } catch (Exception e) { if (RootTools.debugMode) { e.printStackTrace(); } } return null; }
public String sendCommand(String commandString) { String result = ""; if (checkRoot()) { CommandCapture command = new CommandCapture(0, commandString); try { RootTools.getShell(true).add(command).waitForFinish(); result = command.toString(); LAST_COMMAND_OUTPUT = result; LAST_EXIT_CODE = command.exitCode(); } catch (InterruptedException e) { // TODO: Do something useful with the exceptions // e.printStackTrace(); } catch (IOException e) { // e.printStackTrace(); } catch (TimeoutException e) { // e.printStackTrace(); } catch (RootDeniedException e) { // e.printStackTrace(); } } return result; }
protected ArrayList<Mount> getMounts() throws FileNotFoundException, IOException { LineNumberReader lnr = null; try { lnr = new LineNumberReader(new FileReader("/proc/mounts")); String line; ArrayList<Mount> mounts = new ArrayList<Mount>(); while ((line = lnr.readLine()) != null) { RootTools.log(line); String[] fields = line.split(" "); mounts.add( new Mount( new File(fields[0]), // device new File(fields[1]), // mountPoint fields[2], // fstype fields[3] // flags )); } return mounts; } finally { // no need to do anything here. } }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mTextView = new TextView(this); mTextView.setText(""); mScrollView = new ScrollView(this); mScrollView.addView(mTextView); setContentView(mScrollView); // Great the user with our version number String version = "?"; try { PackageInfo packageInfo = this.getPackageManager().getPackageInfo(this.getPackageName(), 0); version = packageInfo.versionName; } catch (PackageManager.NameNotFoundException e) { } print("SanityCheckRootTools v " + version + "\n\n"); try { if (false == RootTools.isAccessGiven()) { print("ERROR: No root access to this device.\n"); return; } } catch (TimeoutException e) { print("ERROR: could not determine root access to this device.\n"); return; } // Display infinite progress bar mPDialog = new ProgressDialog(this); mPDialog.setCancelable(false); mPDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); new SanityCheckThread(this, new TestHandler()).start(); }
public void run() { DataOutputStream os = null; InputStreamReader osRes = null; InputStreamReader osErr = null; try { if (executer.process == null) { Runtime.getRuntime().gc(); if (RootTools.customShell.equals("")) { executer.process = Runtime.getRuntime().exec(useRoot ? "su" : "sh"); RootTools.log(useRoot ? "Using Root" : "Using sh"); } else { executer.process = Runtime.getRuntime().exec(RootTools.customShell); RootTools.log("Using custom shell: " + RootTools.customShell); } if (null != executer.result) { executer.result.setProcess(executer.process); } } os = new DataOutputStream(executer.process.getOutputStream()); osRes = new InputStreamReader(executer.process.getInputStream()); osErr = new InputStreamReader(executer.process.getErrorStream()); BufferedReader reader = new BufferedReader(osRes); BufferedReader reader_error = new BufferedReader(osErr); List<String> response = null; if (null == executer.result) { response = new LinkedList<String>(); } try { // Doing Stuff ;) for (String single : commands) { RootTools.log("Shell command: " + single); os.writeBytes(single + "\n"); os.flush(); Thread.sleep(sleepTime); } os.writeBytes("exit \n"); os.flush(); String line = reader.readLine(); String line_error = reader_error.readLine(); while (line != null) { if (null == executer.result) { response.add(line); } else { executer.result.process(line); } RootTools.log("input stream: " + line); line = reader.readLine(); } RootTools.log("Done reading input stream"); while (line_error != null) { if (null == executer.result) { response.add(line_error); } else { executer.result.processError(line_error); } RootTools.log("error stream: " + line_error); line_error = reader_error.readLine(); } RootTools.log("Done reading error stream"); } catch (Exception ex) { if (RootTools.debugMode) { RootTools.log("Error: " + ex.getMessage()); } if (null != executer.result) { executer.result.onFailure(ex); } } finally { RootTools.log("In finally block"); if (executer.process != null) { RootTools.log("Getting Exit"); finalResponse = response; exit = -1; exit = executer.process.waitFor(); RootTools.log("Exit done..."); RootTools.lastExitCode = exit; if (null != executer.result) { executer.result.onComplete(exit); } else { response.add(Integer.toString(exit)); } } } } catch (InterruptedException ignore) { return; } catch (Exception e) { if (RootTools.debugMode) { e.printStackTrace(); RootTools.log("Error: " + e.getMessage()); } } finally { try { if (os != null) { os.writeBytes("exit \n"); os.flush(); os.close(); os = null; } if (osRes != null) { osRes.close(); osRes = null; } if (osErr != null) { osErr.close(); osErr = null; } } catch (Exception ignore) { } executer.closeShell(); } }
/** * This will take a path, which can contain the file name as well, and attempt to remount the * underlying partition. * * <p>For example, passing in the following string: * "/system/bin/some/directory/that/really/would/never/exist" will result in /system ultimately * being remounted. However, keep in mind that the longer the path you supply, the more work this * has to do, and the slower it will run. * * @param file file path * @param mountType mount type: pass in RO (Read only) or RW (Read Write) * @return a <code>boolean</code> which indicates whether or not the partition has been remounted * as specified. */ protected boolean remount(String file, String mountType) { // if the path has a trailing slash get rid of it. if (file.endsWith("/") && !file.equals("/")) { file = file.substring(0, file.lastIndexOf("/")); } // Make sure that what we are trying to remount is in the mount list. boolean foundMount = false; while (!foundMount) { try { for (Mount mount : RootTools.getMounts()) { RootTools.log(mount.getMountPoint().toString()); if (file.equals(mount.getMountPoint().toString())) { foundMount = true; break; } } } catch (Exception e) { if (RootTools.debugMode) { e.printStackTrace(); } return false; } if (!foundMount) { try { file = (new File(file).getParent()).toString(); } catch (Exception e) { e.printStackTrace(); return false; } } } Mount mountPoint = findMountPointRecursive(file); RootTools.log( InternalVariables.TAG, "Remounting " + mountPoint.getMountPoint().getAbsolutePath() + " as " + mountType.toLowerCase()); final boolean isMountMode = mountPoint.getFlags().contains(mountType.toLowerCase()); if (!isMountMode) { // grab an instance of the internal class try { CommandCapture command = new CommandCapture( 0, "busybox mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(), "toolbox mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(), "mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(), "/system/bin/toolbox mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath()); Shell.startRootShell().add(command); command.waitForFinish(); } catch (Exception e) { } mountPoint = findMountPointRecursive(file); } Log.i(InternalVariables.TAG, mountPoint.getFlags() + " AND " + mountType.toLowerCase()); if (mountPoint.getFlags().contains(mountType.toLowerCase())) { RootTools.log(mountPoint.getFlags().toString()); return true; } else { RootTools.log(mountPoint.getFlags().toString()); return false; } }
protected void doExec(String[] commands) { Process process = null; DataOutputStream os = null; InputStreamReader osRes = null; try { process = Runtime.getRuntime().exec("su"); os = new DataOutputStream(process.getOutputStream()); osRes = new InputStreamReader(process.getInputStream()); BufferedReader reader = new BufferedReader(osRes); // Doing Stuff ;) for (String single : commands) { os.writeBytes(single + "\n"); os.flush(); } os.writeBytes("exit \n"); os.flush(); String line = reader.readLine(); while (line != null) { if (commands[0].equals("id")) { Set<String> ID = new HashSet<String>(Arrays.asList(line.split(" "))); for (String id : ID) { if (id.toLowerCase().contains("uid=0")) { InternalVariables.accessGiven = true; Log.i(InternalVariables.TAG, "Access Given"); break; } } if (!InternalVariables.accessGiven) { Log.i(InternalVariables.TAG, "Access Denied?"); } } if (commands[0].equals("df") && line.contains(InternalVariables.getSpaceFor)) { InternalVariables.space = line.split(" "); } RootTools.log(line); line = reader.readLine(); } process.waitFor(); } catch (Exception e) { if (RootTools.debugMode) { RootTools.log("Error: " + e.getMessage()); e.printStackTrace(); } } finally { try { if (os != null) { os.close(); } if (osRes != null) { osRes.close(); } process.destroy(); } catch (Exception e) { if (RootTools.debugMode) { RootTools.log("Error: " + e.getMessage()); e.printStackTrace(); } } } }
public void run() { visualUpdate(TestHandler.ACTION_SHOW, null); // First test: Install a binary file for future use // if it wasn't already installed. /* visualUpdate(TestHandler.ACTION_PDISPLAY, "Installing binary if needed"); if(false == RootTools.installBinary(mContext, R.raw.nes, "nes_binary")) { visualUpdate(TestHandler.ACTION_HIDE, "ERROR: Failed to install binary. Please see log file."); return; } */ visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing df"); long spaceValue = RootTools.getSpace("/data"); visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking /data partition size]\n"); visualUpdate(TestHandler.ACTION_DISPLAY, spaceValue + "k\n\n"); visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing sendShell() w/ return array"); try { List<String> response = RootTools.sendShell("ls /", InternalVariables.timeout); visualUpdate(TestHandler.ACTION_DISPLAY, "[ Listing of / (passing a List)]\n"); for (String line : response) { visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n"); } } catch (IOException e) { visualUpdate(TestHandler.ACTION_HIDE, "ERROR: " + e); return; } catch (RootToolsException e) { visualUpdate(TestHandler.ACTION_HIDE, "DEV-DEFINED ERROR: " + e); return; } catch (TimeoutException e) { visualUpdate(TestHandler.ACTION_HIDE, "Timeout.. " + e); return; } visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing sendShell() w/ callbacks"); try { visualUpdate(TestHandler.ACTION_DISPLAY, "\n[ Listing of / (callback)]\n"); RootTools.Result result = new RootTools.Result() { @Override public void process(String line) throws Exception { visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n"); } @Override public void onFailure(Exception ex) { visualUpdate(TestHandler.ACTION_HIDE, "ERROR: " + ex); setError(1); } @Override public void onComplete(int diag) { visualUpdate(TestHandler.ACTION_DISPLAY, "------\nDone.\n"); } @Override public void processError(String line) throws Exception { visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n"); } }; RootTools.sendShell("ls /", result, InternalVariables.timeout); if (0 != result.getError()) return; } catch (IOException e) { visualUpdate(TestHandler.ACTION_HIDE, "ERROR: " + e); return; } catch (RootToolsException e) { visualUpdate(TestHandler.ACTION_HIDE, "DEV-DEFINED ERROR: " + e); return; } catch (TimeoutException e) { visualUpdate(TestHandler.ACTION_HIDE, "Timeout.. " + e); return; } visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing sendShell() for multiple commands"); try { visualUpdate(TestHandler.ACTION_DISPLAY, "\n[ ps + ls + date / (callback)]\n"); RootTools.Result result = new RootTools.Result() { @Override public void process(String line) throws Exception { visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n"); } @Override public void onFailure(Exception ex) { visualUpdate(TestHandler.ACTION_HIDE, "ERROR: " + ex); setError(1); } @Override public void onComplete(int diag) { visualUpdate(TestHandler.ACTION_DISPLAY, "------\nDone.\n"); } @Override public void processError(String line) throws Exception { visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n"); } }; RootTools.sendShell( new String[] { "echo \"* PS:\"", "ps", "echo \"* LS:\"", "ls", "echo \"* DATE:\"", "date" }, 2000, result, InternalVariables.timeout); if (0 != result.getError()) return; } catch (IOException e) { visualUpdate(TestHandler.ACTION_HIDE, "ERROR: " + e); } catch (RootToolsException e) { visualUpdate(TestHandler.ACTION_HIDE, "DEV-DEFINED ERROR: " + e); } catch (TimeoutException e) { visualUpdate(TestHandler.ACTION_HIDE, "Timeout.. " + e); return; } visualUpdate(TestHandler.ACTION_PDISPLAY, "All tests complete."); visualUpdate(TestHandler.ACTION_HIDE, null); }
public void killradare() { RootTools.useRoot = false; if (RootTools.isProcessRunning("radare2")) { RootTools.killProcess("radare2"); } }