├── .gitignore ├── ExampleApp ├── .gitignore ├── build.gradle ├── jni │ ├── Android.mk │ ├── Application.mk │ └── hello_world │ │ ├── Android.mk │ │ └── hello_world.c ├── libs │ ├── mips │ │ └── libhello_world_bin.so │ └── x86 │ │ └── libhello_world_bin.so └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── org │ │ └── sufficientlysecure │ │ └── rootcommands │ │ └── demo │ │ └── BaseActivity.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-ldpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── layout │ └── main.xml │ └── values │ └── strings.xml ├── LICENSE ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── libraries └── RootCommands │ ├── .gitignore │ ├── build.gradle │ └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── sufficientlysecure │ └── rootcommands │ ├── Mount.java │ ├── Remounter.java │ ├── RootCommands.java │ ├── Shell.java │ ├── SystemCommands.java │ ├── Toolbox.java │ ├── command │ ├── Command.java │ ├── ExecutableCommand.java │ ├── SimpleCommand.java │ └── SimpleExecutableCommand.java │ └── util │ ├── BrokenBusyboxException.java │ ├── Log.java │ ├── RootAccessDeniedException.java │ ├── UnsupportedArchitectureException.java │ └── Utils.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | #Android specific 2 | bin 3 | gen 4 | obj 5 | libs/armeabi 6 | lint.xml 7 | local.properties 8 | release.properties 9 | ant.properties 10 | *.class 11 | *.apk 12 | 13 | #Gradle 14 | .gradle 15 | build 16 | gradle.properties 17 | gradle-app.setting 18 | 19 | #Maven 20 | target 21 | pom.xml.* 22 | 23 | #Eclipse 24 | .project 25 | .classpath 26 | .settings 27 | .metadata 28 | 29 | #IntelliJ IDEA 30 | .idea 31 | *.iml 32 | -------------------------------------------------------------------------------- /ExampleApp/.gitignore: -------------------------------------------------------------------------------- 1 | #Android specific 2 | bin 3 | gen 4 | obj 5 | libs/armeabi 6 | lint.xml 7 | local.properties 8 | release.properties 9 | ant.properties 10 | *.class 11 | *.apk 12 | 13 | #Gradle 14 | .gradle 15 | build 16 | gradle.properties 17 | gradlew 18 | gradlew.bat 19 | gradle 20 | 21 | #Maven 22 | target 23 | pom.xml.* 24 | 25 | #Eclipse 26 | .project 27 | .classpath 28 | .settings 29 | .metadata 30 | 31 | #IntelliJ IDEA 32 | .idea 33 | *.iml 34 | -------------------------------------------------------------------------------- /ExampleApp/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'android' 2 | 3 | dependencies { 4 | compile project(':libraries:RootCommands') 5 | } 6 | 7 | android { 8 | compileSdkVersion 17 9 | buildToolsVersion "17.0.0" 10 | 11 | defaultConfig { 12 | minSdkVersion 7 13 | targetSdkVersion 17 14 | } 15 | } 16 | 17 | /** 18 | * Android Gradle Plugin 0.4 does not support library packaging. 19 | * This is a hack from https://groups.google.com/d/msg/adt-dev/Dkf9nsZlq8I/3gtG1Ofu1zAJ 20 | */ 21 | tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask -> 22 | pkgTask.jniDir new File(projectDir, 'libs') 23 | } 24 | 25 | /** 26 | * Task to rename executables from hello_world to libhello_world_exec.so 27 | * If they look like libraries, they are packaged in the apk and deployed on the device in the lib folder! 28 | * 29 | * http://www.gradle.org/docs/current/userguide/working_with_files.html 30 | */ 31 | task renameExecutables(type: Copy) { 32 | from 'libs' 33 | into 'libs' 34 | include '**/*' 35 | exclude '**/*.so' 36 | exclude '**/*.jar' 37 | 38 | rename(/(.+)/, 'lib$1_exec.so') 39 | } 40 | 41 | 42 | build.dependsOn renameExecutables -------------------------------------------------------------------------------- /ExampleApp/jni/Android.mk: -------------------------------------------------------------------------------- 1 | include $(call all-subdir-makefiles) -------------------------------------------------------------------------------- /ExampleApp/jni/Application.mk: -------------------------------------------------------------------------------- 1 | # Optimizations 2 | APP_OPTIM := release 3 | 4 | # Build target 5 | APP_ABI := armeabi x86 mips 6 | #APP_ABI := armeabi armeabi-v7a x86 mips 7 | 8 | # If APP_MODULES is not set, all modules are compiled! 9 | APP_MODULES := hello_world -------------------------------------------------------------------------------- /ExampleApp/jni/hello_world/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | LOCAL_SRC_FILES := hello_world.c 5 | LOCAL_LDLIBS := -llog 6 | 7 | LOCAL_MODULE := hello_world 8 | 9 | include $(BUILD_EXECUTABLE) -------------------------------------------------------------------------------- /ExampleApp/jni/hello_world/hello_world.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | // from http://www.enderunix.org/documents/eng/daemon.php 9 | void daemonize() 10 | { 11 | int i,lfp; 12 | char str[10]; 13 | if(getppid()==1) return; /* already a daemon */ 14 | i=fork(); 15 | if (i<0) exit(1); /* fork error */ 16 | if (i>0) exit(0); /* parent exits */ 17 | /* child (daemon) continues */ 18 | setsid(); /* obtain a new process group */ 19 | } 20 | 21 | int main(void) { 22 | __android_log_print(ANDROID_LOG_INFO,"Demo", "Starting Hello World daemon..."); 23 | 24 | daemonize(); 25 | 26 | __android_log_print(ANDROID_LOG_INFO,"Demo", "Hello World daemon started!"); 27 | 28 | while (1) { 29 | sleep(1); 30 | } 31 | 32 | return 0; 33 | } -------------------------------------------------------------------------------- /ExampleApp/libs/mips/libhello_world_bin.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Free-Software-for-Android/RootCommands/63b4783c7d4873690cf39989d9c9f8399c073ddb/ExampleApp/libs/mips/libhello_world_bin.so -------------------------------------------------------------------------------- /ExampleApp/libs/x86/libhello_world_bin.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Free-Software-for-Android/RootCommands/63b4783c7d4873690cf39989d9c9f8399c073ddb/ExampleApp/libs/x86/libhello_world_bin.so -------------------------------------------------------------------------------- /ExampleApp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ExampleApp/src/main/java/org/sufficientlysecure/rootcommands/demo/BaseActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Dominik Schürmann 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.sufficientlysecure.rootcommands.demo; 18 | 19 | import org.sufficientlysecure.rootcommands.RootCommands; 20 | import org.sufficientlysecure.rootcommands.Shell; 21 | import org.sufficientlysecure.rootcommands.Toolbox; 22 | import org.sufficientlysecure.rootcommands.command.Command; 23 | import org.sufficientlysecure.rootcommands.command.SimpleExecutableCommand; 24 | import org.sufficientlysecure.rootcommands.command.SimpleCommand; 25 | 26 | import android.app.Activity; 27 | import android.os.Bundle; 28 | import android.util.Log; 29 | import android.view.View; 30 | 31 | public class BaseActivity extends Activity { 32 | public static final String TAG = "Demo"; 33 | 34 | @Override 35 | public void onCreate(Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | setContentView(R.layout.main); 38 | 39 | // enable debug logging 40 | RootCommands.DEBUG = true; 41 | } 42 | 43 | private class MyCommand extends Command { 44 | private static final String LINE = "hosts"; 45 | boolean found = false; 46 | 47 | public MyCommand() { 48 | super("ls -la /system/etc/"); 49 | } 50 | 51 | public boolean isFound() { 52 | return found; 53 | } 54 | 55 | @Override 56 | public void output(int id, String line) { 57 | if (line.contains(LINE)) { 58 | Log.d(TAG, "Found it!"); 59 | found = true; 60 | } 61 | } 62 | 63 | @Override 64 | public void afterExecution(int id, int exitCode) { 65 | } 66 | 67 | } 68 | 69 | public void commandsTestOnClick(View view) { 70 | try { 71 | // start root shell 72 | Shell shell = Shell.startRootShell(); 73 | 74 | // simple commands 75 | SimpleCommand command0 = new SimpleCommand("echo this is a command", 76 | "echo this is another command"); 77 | SimpleCommand command1 = new SimpleCommand("toolbox ls"); 78 | SimpleCommand command2 = new SimpleCommand("ls -la /system/etc/hosts"); 79 | 80 | shell.add(command0).waitForFinish(); 81 | shell.add(command1).waitForFinish(); 82 | shell.add(command2).waitForFinish(); 83 | 84 | Log.d(TAG, "Output of command2: " + command2.getOutput()); 85 | Log.d(TAG, "Exit code of command2: " + command2.getExitCode()); 86 | 87 | // custom command classes: 88 | MyCommand myCommand = new MyCommand(); 89 | shell.add(myCommand).waitForFinish(); 90 | 91 | Log.d(TAG, "myCommand.isFound(): " + myCommand.isFound()); 92 | 93 | // close root shell 94 | shell.close(); 95 | } catch (Exception e) { 96 | Log.e(TAG, "Exception!", e); 97 | } 98 | } 99 | 100 | public void toolboxTestOnClick(View view) { 101 | try { 102 | Shell shell = Shell.startRootShell(); 103 | 104 | Toolbox tb = new Toolbox(shell); 105 | 106 | if (tb.isRootAccessGiven()) { 107 | Log.d(TAG, "Root access given!"); 108 | } else { 109 | Log.d(TAG, "No root access!"); 110 | } 111 | 112 | Log.d(TAG, tb.getFilePermissions("/system/etc/hosts")); 113 | 114 | shell.close(); 115 | } catch (Exception e) { 116 | Log.e(TAG, "Exception!", e); 117 | } 118 | } 119 | 120 | public void binariesTestOnClick(View view) { 121 | try { 122 | SimpleExecutableCommand binaryCommand = new SimpleExecutableCommand(this, "hello_world", ""); 123 | 124 | // started as normal shell without root, but you can also start your binaries on a root 125 | // shell if you need more privileges! 126 | Shell shell = Shell.startShell(); 127 | 128 | shell.add(binaryCommand).waitForFinish(); 129 | 130 | Toolbox tb = new Toolbox(shell); 131 | if (tb.killAllExecutable("hello_world")) { 132 | Log.d(TAG, "Hello World daemon killed!"); 133 | } else { 134 | Log.d(TAG, "Killing failed!"); 135 | } 136 | 137 | shell.close(); 138 | } catch (Exception e) { 139 | Log.e(TAG, "Exception!", e); 140 | } 141 | } 142 | 143 | } -------------------------------------------------------------------------------- /ExampleApp/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Free-Software-for-Android/RootCommands/63b4783c7d4873690cf39989d9c9f8399c073ddb/ExampleApp/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /ExampleApp/src/main/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Free-Software-for-Android/RootCommands/63b4783c7d4873690cf39989d9c9f8399c073ddb/ExampleApp/src/main/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /ExampleApp/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Free-Software-for-Android/RootCommands/63b4783c7d4873690cf39989d9c9f8399c073ddb/ExampleApp/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /ExampleApp/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Free-Software-for-Android/RootCommands/63b4783c7d4873690cf39989d9c9f8399c073ddb/ExampleApp/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ExampleApp/src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 |