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?
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.
Im not sure what it is called but ill do my best to explain it. I did search here on stack exchange and found this answer for an allias for path but i dont want to set a variable for it and i already know that. create alias for path
What I need is and its been along time since I seen it but its used with a % or $ or something that when the program runs from the directory it knows where the directory for the game files are. It didn't matter what the directory the program is in as long as the directory 'gameFiles' is in that directory it will work.
Here's my path:
"/storage/emulated/0/MyGame/MyHackGame/jni/gameFiles/oscom.txt"
I think its something like:
"%or$/gameFiles/oscom.txt"
The main problem is I have a project on source forge and don't want my developers to have to change these paths like 100 times to run the program and then I'll have to change them back.
Also iam using aide for android to make the program and using the standard c++ libaray do this might be difficult to do. I'm not even sure if I can add libarays with aide and native code or how to do it.
Use symlinks as Eugene has suggested or modify build scripts to generate user specific paths into binaries or spearate files at build time. These are ignored by version tracking, so no more double mills. Another way might be checking env variables at runtime.
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.
Can I write a custom userspace file system that can be run on non-rooted factory devices through the standard available utilities?
I am aware of the existence of fuse-android, however as far as I have understood, it requires a rooted device. If that is not the case, please do correct me.
The goal I am trying to achieve is create a 'fake' FS that actually is mounted to a file.
I had the same need some time ago and came to the point where I had to admit that's not possible at all (mostly). It shouldn't be a problem to build libfuse for android, also the Java wrapper is no problem.
The real problem is that most of the systems I have seen aren't build with fuse support buildin nor do they provide modules which may be loaded (which would require root, but anyway).
You can easily find out if fuse is enabled by reading /proc/filesystems. It should list fuse, otherwise you will need root. But it's very likely that most android devices are build without fuse support.
My other ideas were to use another filesystem to "fake" something like fuse. This may be possible with nfs or some other network filesystem where you can implement the server by yourself. This whould enable you to write a fake fuse but I don't think it's worth it.
Edit:
And even if many devices would have fuse support buildin chances are high they wouldn't let you mount it as a user, you would need root access as your app wouldn't have the privileges to mount fuse filesystems.
Luminger almost has the right idea. Here's what I found on my Galaxy S3 (on Verizon):
The appropriate fuse stuff does exist in /proc/filesystems. So something must be using it, quite possibly system. However, when I attempt to execute 'fusermount', I get "Cannot execute -- Permission denied."
So it looks like all the FUSE stuff is there, but I've got no idea whether I could actually use it directly (dropbox? sshfs?) without rooting the device.
It depends on your implementation. What it sounds like to me is you want to have a physical file(s) that represent a full user space file system. Perhaps similar to a mounted .iso. If this is the case, I cannot think of any reason for needing root: You simply create/install the file somewhere such as /sdcard/ and "mount" your file system on top of it.
That said, if you want said file system to be accessible from other applications that you do not control, you'll need root as your application will be running in a Android sandbox otherwise.