Android NDK running native processes - android

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).

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?

Android privileges to execute native applications?

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.

Issue with system() call when cross compiling for Android

Based on some limitations with the NDK standalone toolchain and bionic, I have rolled my own toolchain using crosstool-NG with these general settings:
binutils-2.22
gcc-4.5.3 with gfortran enabled
glibc-2.14.1
kernel-headers-2.35.7
arch arm4t
Using this I build an executable and upload all dependencies, including libc, ld-linux etc with it onto my Android device. I manually run the executable with ld-linux.so.3 --library-path ...
It is a very complex executable, and it all seems to work except, if I do any system() call, even something basic, like system("pwd") or system(NULL) I get 127 as the status (not found). If I go further and use popen instead to collect a response, I get:
*glibc detected * double free or corruption
What is going on? Has anyone succeeded at doing similar? Is there a permissions issue? Is there something fundamentally different about Android that makes system() calls not possible? Where can I find out how bionic handles system and popen (source code) in the end, because I think if you use the NDK you can do system() calls.
(1) SHELL environment variable is unlikely to be set on Android. The default shell /bin/sh doesn't exist (AFAIK); it's in /system/bin/sh. This is likely what causes system to fail.
(2) You can find the implementations on GitHub: system, popen. Your crash in glibc sounds like a library bug to me (unless you're using popen from a signal handler or in a multithreaded environment)
I would suggest just rolling your own version of system. It's not complicated at all and that will enable you to determine the exact system call that failed and what error it fails with. Most likely, the shell isn't correct and that's what's generating the error -- your library is specifying a shell program that doesn't exist.

Running C/C++ code using OpenCV in android

I don't know whether i make sense or not. But just wanted to now that can i run the c/c++ code in android without the need of writing JNI wrapper or using Native Activity way?
I mean, I am having a simple C++ Template Matching code which contains main function and I use to run it using g++ in terminal.
Now I want this Template Matching code to be run in android usng NDK. Is there any way? I have googled a lot but all they is to either use JNI wrapper or use SWIG which makes JNI wrapper, but can't actually get into any of them. I need more simpler solution.
If you have a rooted phone, you can compile and run programs as on any linux machine, from the adb shell.
However, that requires a bit of knowledge about Linux.
So, to start:
Root your phone (force it to give you admin privileges). That is easy for developer phones/boards, and a kill for regular phones bought at a shop downstreet.
compile your app for android and run it from adb as you would do from a linux shell.
Here is a more detailed answer on the matter
How to compile C into an executable binary file and run it in Android from Android Shell?

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.

Categories

Resources