Sei sulla pagina 1di 25

FACULTY NAME- Prof.

NITHYANANDAM P

SUBMITTED TO DIVISION OF

COMPUTER SCIENCE AND ENGINEERING

VIT CHENNAI

SUBMITTED BY

MALLIKA CHOWDHARY 15BCE1119

MAHIMA GUPTA 15BCE1210


ABSTRACT

In Linux, the root user has all rights. root can read, write and execute any
file in any directory. All other user's permissions can also be edited by root.

On an Android phone, each app runs as a separate user. eg. The app
Calendar may be running as user cal_01. None of the apps can become
root, and thus cannot have complete access to all filesystems.

The rooting process is by which we somehow gain access to the root user
of an Android device. Once a device is successfully rooted any app can be
given root permissions. Thus any app can now run as the root user and
access all data on the phone and change anything it wants to.

ADB is a bridge for developers to work out bugs in their Android applications.
This is done by connecting a device that runs the software through a PC, and
feeding it terminal commands. ADB lets you modify your device (or devices
software) via a PC command line

INTRODUCTION OF WORK

There are several benefits to rooting.Some are as follows:-

1. Improved performance:You can speed up your Android device by


relocating your phones cache, thus allowing you to save phone memory
and have a faster phone.

2. Altering system files:You can replace many parts of the Android core.
Doing so, you can add new themes, edit the core apps,binaries etc.
3. More application choices:You will be able to install apps that are only
compatible with rooted phones .eg over clocking apps,tethering etc.

4. Latest Android OS (operating system):With many


manufacturers(<cough,cough>Huawei,Sony Ericsson etc.) holding back
the updates to the latest Android operating system, rooting your device
will give you the option to install any current and future OSs by
installing custom-tailored ROMs.Also,you can try ROMs with many
useful features

CODE

public abstract class ExecuteAsRootBase


{
public static boolean canRunRootCommands()
{
boolean retval = false;
Process suProcess;

try
{
suProcess = Runtime.getRuntime().exec("su");

DataOutputStream os = new
DataOutputStream(suProcess.getOutputStream());
DataInputStream osRes = new DataInputStream(suProcess.getInputStream());

if (null != os && null != osRes)


{
// Getting the id of the current user to check if this is root
os.writeBytes("id\n");
os.flush();

String currUid = osRes.readLine();


boolean exitSu = false;
if (null == currUid)
{
retval = false;
exitSu = false;
Log.d("ROOT", "Can't get root access or denied by user");
}
else if (true == currUid.contains("uid=0"))
{
retval = true;
exitSu = true;
Log.d("ROOT", "Root access granted");
}
else
{
retval = false;
exitSu = true;
Log.d("ROOT", "Root access rejected: " + currUid);
}

if (exitSu)
{
os.writeBytes("exit\n");
os.flush();
}
}
}
catch (Exception e)
{
// Can't get root !
// Probably broken pipe exception on trying to write to output stream (os) after
su failed, meaning that the device is not rooted

retval = false;
Log.d("ROOT", "Root access rejected [" + e.getClass().getName() + "] : " +
e.getMessage());
}

return retval;
}

public final boolean execute()


{
boolean retval = false;

try
{
ArrayList<String> commands = getCommandsToExecute();
if (null != commands && commands.size() > 0)
{
Process suProcess = Runtime.getRuntime().exec("su");

DataOutputStream os = new
DataOutputStream(suProcess.getOutputStream());

// Execute commands that require root access


for (String currCommand : commands)
{
os.writeBytes(currCommand + "\n");
os.flush();
}
os.writeBytes("exit\n");
os.flush();

try
{
int suProcessRetval = suProcess.waitFor();
if (255 != suProcessRetval)
{
// Root access granted
retval = true;
}
else
{
// Root access denied
retval = false;
}
}
catch (Exception ex)
{
Log.e("ROOT", "Error executing root action", ex);
}
}
}
catch (IOException ex)
{
Log.w("ROOT", "Can't get root access", ex);
}
catch (SecurityException ex)
{
Log.w("ROOT", "Can't get root access", ex);
}
catch (Exception ex)
{
Log.w("ROOT", "Error executing internal operation", ex);
}

return retval;
}
protected abstract ArrayList<String> getCommandsToExecute();
}

PROPOSED METHODOLOGY OF ROOTING


There are some devices that are relatively friendly to rooting like Nexus phones and
tablets. They have unlockablebootloaders and can be rooted with almost no legwork.
They also have system images that can be used to restore the device in case
something goes wrong.

Rooting should be tried on suck phones to avoid risk involved.

Further rooting is generally done using various apps like Kingo root, supersu, etc,

These apps dont guarantee the safety of device. For the safety purpose rooting
must be done using Android SDK.

Step 1: Prep work and download

First, let's prepare a workspace on your PC. My suggestion is to create a folder in


the top level of your hard drive so it's easy to get to from the command line.
C:\Android_stuff is much easier to remember than
C:\users\gbhil\documents\tools\devices\Android\stuff. I use my workspace for
backups, wallpapers, ROMs, and tools as well as the SDK. Simply make a separate
folder inside your workspace for each. Click the image below to enlarge it and see
how I have my Android_stuff folder set up.

Android_stuff folder

Now it's time to download the SDK. Head to


http://developer.android.com/sdk/index.html. You'll see downloads for Windows, Mac
OS X, and Linux. Pick the appropriate category and download the file to your
desktop. Don't be put off by the license agreement. Have a read and you'll see it's
pretty standard.

Unzip the download with your favorite archiving tool and drag the folder you
extracted into your Workspace. Don't open the folder, just drag the whole thing over.
That's it. The Android SDK is now installed.

Step 2: Install the USB driver - a necessary evil

Installing the USB driver is almost as simple, though it takes a few steps, and you'll
need to do it if you're running Windows. Open the SDK folder that you just moved
over, and double-click "SDK Setup.exe" in the SDK directory. You'll be see a
window like the one below.

Android SDK setup window


Make sure "Available Packages" in the left pane is selected.

Click the triangle beside the globe on the top line to expand the list.

What I have circled in red in our example picture needs to be checked. That will
download the USB driver. Unless you have an interest in software development or
running an Android device emulator, you can leave everything else unchecked. If
you decide to install the other portions, be prepared for a 1 Gigabyte download.

Click install selected. The driver will download itself into the SDK.

Now on your device, hit the menu button. Choose Settings, then choose
Applications. Now click Development, and make sure USB debugging is checked.
Use the back key to exit back to your desktop.

Now, plug your phone in, just as if you were going to transfer a song or a picture. But
this time don't pull down the shade and mount the SD card. You'll get a "Found New
Hardware" message from Windows.

Select "Locate and install driver software."

Select "Don't search online."

Select "I don't have the disk. Show me other options."

Select "Browse my computer for driver software."

Now browse to the SDK folder, and point Windows to the folder named usb_driver.
Click the image below to enlarge it and see the usb_driver folder inside your Android
SDK.

Android SDK folder contents

Leave "Include subfolders" checked, and click "Next." Windows might ask you if
you're sure. Say yes if it does. When windows does it's thing, and asks you if you
want to install the "Google ADB interface driver" say yes.

Of course if we want to run emulators or program applications there's more to it. But
for our purposes, we're done. Unplug your phone and reboot your computer.

Now is a good time to mention that you probably shouldn't ever reboot your PC while
your phone is plugged in. Some newer PC's can boot from a USB device, and will
try to load Android to your PC if you do. As interesting as that sounds, it won't work,
and could lead to problems.
Funny how the hardest part of the whole operation is setting up Windows isn't it?

First test: Back up your apps

Here's a trick that anyone can do, even with an unrooted phone. Plug your phone
into the computer, the same way you would if you were transferring pictures or a
song, except once again don't pull down the shade and mount the SD card. Anytime
we're interacting with the phone through the command prompt, the card will need to
stay unmounted.

Now open your command prompt. In Windows, just hit the start menu and type
(either in the Windows 7 search field or the "run" command in XP) "cmd." Don't let
that 1960s computer look scare you off, this is going to be easy.

At the prompt, navigate to the location you put the Android SDK. If you're following
our example, just type (or copy and paste) the following in your command line:

cd C:\Android_stuff\android-sdk-windows

If you are using a different location, modify the command to point to the location
you've placed your Android SDK.

Inside the SDK there are some other folders. The one we will usually be working with
is the tools folder. Navigate into it by typing the following into your command prompt:

cd tools

Click the picture below to get a larger view of the commands typed into the Windows
command prompt.

Windows command prompt navigation

Now open up your file manager, and in your workspace make a folder called apps.
We're going to back up all of our applications here. The market keeps a record of
what you've paid for, but sometimes finding the free ones again can be a pain, so
lets keep our own copy. If you scroll up the page to the image of my Android_stuff
folder, you'll see an apps subfolder is already in there.

At your prompt type in the following:

adb pull /data/app/ C:\Android_stuff\apps

EXECUTION

As mentioned above about the process of rooting, perform in the Samsung mobile
exactly the way it is said in the method.
1. Unlock the Bootloader: Google and device manufacturers dont officially
support rooting, but they do provide an official way to gain low-level access to
some devices, which then allows you to root. For example, Nexus devices are
intended for developers, and you can easily unlock the bootloader with a
single command. Tools like the Nexus Root Toolkit for Nexus
devices automate this process.
2. Create recovery set of the android and store it either in internal or external
memory
3. Root the phone by using various apps egkingoroot or supersu. Android studio
can also be used.
4. Flash CyanogenMod or Another Custom ROM: Technically, this is an
extension of one of the above methods. Unlocking the bootloader and
exploiting a security vulnerability can each allow you to flash Custom
ROMs like CyanogenMod, which often come pre-rooted. CyanogenMod
includes a simple toggle on its settings screen that allows you to enable or
disable root access. Upgrading to a new version of CyanogenMod or your
custom ROM wont unroot your device if the ROM comes with an integrated
way to enable root.

The following results will be obtained after execution:

1. Better speed
2. Better performance
3. Up gradation in the android version
4. Memory expansion
Benefits of Rooting Android Smartphones

Plenty of Apps-

Google Play has some apps, but apps which are accessible through rooting are
much greater. By rooting one does not only get access to more number of apps, but
one can get deep into the phones brains too! This is not all that rosy as it sounds.
Network Spoofer uses the android device for setting up a fake wireless network. This
is harmful. One gets access to expanded superpowers by rooting the android phone.

Latest Mobile OS Updates-

Developer community of Android is a hard core bunch. They are able to get a new
OS onto a phone months before the carrier releases the update with a few bonus
features. Once rooted, you have the provision of getting the OS version you want
which is done very easily.
Bloat Banishment

Android phones do not only have the OEM skins, but a few superfluous apps which
one may not use at all. One cannot remove them either. In android 4.1 one can
disable those apps and one does not see them afterwards. But they are still there
occupying some space. After rooting one can use Titanium Backup to delete them
once and forever.

Increase Speed / Battery Life

Rooting allows users to install customized kernels that are optimized differently.
Some of them are made for low-power consumption, yet others are built for speed.
Set CPU is an app which can be used to over clock or under clock the phones
processor and rules can be set for usage. The processor should draw bare minimum
power when the screen is off.

Infinite Availability of Features-

Android Rooting does not only customize an android phones existing features, but
it also helps the user to pile on all kinds of features. An android user can hook up his
Play Station controller to his phone for better gaming. A user can also set rules for
callers to decide who can and who cannot call him.

Better Back Up Solution-

Once the android phone is rooted, the user can go a long way into increasing the
back-up. Titanium Backup can back up all your apps and it can back up all
information stored in those apps as well.

More Customization-

Android is the most customizable mobile OS in the world. The user can download
custom ROM's which do not look like Android at all. You can use a sliding keyboard
when you are in portrait mode, and a tapping, predictive keyboard when you are in
landscape. Keyboard manager helps the user to automatically switch between the
keyboards of the users choice whenever the phone is rotated.
Android Secret Codes for Hidden Menus

Secret Android Codes are the combination of numeric/symbolic sequences which


would be entered through the phone dialer of smartphones and tablets, which will
allow you to change device parameters, access hidden menus and perform
diagnostic tests.

These secret codes are universal for various Android platform that can be used on a
variety of devices
##3282# Show EPST menu
##33284# Perform field test
##3424# Run diagnostic mode
##7764726 Hidden service menu for Motorola Droid
##778 (+call) Show EPST menu
##786# Reverse Logistics Support
##8626337# Run VOCODER
*#*#0*#*#* Run an LCD display test
*#*#0283#*#* Perform a packet loopback test
*#*#0289#*#* Run Audio test
*#*#0588#*#* Perform a proximity sensor test
*#*#0842#*#* Backlight/vibration test
*#*#1111#*#* FTA software version (1234 in the same code will give PDA
and firmware version)
*#*#1234#*#* Show PDA and Phone firmware info
*#*#1472365#*#* Perform a quick GPS test
*#*#1575#*#* For a more advanced GPS test
*#*#197328640#*#* Enable test mode for service
*#*#2222#*#* Show FTA Hardware version
*#*#232331#*#* Run Bluetooth test
*#*#232337#*# Show devices Bluetooth address
*#*#232338#*#* Shows Wi-Fi MAC address
*#*#232339#*#* Wireless LAN tests
*#*#2663#*#* Show devices touch-screen version
*#*#2664#*#* Test the touchscreen
*#*#273282*255*663282*#*#* Immediate backup of all media files
*#*#273283*255*663282*#*#* Make a quick backup of all the media files on
your Android device
*#*#3264#*#* Show RAM version
*#*#3424#*#* Run HTC function test program
*#*#34971539#*#* Detailed camera information
*#*#44336#*#* Show Build time and change list number
*#*#4636#*#* Phone information, usage statistics and battery
*#*#4636#*#* Show HTC info menu
*#*#4986*2650468#*#* Show Phone, Hardware, PDA, RF Call Date
firmware info
*#*#7262626#*#* Perform a field test
*#*#7594#*#* Enable direct powering down of device once this code is
entered
*#*#7780#*#* Reset the /data partition to factory state
*#*#8255#*#* Launch Google Talk service monitor
*#*#8255#*#* Monitor Google Talk service
*#*#8351#*#* Enable voice dialing log mode, dial *#*#8350#*#* to disable it
*#0*# Enter the service menu on newer phones like Galaxy S III
*#06# IMEI number
*#12580*369# Software and hardware info
*#301279# HSDPA/HSUPA Control Menu
*#7465625# View phone lock status
*#872564# USB logging control
*#9090# Diagnostic configuration
*#9900# System dump mode
Android Rooting Using ADB

Android rooting explained: principles


Overview

In three words, the main rooting idea is to get super user rights on a device shell.
Like a standard Linux shell, it allows you to interact with the device by executing
commands from the shell. The shell can be accessed via ADB (Android Debug
Bridge) command tool. The main purposes of the ADB on Android-powered devices
are debugging, helping to develop applications and also, in some cases, it is used for
synchronization purposes (when syncing HTC Wildfire, it is required to turn on
the USB Debugging). We will use the ADB tool for uploading and executing the
exploit, working with rooted device via super user shell with full access to whole
device file system, programs and services.

ADB includes three components:

1. A client, which runs on your machine. Windows users can invoke it from the
cmd and Linux users - from the shell;
2. A server, which runs as a background process on your machine. It manages
communication between the client and the daemon running on the Android-
powered device;
3. A daemon, which runs as a background process on the device.

As, I am interested only in the third component. The daemon runs on a device and
communicates with a client through a server. When you issue the ADB command
like a shell, the daemon will create a shell instance on a device and redirect its
output to the client. Obviously, the shell new instance created by the daemon inherits
rights and environment from its parent. As the daemon runs with
the AID_SHELL rights, the shell new instance and all processes created by the shell
will have the same access rights. Hence, to get super user rights in the shell, we just
need the daemon to be running with these rights.

To understand why the ADB daemon has the ADT_SHELL user space, we will
consider how it is started up and look at its initialization script.

The first user land process started after the Android device booting is
the init process. After initialization and starting of internal services like property
service, ueventd service etc., it begins parsing the init.rc configuration script.
The ADB daemon is mentioned in the script as the service and it is started by
the initservice on the boot if the USB Debugging is enabled.

Lets look at the ADB daemon initialization source code. The main daemon entry
point, where it starts its execution, is adb_main. I skipped non significant pieces of
code to focus your attention on the daemon security.

int adb_main(int is_daemon, int server_port)

{
...

int secure = 0;

...

/* run adbd in secure mode if ro.secure is set and

** we are not in the emulator

*/

property_get("ro.kernel.qemu", value, "");

if (strcmp(value, "1") != 0) {

property_get("ro.secure", value, "");

if (strcmp(value, "1") == 0) {

// don't run as root if ro.secure is set...

secure = 1;

/* don't listen on a port (default 5037) if running in secure mode */

/* don't run as root if we are running in secure mode */

if (secure) {

...

/* then switch user and group to "shell" */

setgid(AID_SHELL);

setuid(AID_SHELL);

...

return 0;

So, what we see here. When the ADB daemon is starting, it has super user rights,
like the init process has. However, the daemon reads some properties from the
system and decides to set secure flag or not. Usually, if the device is not a
development device and it is not an emulator, the properties have such values:
ro.kernel.qemu "0" // is running on the emulator
ro.secure "1" // is running in the secure mode

After properties are checked, the secure flag is set to true, and we hit to such code
section:

if (secure) {

...

/* then switch user and group to "shell" */

setgid(AID_SHELL);

setuid(AID_SHELL);

...

Starting from this point, the daemon continues its execution with
the AID_SHELL user id as it drops root privileges. All processes, started by
the ADB daemon, like sh, will inherit its rights and will work in very limited
environment. It is really sad, isnt it?

How to root Android programmatically: Exhaustion attack

The main Android device rooting principle of the exploit described in this article is
the setuid exhaustion attack. The setuid function changes the user id for a process
only in case if there are resources available, otherwise it fails and the process
remains with that user id, with which it was started. Lets look at the resources that
can be limited by the Linux operating system. We are interested only in
the RLIMIT_NPROCresource. This resource limits maximum numbers of processes
that can be created with the same user id. If you have reached the limit, you cant
create more processes with this user id. The setuid function doesnt create
processes, but it follows this rule. Once, the NPROC limit for the AID_SHELL user is
reached, setuid fails and the process continues its execution with the user id set
before the setuid call. It means, when the ADB daemon starts with
the AID_ROOT user id and tries to change it for AID_SHELL, for which NPROC is
reached, setuid fails and the daemon user id remains AID_ROOT.

It is easy enough, isnt it?

In files attached to the article, you can find the binary file and Android root exploit
source code. They implement the adb exhaustion attack explained above. The
rooting process is easy for a user and I will describe how to use it below, but now, I
will go into detail about the attack implementation. I will touch upon the Android
rooting code structure and go into detail about a few important points.

Lets look at the root() function in the impl.cpp file. It implements the main logic of
the exploit.
rlimit s_rlimit = { 0 };

getrlimit( RLIMIT_NPROC, &s_rlimit );

printf( "RLIMIT_NPROC: %d.%d\n", s_rlimit.rlim_cur, s_rlimit.rlim_max );

pid_t adbdPid( get_pid( g_adbd_name ) );

At the beginning, after it gets and prints the NPROC limits, it runs the ADB daemon
PID and saves it into a variable. It will be used later to kill original process. Next, look
at the fork loop:

pid_t pid( -1 );

for( int i( 0 ); ; ++i )

pid = fork();

if( pid == 0 )

return ret;

...

The code above represents an infinite loop. It forks calling process and exits from a
child. That is enough because PID, allocated for current user, remains active until
the parent process exits. The loop works until the fork function returns negative
value. It means that we have reached the NPROC limit. Lets look at the next code
piece. The PID is negative, but we have to remember that there is one more shell
user process that will be terminated soon. This process is the ADB daemon that is
still running. We couldnt kill it on start because the init process would start it again
and it is an advantage for us. So, as soon as we reach that condition, we read
the ADB daemon PID and check if its user id
is AID_SHELL or AID_ROOT (because we could reach the condition from the
second or third iteration).If it is AID_SHELL, the program just sends SIGKILL to it
and continues the loop (soon, we will reach it again). Once the daemon is killed, one
more PID for this user is freed. We have to allocate this PID for the AID_SHELL user
as soon as possible to prevent the daemon setting its user id as AID_SHELL. Ideally,
there will be two additional loops: the first one forks and allocates a new PID for
the AID_SHELL user and, as the result, the second one reaches the limit again,
checks the daemon PID that should be AID_ROOT and exits. However, because of
lack of resources or lots of delays, there could be rather more iterations.

...

else if( pid < 0 )

printf( "limit reached. kill adbd and wait for its root ...\n" );

adbdPid = get_pid( g_adbd_name );

if( adbdPid >=0 )

if( get_pid_user( adbdPid ) != 0 )

kill( adbdPid, SIGKILL );

else

break;

...

To prevent the exploit infinite loop in case if it is impossible to start the ADB daemon
as root, there is a respawn guard for each forked child. Ten iterations and one
second timeout have been chosen empirically when I was working with several
devices and I found that some devices had a too big NPROC limit. It is obvious.
They enquire too much processor resources to handle all created child processes.
So, you may change the guard to fit your requirements or device.

...

else

static int theRespounGuard( 10 );


if( --theRespounGuard )

sleep( 1 );

else

break;

...

Configuration & Build

The exploit was configured to be built with the NDK toolset both on Linux, and on the
Windows platform. If you are working on Linux, it will be enough for you to
download NDK only; however, on the Windows platform, you have to download and
install the Cygwin environment on your machine. In this paragraph, I will tell you how
to configure and build the exploit on the Windows platform.

First of all, download and install the Android SDK. We need only a platform-tools
package from the SDK to communicate with a device through ADB, so, at
the SDK root directory, start the SDK Manager and check the platform-tools
package. Install it.
You can add a path to platform-tools into your PATH variable or type the absolute
path to the adb.exe executable any time later.

The second step is to download and install the Android NDK package and
the Cygwin environment. Install them in the same location with SDK and add a path
to your NDK package into the PATH variable or into your Cygwin.bash_profile. Then
unpack a project archive attached to this article into your working directory available
for Cygwin.

The project structure is very simple. In the AndroidExploit root, you will find two
directories. In the bin directory, I have placed a precompiled exploit binary and a
windows shell script file. The jni directory contains sources and the NDK build
scripts.

/AndroidExploit

/bin

exploit // precompiled binary file

root.cmd // windows shell script. It helps to upload and run

// the exploit in device. Usually, it is enough run

// the script to root device.

/jni
Android.mk // NDK build script

Application.mk // some application settings

// the source files

cmdLine.cpp

cmdLine.h

impl.cpp

impl.h

main.cpp

proc.cpp

proc.h

To build the project, run the Cygwin environment, change a directory to


the project/jni directory, and execute ndk-build. The Compiler output should look
like this:

You can find an executable at libs/armeabi/exploit. The path is relative to the root
of the project.

Running

The next paragraph describes how to use the binary file. You download the Android
SDK, install platform-tools and make them available from the PATH variable. At first,
enable the USB Debugging on your device. For this, from the main screen, go
to Settings -> Applications -> Development and check the USB Debugging
option, then connect your device to the PC and check that it has been detected
by Windows Device Manager. Otherwise, install the Android USB drivers for your
device from the manufacturer site.
Type the adb devices command in the command line. It will show you devices
connected to your PC. If there are no devices connected, check that Windows
Device Manager and Android USB drivers are installed.

We are on the right way! Lets go to the device. Type the adb shell command, which
will start the device shell, and then check your id to see who you are.

As it was expected, you are a shell user that has no privileges, no access, nothing
The only things you can do are installing programs and listing some directories. In
other words, you can perform only permitted actions. I was very surprised when I
couldnt read /data/data directory, it was impossible for me to list it and see what
programs were installed on my device.

Break the law. Go to the exploit bin directory and type adb push exploit
/data/local/tmp. This command will upload the exploit in the device temporary
directory available for the user. Then, type adb shell and change the directory
to /data/local/tmp. The ls l command will show you its content and permissions on
recently uploaded files. Make the file executable by executing chmod exploit 776 and
run it by ./exploit root.
The output shows NPROC and ADB daemon PID. Then, as soon as RLIMIT is
reached, the shell will be disconnected. Wait for ~5 seconds and type adb
shell again. As a result, you should see root # shell. Type id to make sure you are a
root.

Yes, you are! Now, you can do anything even let me think even damage your
device! So, all things you will do next are at your risk. Be careful!

RESULTS-
Run Special Applications

After you have rooted your phone, you can run special applications that
require root access on your phone. When compared to regular applications,
root applications provide more features.
As these special apps can directly deal with the Android system files, they can
tweak your Android in more extensive ways. For example, you can uninstall
multiple applications silently after you have root access using eUninstall.

Run Custom ROMs

One of the main reasons I rooted my phone was because I wanted to install
and use custom ROMs on it.
These custom ROMs bring many teaks and performance fixes and are much
more user friendly when compared to the stock ones. They are optimized in
performance and battery areupdated more frequently than the stock ROMs.

Free Internal Storage

People who have low internal memory can transfer any application from
internal memory to SD card after rooting their phone. There are some
applications that provide the option by default. But if you want to force move
an app by creating a symlink, you must use an app that only works on a rooted
phone

Potrebbero piacerti anche