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();
    }
  }
Example #3
0
 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);
    }
Example #14
0
 public void killradare() {
   RootTools.useRoot = false;
   if (RootTools.isProcessRunning("radare2")) {
     RootTools.killProcess("radare2");
   }
 }