I am currently trying to write a root app.
I know that I can execute shell commands in a root shell like this.
However, I also want to execute some commands that way:
Code:
su -c[command]
But I can't get it to work if I use commands with parameters like ls -l or mkdir <path>. Executing something like su -c reboot works fine.
According to this it should work.
If I execute these commands using an adb shell or the Terminal Emulator app, they work fine.
This is my code:
Code:
package de.nikwen.sutest;
import java.io.IOException;
import android.os.Bundle;
import android.app.Activity;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("su");
runtime.exec("su -c 'mkdir /data/data/abcdef'");
runtime.exec("su -c \"print asdf\"");
//However, this works:
// runtime.exec("su -c 'reboot'");
} catch (IOException e) {
e.printStackTrace();
}
}
}
I get this logcat:
Code:
04-02 21:03:14.509: D/su(3620): su invoked.
04-02 21:03:14.519: E/su(3624): Unknown id: /data/data/abcdef'
04-02 21:03:14.519: E/su(3624):
04-02 21:03:14.529: D/su(3623): su invoked.
04-02 21:03:14.539: D/su(3625): su invoked.
04-02 21:03:14.559: E/su(3626): Unknown id: asdf"
04-02 21:03:14.559: E/su(3626):
04-02 21:03:14.639: D/su(3629): 10079 de.nikwen.sutest executing 0 /system/bin/sh using shell /system/bin/sh : sh
Does anybody have an idea to solve my problems?
Could anybody please test this code on his device? I would really appreciate this as it could be ROM related. (http://forum.xda-developers.com/showthread.php?t=2180669)
Well, as far I know if you already used su you don't need to use it in the other commands, like this:
Code:
runtime.exec("su");
runtime.exec("mkdir /data/data/abcdef");
Anyway, to run commands as root easily, I recommend you RootTools
RoberGalarga said:
Well, as far I know if you already used su you don't need to use it in the other commands, like this:
Code:
runtime.exec("su");
runtime.exec("mkdir /data/data/abcdef");
Anyway, to run commands as root easily, I recommend you RootTools
Click to expand...
Click to collapse
First of all: Big thanks for your answer. :good:
Well, it doesn't work if I do not use
Code:
runtime.exec("su");
And not using the su command again works, but only if you write the commands into the OutputStream of the process which is returned.
You have to call it at least once after installation to make the SU app ask the user for permission. Then the other lines should work on its own.
The advantage of using su -c [command] is that the user isn't shown all these annoying Toasts like "App x has been granted Su permissions", just the first time when it requests su rights after each launch of the app. My app has to call these functions very often and all these Toasts are VERY annoying. If you look at apps like file managers, there is also just one Toast at launch time and then they execute all commands without any Toast.
According to this you should execute everything like this:
Usage: su -c 'command'
su -c 'command1; command2; .... ; commandN'
Click to expand...
Click to collapse
My question is just if this works on other devices or ROMs. I will really appreciate if you try it.
And if it doesn't, then my question will be why it doesn't.
EDIT: And I don't want to use any libraries, even though it would be much easier.
The strange thing is that the last quotation mark is seen as a part of the argument.
EDIT: Inserting a space before the quotation mark doesn't work:
Code:
04-03 00:02:59.129: E/su(13793): Unknown id: /data/data/abcdef
04-03 00:02:59.129: E/su(13793):
04-03 00:02:59.139: D/su(13790): su invoked.
04-03 00:02:59.139: D/su(13792): su invoked.
04-03 00:02:59.159: D/su(13794): su invoked.
04-03 00:02:59.169: E/su(13795): Unknown id: asdf
04-03 00:02:59.169: E/su(13795):
04-03 00:02:59.189: D/su(13796): db allowed
04-03 00:02:59.219: D/su(13798): 10079 de.nikwen.sutest executing 0 /system/bin/sh using shell /system/bin/sh : sh
EDIT2: Deleting the last quotation mark also didn't help:
Code:
04-03 00:05:18.409: D/su(14117): su invoked.
04-03 00:05:18.439: D/su(14120): 10079 de.nikwen.sutest executing 0 /system/bin/sh using shell /system/bin/sh : sh
04-03 00:05:18.439: D/su(14118): db allowed
04-03 00:05:18.459: E/su(14123): Unknown id: /data/data/abcdef
04-03 00:05:18.459: E/su(14123):
04-03 00:05:18.469: D/su(14122): su invoked.
04-03 00:05:18.489: D/su(14124): su invoked.
04-03 00:05:18.489: E/su(14125): Unknown id: asdf
04-03 00:05:18.489: E/su(14125):
Ok, in Terminal Emulator this works fine (2.3.7, CM-bassed):
su -c "ls /sys"
So it's kinda weird =/
RoberGalarga said:
Ok, in Terminal Emulator this works fine (2.3.7, CM-bassed):
su -c "ls /sys"
So it's kinda weird =/
Click to expand...
Click to collapse
Yes, it is.
Did you try the source code?
If you want, I can compile it for you.
Flashed this and it doesn't work, too.
Here is the compiled apk.
Could somebody please test this?
Tested, don't seems to work (it should create the folder /data/data/abcdef right?)
RoberGalarga said:
Tested, don't seems to work (it should create the folder /data/data/abcdef right?)
Click to expand...
Click to collapse
Yes, it should.
Thank you very much for your answer as you have been the only one giving me answers. :good:
EDIT: The link in your signature is broken.
However, I don't understand why this works here:
Code:
Runtime.getRuntime().exec("/system/bin/su -c 'setprop ctl.stop zygote'");
Something else I found:
Usage:
su --> becomes root (starts /bin/sh as root)
su -c '' --> run a command or many commands separated by ; as root.
Click to expand...
Click to collapse
(http://de.appszoom.com/android_applications/tools/superuser-su_feoig.html)
I have solved the problem now:
Code:
package de.nikwen.sutest;
import java.io.IOException;
import android.os.Bundle;
import android.app.Activity;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("su");
runtime.exec(new String[] {"su", "-c", "mkdir /data/data/abcdef"});
runtime.exec(new String[] {"su", "-c", "print asdf"});
//do this to execute two ore more commands at once
runtime.exec(new String[] {"su", "-c", "mkdir /data/data/aaab; mkdir /data/data/aaac"});
} catch (IOException e) {
e.printStackTrace();
}
}
}
I know that I shouldn't run this on the main thread but in a service or at least in a different thread. This is for testing purposes only.
I missunderstood this blog entry.
But now everything works fine.
However, I still don't know why my first code example doesn't work. If anybody has an idea, please still answer my question as it hasn't been answered completely yet.
Again: Big thanks to RoberGalarga! :good:
Hello everyone,
An error related to SuperSU's su binary file occured when i try to run "mount" linux command through background sh process.
Everything is ok in the process of running su and a root permission is properly got by SuperSU, code is here:
Code:
Process process = (new ProcessBuilder("/system/bin/sh")).redirectErrorStream(true).start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
PrintWriter writer = new PringWriter(process.getOutputStream());
writer.println("echo start");
writer.println("su");
writer.println("echo end");
String res = null;
while ((res = reader.readLine()) != null) {
if (res.equals("end")) break;
}
Of cause i run it in a sub thread and won't block the UI thread.
And in the click listener of a button i trigger the mount command in the similar process.
writer.println("toolbox mount -o rw,remount /system");
But when i successfully mount that path and return to SuperSU, the error occurs with no doult.
An error dialog will be poped up like this: There is no SU binary installed, and SuperSU cannot install it. This is a problem!
Any one have an idea that why running a single linux mount command can cause that problem? And how couldi do?
More information: I have tried several other command like pwd, ls and other basic command, but all of them work well, except
mount, who would like to explain this problem?
Hacking android, got "system" user, but not root, how to escalate privilege?
Hello, i am new to XDA. I am trying to jail-break my android device:
Android 5.1.1, Linux 3.10.49
This device is a rare brand and have no any unlock & flash mechanism.
Currently i have successfully got "system" user (UID 1000) by using a preinstalled DEBUGGABLE system app.
This user can only change /data directory etc, it can not change any file owned by root.
So any help to escalate "system" user to root user will be very appreciate.
the result of command "id":
Code:
uid=1000(system)
gid=1000(system)
groups=1000(system)
1007(log)
1010(wifi)
1015(sdcard_rw)
1021(gps)
1023(media_rw)
1028(sdcard_r)
3001(net_bt_admin)
3002(net_bt)
3003(inet)
3004(net_raw)
3005(net_admin)
3006(net_bw_stats)
3009(qcom_diag)
9997(everybody)
41000(u0_a31000)
context=u:r:system_app:s0
This account can change /data/system/packages.xml etc, but can not change /system/*, nor chown/mount.....
It's CapBound is 0, too strict. And also can not disable SELinux.
Can anyone help me?
----------------------- PS: share how i get system user privilege, maybe helpful to others -----------------------
In a word, just use jdb to attache to the app then print new java.lang.Runtime().exec("sh /sdcard/my.sh").
First, i found a package appeared in Android Device Monitor's debuggable app list, e.x. com.example.app.
Then i use
Code:
pm dump com.example.app
got confirmed it use system UID, then
Code:
run-as com.example.app
but failed due to "Package not found", i don't know why.
Then i try to use JDWP way.
Get the debuggable process ID:
Code:
$ adb jdwp
9424
$ adb forward tcp:8600 jdwp:9424
$ jdb -attach localhost:8600
> threads
group system:
(java.lang.Thread)0x2a86 Signal Catcher ...
(java.lang.Thread)0x2a87 FinalizerWatchdogDaemon ...
...
group main:
(java.lang.Thread)0x2a8d main ...
(java.lang.Thread)0x2a8e Binder_1 ...
...
> thread 0x2a8d
main[1] stepi
>
stepi completed: "thread=main", android.os.MessageQueue.next()、row=145 bci=22
main[1] > print new java.lang.Runtime().exec("sh /sdcard/qj.sh")
There are some files need be upload(adb push .... ) before run the last command.
/sdcard/qj.sh:
Code:
date > /sdcard/log
cp -f /sdcard/busybox /data/ 2>> /sdcard/log || exit 1
chmod 4777 /data/busybox 2>> /sdcard/log || exit 1
(while true; do /data/busybox nc -l -p 7777 -e sh; done) >> /sdcard/log 2>&1 &
echo server OK >> /sdcard/log
/sdcard/busybox:
this file can be found at busybox.net/downloads/binaries/latest, choose ARM7v.
The above jdb command "print new java.lang.Runtime().exec("sh /sdcard/qj.sh")" will create a shell server listening at 7777 port, bridge input/output to sh.
So, to connect to the shell server,
Code:
adb forward tcp:7777 tcp:7777
nc localhost 7777
then in this connection, input shell command.
Sorry: i forgot a very important step: to run the "print new ...." statement, i have to turn on screen, even touch the app so can be trapped into jdb.
---------That's all------------
My goal is simple: Send a command through ADB to bluestacks (which i got working) to FakeGPS (which Is responding) to set GPS location to a specified lat/long (part that doesn't work)
First, background info
my environment is bluestacks 2, with FakeGPS (this one) installed as system app using LuckyPatcher
Setting a location directly in FakeGPS does work corectly - Good
I saw this on the FakeGPS page linked above:
FAQ for integration with Tasker only (Example is lat 18.89768D long: -55.0365D) :
Create a new task and add Action -> Misc -> Send Intent
2. Edit:
- Action: com.incorporateapps.fakegps.ENGAGE (to Stop add a new task and use com.incorporateapps.fakegps.STOP)
- enter 1st extra: lat:18.89768D
- enter 2nd extra: lng:-55.0365D
the "D" at the end is important so add it!
- Target: Service
Click to expand...
Click to collapse
I tried it out with Tasker, and lo and behold, Tasker can indeed send intents to FakeGPS and FakeGPS will set the location correctly - Good
What I want to do is send an intent through ADB (source information here) so I can set the FakeGPS location inside bluestacks from a windows console window. I have gotten it to the point where FakeGPS will respond, but I cannot get it to go to the lat / lng I give it. IT always either does nothing, or goes to lat:0 lng:0.
Commands I have tried:
Code:
Connect to bluestacks:
adb connect 127.0.0.1:5555
adb -s 127.0.0.1:5555 shell am startservice -a com.incorporateapps.fakegps.ENGAGE --ef lat 41.0050073D --ef lng -28.4530577D
adb -s 127.0.0.1:5555 shell am startservice -a com.incorporateapps.fakegps.ENGAGE --ef lat 41.0050073 --ef lng -28.4530577
adb -s 127.0.0.1:5555 shell am startservice -a com.incorporateapps.fakegps.ENGAGE -e lat 41.0050073D -e lng -28.4530577D
adb -s 127.0.0.1:5555 shell am startservice -a com.incorporateapps.fakegps.ENGAGE -e lat 41.0050073 -e lng -28.4530577
adb -s 127.0.0.1:5555 shell am startservice -a com.incorporateapps.fakegps.ENGAGE --ef lat 41.0050073D --ef lon -28.4530577D
adb -s 127.0.0.1:5555 shell am startservice -a com.incorporateapps.fakegps.ENGAGE --ef lat 41.0050073 --ef lon -28.4530577
adb -s 127.0.0.1:5555 shell am startservice -a com.incorporateapps.fakegps.ENGAGE -e lat 41.0050073D -e lon -28.4530577D
adb -s 127.0.0.1:5555 shell am startservice -a com.incorporateapps.fakegps.ENGAGE -e lat 41.0050073 -e lon -28.4530577
I've also tried a few other things, but none of them got any sort of response from FakeGPS. From what I read in the intent documentation and the blurb quoted above, one of these SHOULD work, but none of them do. However I KNOW that what I want to do is possible because Tasker can successfully set the location. Can someone help me get this working from ADB?
I sadly don't know exactly *what* is required to get intents to shell form..
(If anyone knows: Please enlighten us. Using tasker for all intents is a pain in the ...)
But.. you could use XPosed Edge's Export "as broadcast command" option and call that via windows.
Device-info:
Phone: Sony Xperia Z1
Model number: C6903
Android version: 5.1.1
Build Number: 14.6.A.1.236
Rooted and BusyBox installed (Play Store Version!!!)
I have formatted an SD-Card to an ext4-filesystem and put another Linux on it.
After mounting the filesystem and files without problems I want to execute:
Code:
chroot /data/local/mnt /bin/bash
with /data/local/mnt is the Linux root-folder.
Execute the line above leads to the message:
Code:
chroot: can't execute '/bin/bash': Permission denied
I have checked the permission of /bin/bash and also of /data/local/mnt and remounted nearly every path which are related to that folder with exec and rw permission. So maybe you know some special rights-associated files or folders I forgot, but I think the problem is something else...
After readed that some of the Linux-on-Android project-users had some trouble with executing the init.sh because of selinux I set it to permissive:
Code:
setenforce 0
and checked it:
Code:
[email protected]:/ # getenforce
Permissive
(Of course) chroot does not work. So I checked the message buffer of the kernel for selinux-avc-deny-messages and BINGO:
Code:
[email protected]:/ # dmesg | grep denied
...
<36>[58575.652383] type=1400 audit(1470337082.042:10188): avc: denied { read } for pid=18553 comm="busybox" name="mmcblk0p23" dev="tmpfs" ino=9821 scontext=u:r:ric:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file op_res=0 ppid=4602 pcomm="ric" tgid=4602 tgcomm="ric"
<36>[58575.653740] type=1400 audit(1470337082.042:10189): avc: denied { open } for pid=18553 comm="busybox" name="mmcblk0p23" dev="tmpfs" ino=9821 scontext=u:r:ric:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file op_res=0 ppid=4602 pcomm="ric" tgid=4602 tgcomm="ric"
<36>[58575.655002] type=1400 audit(1470337082.042:10190): avc: denied { ioctl } for pid=18553 comm="busybox" path="/dev/block/mmcblk0p23" dev="tmpfs" ino=9821 scontext=u:r:ric:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file op_res=0 ppid=4602 pcomm="ric" tgid=4602 tgcomm="ric"
These are just 3. You can have some more if you want! So 1. QUESTION:
Why does selinux denies something when getenforce returns Permissive???
But I thought first that could be fixed anyway by allowing all these denied permissions with:
Code:
supolicy --live "allow source_class target_class permission_class permission"
FOR EXAMPLE:
Code:
supolicy --live "allow ric rootfs file execute_no_trans"
which returns:
Code:
Patching policy ...
-allow:ric:rootfs:file:execute_no_trans=ok
- Success
Well (of course) it did not work AND I get a denied message for the exact same case for a bunch of cases.
So 2. QUESTION:
Why does allowing policies not change policies to be allowed???
(Of course) I am not 100% sure if the denial of executing chroot is related to selinux and it would be very easy to find it out if I could just set it to permissive.... So 3. QUESTION:
How to solve this problem?
Well (Of course) I could take a hammer smash my device... I think that works well.
I appreciate your Help!