Android strace (or any linux binary) execution - android

I've got a problem which is probably very easy to solve but I can't seem to find the answer.
I'm trying to execute strace on different processes running on an Android device. I've succeded in doing this by copying the strace binary to /system/xbin (just like the emulator) and works just fine. My problem is I copied the binary through the bootloader and I don't want users to have to go through that.
So I found this great tutorial to run binaries from within an app:
http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App
I follow the tutorial and do this:
Copy the binary of strace to /data/data/com.mypackage
Change execution permissions to the binary (I've tryed with 777 too)
Try to execute it with
Process process = Runtime.getRuntime().exec("/data/data/com.mypackage/strace -p PID -o /sdcard/folder_I_know_it_works");
I know the command is right because when I execute it from /xbin/system it works perfectly. When I run the one I copied from within my app I get empty outputs. I only get the proper output for my own process, so I understand it's a permission problem.
I didn't mention yet that I have root permission on my app of course. I also tryed changing the owner to the strace binary to root:root and system:system and nothing.
To sum up: I need to reach the same permission on a binary I copy from my app to the phone memory than the one I have on a binary found on /xbin/strace
What am I doing wrong?
Another good solution would be finding a way to copy strace to /system/xbin from within an app with root permission. Any ideas?
Thanks a lot in advance!

Found the answer to this in case it's useful for anyone else.
Process process = Runtime.getRuntime().exec("su");
OutputStream os;
os = process.getOutputStream();
os.write("your linux command here".getBytes());
os.close();
You are basically simply running su as a process and sending commands through its output stream.
Later you may want to call process.wait()

Related

Root access works with adb, but root process on Android Studio doesn't (Android Things)

Currently I'am working on an aplication via Android Studio, that executes commands using the next sintaxis:
Process p = Runtime.getRuntime().exec(new String[] { "su", "-c", "ip link show"});
I'am working with the device IMX7D_PICO (it uses Android Things as SO). It is rooted, as is shown in the following pic:
But, when I run a command as root on Android Studio, I get the next error:
W/System.err: java.io.IOException: Cannot run program "su": error=13, Permission denied
W/System.err: at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at java.lang.Runtime.exec(Runtime.java:692)
at java.lang.Runtime.exec(Runtime.java:560)
I don't know why su works only on adb. In other hand, I know that there are others ways to obtain the data of ip link show, but the next step, it's open a socket RAW with the command that I said. So, I need to run process as su via Android Studio.
An app's process has less privileges compared to those of the shell's, resulting in
java.io.IOException: Cannot run program "su": error=13, Permission denied
For the permission to be granted you should install SuperSU app or alike and follow the app's prompts while your app is trying to su with Runtime.getRuntime().exec("su").
Once the process has gotten root you can grab the standard input of the root process and write the command(s) to it, reading its standard output. For more details see: execute shell command from android.
I don't know why su doesn't work. I 'suspect' that Android Things is using a single user that is root already, so maybe executing the command without using su would work.
On the other part of your question. Parsing the output of system commands is not the best way of getting info, in this case, you can probably get what you want using the Android class NetworkInterface https://developer.android.com/reference/java/net/NetworkInterface#getNetworkInterfaces().
You can manage raw sockets using the Android framework classes too.

What is the Android equivalent of /tmp and how do I get Python scripts to use it?

I am trying to use pelican (python) on Android (in termux). It fails when pelican tries to write to /tmp which near as I can tell, does not exist, and/or is a read-only file system.
The error is from os.py, in makedirs(name, mode)
OSError: [Errno 30] Read-only file system: '/tmp'
How do I tell any sort of script on Android to use a different location for /tmp?
How do I tell python on Android (in Termux) to use a different location for /tmp?
What is the Android equivalent of /tmp?
Editing to respond to suggestion this is a duplicate:
I found that answer helpful, but it doesn't pertain to this question.
I tried the instructions suggested here: https://stackoverflow.com/a/18280309/608970 and found that by setting TMP, TMPDIR and TEMP that I can indeed change /tmp for python and create tmp files, IF the script uses the tempfile module.
Apparently, pelican does not. Which leaves my original question, in Android what is the model for /tmp, how do we port arbitrary scripts, and does it require a change to the code, or can it be otherwise fixed by changing the Android environment the code works within?
According to https://stackoverflow.com/a/41105574/493161, it's /data/local/tmp, but my experience with termux is that it cannot read many/most files and directories that can be seen using adb from the desktop, and has write access to nothing (that I've found) outside its own files. I'd suggest mkdir $HOME/tmp instead, and using that.
Some of the other answers on that same question have good information on the lack of /tmp. Note that /data/local/tmp does not have the sticky ("t") bit set, nor does it have full read/write access to all users, as does Linux.
A better answer for many use cases is to use the file sharing options built into termux, documented at https://wiki.termux.com/wiki/Sharing_Data
$ termux-setup-storage
$ cp test.png ~/storage/downloads
$ xdg-open ~/storage/downloads/test.png

Can I start an executable in an approved application?

I've noticed that it is possible on Android to change the permissions on a file with chmod, which means we can easily execute anything from an application:
var runtime = Runtime.GetRuntime();
runtime.Exec("chmod 0755 /my/file").WaitFor();
// Then ProcessBuilder to execute it.
Would Google Play Store accept an application that takes advantage of this flaw? I can't find any documentation about it, but I confirm that it works.
Actually, I want to include ffmpeg for tasks that are too slow to be executed using MediaCodec.
(I've also noticed that the Android framework sometimes directly access to a native version of ffmpeg, so maybe I could access it directly from the phone?)
I don't know for sure if it is ok for Google Play.
However i don't think it is security issue. You will exec process with the autorisation of your app.
I hope the following example will help you.
You can try the following command line with your device connect.
adb shell
To have a shell on your devices
Then you can try to look what is inside the files for an app (replace com.your.package by the name of a debbugable apk)
ls /data/data/com.your.package
This command will failde because you have not the good permission.
Now run the following command.
run-as com.your.package
You will now exec your command line with the same permission as your app.
You can now retry the previous ls command. It will work. However it will not work for another package.
So, i think the command you will exec with your code, will be exec with the privilege of your app. So i don't think you can elevate the privilege of you app on a file with this method.

Where does Android store shutdown logs?

I know that the boot up log can be obtained by pulling out contents of kmsg or dmesg through ADB.
But I'm not aware of how to retrieve the shutdown logs in Android as there's no /var folder in Android (place where most desktop linux distros generally store their shutdown logs).
So how can I obtain the shutdown logs in Android?
Look in some locations such as these:
/proc/last_kmsg
/data/tombstones/
/data/dontpanic/
/data/system/dropbox/
(This list isn't strictly kernel logs, including framework and application logs too, which are also sometimes of interest)
One work around I found for collecting shutdown logs in Android is to run adb pull /proc/kmsg C:\Logs.txt on the host PC and then switch off the device. You will get the logs till the USB communication between the host and the device snaps! I know this is only one case out of the numerous shutdown scenarios but I haven't found satisfactory answers for other cases!
TL;DR:
Run command through adb that copies logcat and proc/kmsg to a file and keep it running even when adb disconnects with nohup, disown or setsid. Probably needs busybox, needs root and adb root, too.
setsid cat proc/kmsg > /sdcard/kmsg.txt &
and
logcat -v long -f /sdcard/logcat.txt (somehow only works without setsid)
Or add normal copy commands to some startup script.
/TL;DR
You can constantly copy proc/kmsg and logcat to a file on your android device or a microSD card to get the logs even after adb disconnects.
You need root access and adb root access for this to work. For the latter, use the setting in the developer options if you have a custom rom or the adbd insecure app.
After using adb shell to get your android shell, type su to get superuser access.
Then you not only need to put an ampersand (&) after the command but also make sure that the command keeps running after adb disconnects. That is done by nohup, disown or setsid (see here for usage).
If it doesn't work because you don't have these commands, you need to install busybox.
See my question here.
See here for how to get logcat and kernel logs and print it to some file or merge it.
See developer.android.com/tools/help/logcat.html for parameters for the logcat command.
In the end you could have a command like setsid cat proc/kmsg > /sdcard/kmsg.txt & for the kernel messages.
For logcat you could have one of the following commands: logcat -v long -f /sdcard/logcat.txt or logcat -v long > /sdcard/logcat.txt
I don't know why, but sometimes it didn't work with setsid and just didn't copy continuously but stopped shortly after executing the command. In these situations, it also showed up when entering jobs, which it didn't otherwise. Then it just worked without setsid, it stayed alive after disconnecting and reconnecting. I guess you must just try when the file does keep getting larger. If someone figured out why it is behaving like it is... let me know and I'll edit the answer.
Probably adding the commands to a startup script could be a solution for some, too.
Hope this helps.
fightcookie
Newer phones do NOT use any of these locations so if you're reading this article then as of now
The kernel crash logs are now in /sys/fs/pstore instead of /proc/last_kmsg
I was looking for the same thing, and finally, I found the answer!
In android 8 all logs are located in \data\log\android_logs\... including apps and kernel logs. Kernel logs are called kmsgcat-log_timestamp_.gz
edit: Although this is a very old thread, I think the answer might be helpful.

Android: how can execute a chmod on rooted devides

I would execute a command on my rooted Android 2.1 device
String path = "/data/data/com.android.providers.settings/databases/settings.db";
Runtime.getRuntime().exec("/system/bin/chmod -f 777 " + path);
But this command does nothing on the targeted file. Any idea?
The RootTools library offers simple methods to check for root and issue root commands:
RootTools.isRootAvailable()
List<String> output = RootTools.sendShell(command);
http://code.google.com/p/roottools/
You need to get the runtime as the root user first. There is a nice ShellInterface class that you can use from the MarketEnabler source available on Google Code. Though keep in mind this source code is released under the GPL.
Essentially what you need to do is determine where your su command is and create a kind of shell using an input stream and output stream for STDIN and STDOUT. With these you can then push your commands to your "terminal". When you are done all your commands, flush your buffer and then wait for the Runtime to complete. Once it is completed, you can then close your runtime interface.
Then take a look at the file you have tried creating/modifying/etc to see if everything worked properly.
Bao Le I believe you are trying to drop shell commands in an Android App, here (Running Android Native Code in your Android app)are few of many ways to run a command from an app.

Categories

Resources