Android privileges to execute native applications? - android

I downloaded the c4droid app for Android and am running commands through system();. I'm learning that somethings work while others don't. Most of the cool stuff don't work and this appears to be due to my user profile not being given the rights to execute such commands at the Linux OS level.
So tried another experiment. I got a special Gnu compiler for the arm processor and compiled a simple hello world app. Then I put on my phone and tried to execute it through the c4droid app like system("./myapp.bin"); . I got a permission denied message.
So I'm just trying to understand what I can do and what I can't do on my phone that paid good money for? Can I execute such a hello world app or not? Do I really need root access to execute an application I made? Is there a way to get my code to run by wrapping it in android/java code? Do I have to go through the Dalvikvm to get this to run?
I'm really looking for a way to do this without rooting it or downloading something like busybox and using su.

Many many different issues.
permission denied is one of the few error messages the primitive shell knows, and it's used for many other types of failures including not finding the requested command.
The toolbox suite is missing many typical unix commands. People sometimes install busybox as a more comprehensive supplement
Some of the things you may want to do will actually require permissions that the shell (or even more so, application user id) accounts do not have. Only on an emulator or engineering device does the adb shell run as root by default, though on a 'rooted' device you may be able to get to a root shell.
You do not need root access to run compiled code, however the code must have a suitable ABI, must have all it's library dependencies satisfied, and must be installed in a file with the executable flag, on a partition which is not mounted with non-executable flag. Some of the issues you face there are glibc (or other) vs Android's bionic libc. Executable scratch directories vary by android version, though the private storage area of an app is an option if the app sets the file to world readable and executable.
The usual (and only "recommended") means of running native code is to build it as a shared library linked against android's Bionic libc, and call into it from a dalvik/java app using JNI.

Related

SocketBuildError: Permission Denied for raw sockets

I was asked to adapt our network testing libraries so that they are able to run on Android.
The application's base functionalities are written in Rust and include ping, dns, traceroute, etc.
I'll use ping as an example, but the same problem applies to other applications that rely on the creation of a raw socket. For instance, performing a DNS query using a standard UDP socket works without any problems.
The framework used for the actual Android app is Flutter.
For now, all tests were done using the Android Emulator inside Android Studio 2021.0.1 Patch 2.
As emulator images go, I tried on:
Android 12.0 x86_64 (API31)
Android 7 x86 (API24)
Android 7 armeabi-v7a (API24)
Android 11 arm64-v8a (API30)
I created a git repo with a minimal example of the entire application, in case anyone wants to test it out.
I'm binding Rust with Flutter using the Flutter Bridge Dart package. (Also in case you want to reproduce the bindings yourself).
The demo application is super simple and tries to focus on the problem at hand, which seems to be the creation of the RAW socket.
While searching for the solution, I've stumbled across a lot of information and I'm not entirely sure what's still relevant (mostly up to date) or not.
When searching for how to create a raw socket with an application built with NDK, I found this:
https://android-developers.narkive.com/BK5uGK4f/android-ndk-raw-socket-creation-problem
The author seems to have the same problem and the answer points out that this would not be possible because the application needs root access.
So, I tried doing adb root && adb remount. When I run adb shell, I'm given the root shell (#), and running tcpdump (which needs all types of access possible for network), seems to work.
Obviously, simply doing adb root did not fix my problem and the application (flutter run) still results in:
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: FfiException(PANIC_ERROR, called `Result::unwrap()` on an `Err` value: Os { code: 1, kind: PermissionDenied, message: "Operation not permitted" }, null)
So, my first thought was that the emulator was not rooted, or something like that, but after some research, I found out that, not only the device has to be rooted, but your app needs to ask for root access itself. So, I tried using this Dart library:
Root Access Plugin
That didn't work as well. The root access gets denied. This library uses a method that is similar to what's described in this Stack Overflow posting.
In order to provide an application with root capabilities, you need to call the application preceded by su.
I haven't tried creating a binary from the Rust library and calling it manually with su, mainly because I just couldn't get the cross-compilation to work for the target x86_64 Android architecture (but this is another very lengthy discussion).
In Linux, you can set the capabilities of the binary with setcap. For raw sockets, a simple setcap cap_net_raw+ep [binary] solves the issue. Of course, you need root or sudo for that. In Android, from my understanding, capabilities work differently. Here's a Stack Overflow posting that touches this subject.
It suggests that you can change the app's capabilities by requesting them in your manifest file. It didn't seem to work for me, but I'm not so sure I did that correctly.
For the emulator, I added
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_SUPERUSER"/>
<uses-permission android:name="android.permission.NET_RAW" />
to the android/app/src/debug/AndroidManifest.xml
SUMMARY
From my Flutter application, I want to be able to call my linked Rust library (compiled .so files), and the Rust code needs to have access to raw sockets.
So, how can I make this work?

Porting C based linux application to the Android platform

I have C Linux based application and now I want to port it to Android.
I figured out, that I can extract the toolchain from Android NDK and build my application, but how to make the APK such that I can install it on the android devices without the need of root access.
In Linux, I used to install it using a bash script which used to put my application related files in different folders like /opt, /etc (files shared with other applications) and /var . How can we handle this in Android. Is there a folder similar to /etc in Android where I can put files that other applications can read.
Thanks
-M
First of all, you are lucky if your project compiles "as is" with NDK standalone toolchain. Often, bionic is not enough, and people need to tweak the build environment (from libpthread to full-blown buildroot alternate toolchain with static C runtime).
As for the shared files location, on Android it's named "external storage". Your app and other app may require special permissions to write and read to this location. Directory /opt does not exist here. You don't have write access to /etc, but files like /etc/hosts are available for read.
Regarding the APK. You are right, this is the ultimate way to distribute and install apps on Android. But you can, even without root, to locally install and run a command-line executable. Usually it's done with Developers Options turned on, and enabled USB debugging. Now you can open an adb shell, install and run your program. The trick is that external storage (see above) is marked as 'non-executable'. Therefore, you must find another place for your binary. Usually, /data/local/tmp will be a good choice.
Instead of adb, you can use a terminal emulator on the device.
If you choose to build an APK, you will probably prefer to convert your app to shared library that will perform actions for Java via JNI. But it is also possible to package your command-line binary as part of the APK and use Java Runtime.exec().

Node.js On Non-Root Android

As the question title states, can I install node.js on Android without root? I have a couple terminal emulator apps and at least one of them has BusyBox, git, and adp, among other things, though I am severely limited in what I can do with them. For example, I can not just git clone the node.js source code, as "No auth methods c[an] be used". I can download the node.js source code, but it seems to be under the "system_server" user as soon as it's downloaded, which I assume is the root user or very close. I am able to unpack it, but unable to run the configure executable in this directory, I assume because it is owned by root as soon as it is downloaded.
Am I trying the right approach here? I have heard about anode, but its wiki is empty and whatever instructions it has are confusing and do not say whether I need to be root. Everything else I have seen tells me I have to have a rooted Android to install node.js, but I hate to give up after so much effort.
Instead installing node.js on the android device, try jxcore.
You can download an android executable binary from its download page, and execute it from the terminal emulator. Remember to set up exec flags.
EDIT: jxcore seems no longer under development.

accessing android os root files

i have the following doubt:
i have read that android os is based on linux, and i imagine it may have the same structure that ubuntu (in terms of file configurations: /root, /dev, etc).
so, is it possible to run an application written in C in android? just as it is possible to do in ubuntu? if so, how can i do that?
also, how can i get access to the root files through an android application (written in java)? and how to get access to the behavior of the os (in terms of interruptions for example)?
thanks in advance for your answers.
gus
Basic answer: Running a C app on Android isn't supported, except through the Native Development Kit (NDK).
You can't get access to the root files except by rooting a phone.
You can get access to some OS behavior through the API. Basically, if it's not part of the API, you can't access it.
The Android OS is based on Linux, but it's an OS, not a windowing server like X or a desktop environment like Gnome or KDE.
You may run C and C++ code on android using NDK. You may use also QT framework. But code is runing in virtual machine named Davlik. Android have root acount , but it is default not available for user. Therefore, access to directory is dependend for chmod.
If you would like read about access to low level in android:
http://www.phrack.org/issues.html?issue=68&id=6
And about architecture this system:
https://developer.android.com/guide/basics/what-is-android.html
You can run programs using Runtime.exec. As an example, you can see Terminal IDE which runs many different programs including ssh, vim and bash. It's also open source so you can learn from the code. You will probably have to include the executable as a resource or asset and then copy to a local directory, grant execute permissions, then run with Runtime.exec. You still have limited user permissions as your app runs under a restricted account unless the device is rooted and you request root access.
an android smartphone/tablet works with an Arm cpu, not a x85. the architecture is different.
but you CAN run a C application in android if you cross compile it for arm linux. or you can use a c compiler inside android device. people ported c compiler to android. you can try C4DROID and in android market. but you can only run compiled program in system memory because of android permissions about sd card.

Android NDK running native processes

I want to run tcpdump on the NDK using Process.start() and want to capture this output to a buffer.Can anybody show me how i can do this?Also is the process created in the same Dalvik Vm as the JNI call or is it in a different VM?
Running native processes is not really a supported use of the ndk, but you wouldn't be the first person to do it.
Also note that tcpdump may need to be run as root or setuid root to be useful. And you do have a version of tcpdump compiled and linked appropriately for android?
I think that you actually want android.os.Exec.createSubprocess which is um, not public, rather than Process.start. There's a right way to do it using reflection, and a wrong way to do it by copying the Exec.java (which has declarations of the native methods) into your project. You can use a pipe to recover the results, or you can launch it through the shell and redirect the output to a file which you read from java.
See the source of an android terminal emulator with a local shell option for an example of how to do it.
(Actually, I should restate this - the right way to do it is to duplicate the native functionality of the non-public Exec methods in your own jni lib, so that you are immune to changes in that non-public part of the platform).

Categories

Resources