Giter VIP home page Giter VIP logo

rootfw's Introduction

RootFW

An Android Root Shell Framework

Usage

RootFW is a tool that helps Android Applications act as root. The only way for an application to perform tasks as root, is by executing shell commands as Android has no native way of doing this. However, due to different types of shell support on different devices/ROM's (Shell type, busybox/toolbox versions etc.), this is not an easy task. RootFW comes with a lot of pre-built methods to handle the most common tasks. Each method tries to support as many different environments as possible by implementing different approaches for each environment. This makes the work of app developers a lot easier.

Unlike other Root methods, RootFW does not reconnect/exit on each command. Once an instance has been created, the connection to the shell will stay open until the close() method is called. This means that you can execute as many commands as you like without the SuperUser Toast going crazy on the users screen.

RootFW root = new RootFW();

if (root.connected()) {
    ShellResult result = root.shell.execute("ls -1 /system");

    if (result != null && result.code() == 0) {
        String[] output = result.output().raw();

        for (int i=0; i < output.length; i++) {
            ...
        }
    }
}

root.close();

RootFW can also return named instances which allows for clones to be returned containing the same shell connection as it's parent instance. This means that you can access the same shell connection across application classes/methods without parsing the instance manually.

/* Sample 1 */

// This will create and return a new instance
RootFW root = RootFW.instance("MyInstance");
 
root.shell.execute("...");

// Call another method
helperMethod();

// helperMethod was not allowed to close the connection, so this will work fine
root.shell.execute("...");

// This will close the shell connection
root.close(); 
/* Sample 2 */

public void helperMethod() {
    // This will create and return a clone using the same shell connection
    RootFW root = RootFW.instance("MyInstance");

    root.shell.execute("...");

    // This will do nothing as clones is not allowed to close connections
    root.close(); 
}

We call for the instance MyInstance in both Sample 1 and Sample 2. However, since the instance has not yet been created in Sample 1, RootFW will create and return a new one. When we call helperMethod in Sample 2, the instance is still active as we have yet to call close() in Sample 1. So here it will instead return a clone containing the same shell connection as used in Sample 1. And because helperMethod get's a clone, it is not allowed to close the connection which means that we can keep executing shell commands in Sample 1, althought Sample 2 made a call to close().

Using RootFW you can also add multiple command entries which will stop at the first command entry that returns 0. This makes it easy to add better support for different environments.

ShellResult result = root.shell.execute("mv file1 file2", "cat file1 > file2 && unlink file1");

If the device supports "mv", then the second command will not be executed. But if the first entry fails, it will move to the second command. Using this feature, RootFW adds an easier way to use different all-in-one binary environments.

ShellResult result = root.shell.execute( ShellProcess.generate("%binary mv file1 file2") );

The above will generate one command entry per index in ShellProcess.BINARIES[]. By default it will generate {"busybox mv file1 file2", "toolbox mv file1 file2", "mv file1 file2"}

If you want to use different binaries across RootFW, just modify BINARIES[]

ShellProcess.BINARIES = new String[] {"/path/to/my/custom/busybox", "busybox", "toolbox"};

ShellResult result = root.shell.execute( ShellProcess.generate("%binary mv file1 file2") );

Now /path/to/my/custom/busybox will be used as default and the others will be used to fallback on if the custom one lacks support for a specific command.

By default RootFW will stop at the first command entry that returns 0 (Normally means success). But you can also add other result codes to be seen as successful.

ShellProcess process = new ShellProcess();
process.addCommand("exit 255");
process.addCommand("exit 130");
process.addCommand("exit 0");
process.addResultCode(130);

ShellResult result = root.shell.execute(process);

RootFW will now stop at the second command as you have added result code 130 to the ShellProcess instance.

You may also want to execute commands without root at some point. Using root will for an example have SuperUser creating Toast messages. To do this, simply add a boolean false when creating the instance.

// Get a non-root instance
RootFW user = new RootFW(false);

// Get a non-root instance using the 'instance' method
RootFW user = RootFW.instance("MyInstance", false);

Note that when using RootFW.instance(), you can have two instances with the same name. One with root and one without. Calling RootFW.instance() with a false boolean will not return an already existing root instance with the same name.

Examples

Like mentioned before, RootFW has a lot of pre-built tools called extenders to help make the job faster and easier. An extender is a group class containing a lot of tools matching each group type. RootFW has the fallowing extenders: Shell, File, Filesystem, Binary, Busybox, Memory, Processes and Utils.

  • Folder Content
    RootFW root = new RootFW();
    
    if (root.connected()) {
        ArrayList<FileStat> statlist = root.file.statList("/system");
        FileStat stat;
    
        if (statlist != null) {
            for (int i=0; i < statlist.size(); i++) {
                stat = statlist.get(i);
    
                System.out.print("[" + stat.type() + "] " + stat.name() + " (" + stat.size() + " bytes), " + stat.access() + ""));
            }
        }
    }

  • List Memory Information
    RootFW root = new RootFW();
    
    if (root.connected()) {
        MemStat stat = root.memory.usage();
    
        System.out.print("Used " + stat.memUsage() + " bytes of " + stat.memTotal() + " bytes, " + stat.memPercentage() + "%");
    }

  • Launch an Update.zip in Recovery
    RootFW root = new RootFW();
    
    if (root.connected()) {
        root.utils.recoveryInstall(context, R.raw.package);
    }

  • Remount /system as RW
    RootFW root = new RootFW();
    
    if (root.connected()) {
        root.filesystem.mount("/system", new String[]{"remount", "rw"});
    }

  • Mount an sd-ext partition
    RootFW root = new RootFW();
    
    if (root.connected()) {
        // Make sure that the directory exists
        if (!root.file.check("/sd-ext", "d")) {
            root.filesystem.mount("/", new String[]{"remount", "rw"});
            root.file.create("/sd-ext");
            root.filesystem.mount("/", new String[]{"remount", "ro"});
        }
    
        root.filesystem.mount("/dev/block/mmcblk0p2", "/sd-ext", "ext4", new String[]{"relatime", "noatime", "nodev"});
    }

  • Bind two folders
    RootFW root = new RootFW();
    
    if (root.connected()) {
        root.filesystem.mount("/sd-ext/app-asec", "/data/app-asec");
    }

  • Shutdown the device
    RootFW root = new RootFW();
    
    if (root.connected()) {
        root.processes.shutdown();
    }

  • Check if Busybox is available
    RootFW root = new RootFW();
    
    if (root.connected()) {
        if (root.busybox.exists()) {
            ...
        }
    }

  • Get device mount location
    RootFW root = new RootFW();
    
    if (root.connected()) {
        DiskStat stat = root.filesystem.statDisk("/dev/block/mmcblk0p2");
    
        System.out.print( stat.location() );
    }

Check the Documentation for further information about all of the available tools

License

Copyright (c) 2013 Daniel Bergløv

RootFW is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

RootFW is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with RootFW. If not, see http://www.gnu.org/licenses/

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.