during the execution of th MLO I create a variable, whose value I want
to make accessible to user space applications in Android. How can this
be achieved?
One way would be to write the contents of the variable to external
memory and let it read by the user space process. However, I would need
to make sure that during boot no other process is overwriting the address.
Do you know of any other ways, ATAGs? If ATAGs can be used, how would one do this? Is it necessary to develop a kernel module?
Cheers
From linux userspace, you can get info from U-Boot environment variables using "fw_printenv" application. During U-Boot execution you would "setenv variablename value", then saveenv.
Your U-Boot MLO would need CONFIG options set to enable the env commands. MLO usually wants (and needs) small code footprint, env commands will make bigger code footprint, that could be an obstacle.
At the linux side, you would need "fw_printenv" configured for your particular target's memory. That can be done at runtime, see fw_env.config. You can get the target executable built in u-boot/tools/env/. This assumes that android carries over the linux mechanisms in this area; I am not familiar with android platform details.
Related
Assume we have a process that may dlopen() some third-party library. This library may perform open("write_only_logfile", O_WRONLY) on some file to which user has only write access. We need to have an ability to be notified if this library attempts to open a file, so later we may dup() returned descriptor and redirect output.
There are few restrictions that make interception harder:
LD_PRELOAD is forbidden - no way to hook open()
inotify(7) doesn't help because user has no read permissions on "write_only_logfile" and it is owned by admin
we have no access to library sources and therefore cannot modify it
"write_only_logfile" is hardcoded inside the library, so we cannot pass another name to perform redirecting
I'm wondering if Linux has an efficient way to help in such situation.
Especially taking in account the fact that process may open() miscellaneous files pretty often.
P.S. To avoid confusion and understand better - it is a regular Android application with loaded JVM. If app hangs (so called ANR) - system sends SIGQUIT to it. Signal is received via dedicated thread that open()s /data/anr/traces.txt and writes JVM state to it. These data extremely useful for debugging. But app cannot read that file directly because of security reasons (All applications write to it, so there may be somewhat sensitive). Anyway I believe that it is absolutely fair to intercept content that my process would write to it.
P.S.S. In the worst case it is possible to find JVM library image (libart.so) and manually patch jump slot for open(). But it doesn't sound well.
Sounds like you are in troublesome situation. Most solutions briefly mentioned below are guaranteed to interfere with SELinux, so don't take my word for any of that.
Debugging your own process with strace to intercept open is one of usual solutions on normal Linux. I am not sure if it would work in Android; it certainly might become off-limit for non-debuggable apps starting in some new versions (if it is has not been banned yet).
seccomp-bpf is another possibility. Might not be available on older Android versions, but since Android O seccomp is going to be a guaranteed part of Android security getup. Intercept open in warn-only mode and give control back to yourself when something interesting happen (via debugging or signals).
If /data/anr/traces.txt is opened on-demand, you should be able to observe that by watching contents of /proc/self/fd/ with inotify or via polling. You might be able to reduce impact of races by setting io niceness of the opening thread…
All of above are only partial solutions, you still might need to decode actual open syscall that happened (strace source code might be helpful there for strace/seccomp solutions, readlink for /proc/self/fd/) and act upon it (dup2, as you already mentioned).
"write_only_logfile" is hardcoded inside the library
Is it possible to modify the memory of data segment of the library/executable? Afaik mprotect and PROTECT_EXEC in particular have been heavily restricted, but at least mmap is certainly permitted (to support JIT compilers etc). It might be possible to cook something up to edit the string constant in place (as long as doing so is possible and allowed, I am not sure myself about that).
If this is just about redirecting writes (and reads) to a single file, you could run the application in a mount namespace with a suitable bind mount for that particular file. Setting things up in this way probably requires a small SUID binary.
A more general solution quickly approaches a union file system, and getting it right is quite hard. Even the in-kernel union file system, overlayfs, does not manage to provide full POSIX semantics.
You need LD_PRELOAD to hook an application. To hook a third-party library, just load your hook normally before the library (or have it in your executable).
Assuming the library calls open from libc and not the corresponding syscall directly, and that it is linked in a normal way, you just have a function named open somewhere in your code. Make it call open from libc (RTLD_NEXT or whatever). The third-party library (and all other libraries of course) will resolve its open symbol to your function.
I'd like to get some numerical data from an app, but they are not stored as files like db. I know there are some memory hack apps for changing in game values although I do not know how they work.
I am looking for similar features but I don't need to change anything.
The app I am trying to write just reads some data from a specific app and do some background calculation based on that. If this is not possible, I would need to get information by reading the screen(for example get pixel color), but this seems to be very cumbersome task for getting many data.
Is there a way of achieving this?
Thanks.
EDIT: I'd assume I would need a root permission for this?
Yes, you would need root permission. Additionally your users must have fully rooted device with e.g. SuperSU or other modern Su app, that can lift most SELinux restrictions. There may also be conflicts with KNOX and other similar systems, but I am not really knowledgeable about those.
You would need to attach your process as debugger to the target application and locate the necessary data by scanning it's memory. This can be done in multiple ways, the best reference implementation to look at can be found in scanmem.
The code, performing the actual deed, which requires root rights, — reading/writing target process memory — would reside in a native executable, being run via su. You'd have to write some code to communicate with that executable (probably via it's stdin/stdout or something like that).
You will also have to write additional code to parse the memory layout of target application yourself.
Alternatively, you may prefer to inject a small module in memory of target application and/or have the app itself load a Dex file of you making (especially handy, if your target data is stored in Java memory). This approach have a benefit of minimizing interaction with memory layout of virtual machine, but you still have to initiate loading of initial Dex file. Once Dex file is loaded, you can do the rest in Java code, using good-old reflection API. If you go with this route, a (decently supported!) code for injecting executable snippets in memory of Linux process can be found in compel library, being developed as part of CRIU project[1].
Two Android processes cannot share memory and communicate with each other directly. So to communicate, objects have to be decomposed into primitives (marshalling) and transfered across process boundaries.
To do this marshalling, one has to write a lot of complicated code, hence Android handles it for us with AIDL (Android Interface Definition Language).
From the OP, as no more details can be found, I would recommend you reading/searching with the keyword "AIDL" and you will be redirected to the concrete solutions.
I am trying to set up a working Linux ecosystem inside an Android terminal emulator, but without actually having root access. This means that I need to adjust every reference to e.g. /bin/sh in the source code of every program I'm trying to compile and use.
Setting LD_PRELOAD before starting an application allows me to modify the behaviour of libc functions, just like fakeroot does; so I might just write a library which redirects all syscalls with absolute path names (except /dev, /sys, and /proc for example) to the folder I have write access to.
This library would have to:
Rewrite all path names so they stay inside the fake root directory
Nevertheless allow references from outside this directory, because e.g. procfs will still provide system-absolute path names
Ensure that a child process does not accidentally unset LD_PRELOAD
But how well would this turn out? I'm no expert when it comes to low-level code, so:
How consistently could I emulate such a "faked root directory"? Am I doomed from the beginning by the kernel which won't cooperate?
How easy would it be for a process inside the "fake root" to accidentally break out of it? I'm not talking about deliberately trying to escape via assembler code.
Edit: Maybe this library could even serve as a replacement for libc, as long as I link all software I compile on that system against it?
I have experimented little with Android OS and I tried to call System.getenv() to get environmental variables. It works e.g. for $PATH, but I was not able to define own variable, which can be accessible in this way... Is it possible?
I have tried to set and export variables from adb shell as a shell user but it does not work - no matter if I started the application from the phone menu or when I used the adb shell am command.
Can the Runtime.getRuntime().exec() help there? Will it help if I will have root access to the phone?
Thanks
Environment variables are only visible in a process that sets the variable, and child processes launched after setting the variable. When you set the environment variable from the adb shell you are not in the parent process of the process that launches the Android application, so the application cannot see the variable you set.
In Java (and Android) there is no System.setenv(), but if you need to set an environment variable for your own program to read there are always better ways. One such way is setting and getting Properties instead.
Setting environment variables in Java is not really possible (well, it is, but you don't want to do it). You can use ProcessBuilder if you want to set a variable that another process should read, but that's if the process is launched from a Java/Android program.
Think about what problem you're trying to solve, and if it can be done without using environment variables. They're not a good fit in Java, and are even worse on Android.
It is possible to set environment variables in Android applications. However, as #richq said, those variables will be only visible in processes launched from the application that has set environment variable (and JNI libraries used by the application).
See this post for regarding setting environment variables from Android application:
https://stackoverflow.com/a/22315463/927592
Android API 21 provides a way to set the environment variables. To set an environment variable, invoke Os.setenv.
See this android.system.Os documentation and this setenv(3) documentation.
Each process has its own environment, which is copied from the parent process's environment. So the environment variables are per-process.
I don't use java much so what are the common (best practice) locations to install components like this. I want to put them in a system directory so multiple users have access.
Common locations are /opt, /srv, and /usr/local. I tend to lean toward /usr/local.
Note that the Android SDK doesn't really require you to install much, it's mostly self-contained. All you need to do is tell Eclipse where it is. You may also want to add the tools and/or platform-tools directories to the system-wide PATH so that your users can use adb and other tools.
See http://developer.android.com/sdk/installing.html.
On Linux, I typically use /usr/local/android-sdk, but anywhere that makes sense and that won't get clobbered by your system works. Just be aware that it may actually make sense to put the SDK in a per-user location, since it requires write access to create a VM image and to download SDK updates.
To be more concise and allow user writing for things like sdk installations and etc, you could put it somewhere inside the ~/.local directory as per the XDG file system hierarchy like ~/.local/lib/arch-id/android-sdk
Also remember to set the ANDROID_SDK_ROOT env variable to that directory as the ANDROID_HOME variable was deprecated.
It doesnt matter where you put the sdk. Just put it in any folder where all user's can access it...