Android Nougat ProcessBuilder ignores PATH env variable - bug/issue? - android

I'm having android app that extracts some native executable on first run and uses it to do some work. It worked before Nougat and stopped working. After few days or investigation i've found that PATH environment variable is accepted but not taken into account! I'm, trying out if it's a feature or a bug.
First, let's see what we have and if we're able to do the same from cmd.
I've replaced actual android app package with 'my.app.package' and not related output with '...' for SO.
ZTE_BLADE_V0800:/ $ run-as my.app.package
ZTE_BLADE_V0800:/data/data/my.app.package $ whoami
u0_a129
ZTE_BLADE_V0800:/data/data/my.app.package $ ls -l
total 56
drwxrwx--x 2 u0_a129 u0_a129 4096 2017-03-14 16:15 app_build
drwxrwx--x 2 u0_a129 u0_a129 4096 2017-03-15 13:15 app_buildSources
drwxrwx--x 2 u0_a129 u0_a129 4096 2017-03-14 16:15 app_downloads
-rw------- 1 u0_a129 u0_a129 35 2017-03-14 16:16 app_repository
drwxrwx--x 14 u0_a129 u0_a129 4096 2017-03-14 16:16 app_sdk
drwxrwx--x 3 u0_a129 u0_a129 4096 2017-03-14 16:15 app_temp
drwxrwx--x 2 u0_a129 u0_a129 4096 2017-03-14 16:15 cache
lrwxrwxrwx 1 root root 54 2017-03-15 13:15 lib -> /data/app/my.app.package-2/lib/arm
ZTE_BLADE_V0800:/data/data/my.app.package $ ls -l ./app_sdk/
total 96
...
drwx------ 4 u0_a129 u0_a129 4096 2017-03-14 16:16 cppcheck#1.64#1
...
ZTE_BLADE_V0800:/data/data/my.app.package $ ls -l ./app_sdk/cppcheck\#1.64\#1/
total 16
...
drwx------ 3 u0_a129 u0_a129 4096 2017-03-14 16:16 bin
-rw------- 1 u0_a129 u0_a129 0 2017-03-14 16:16 init.done
ZTE_BLADE_V0800:/data/data/my.app.package $ ls -l ./app_sdk/cppcheck\#1.64\#1/bin
total 6960
drwx------ 2 u0_a129 u0_a129 4096 2017-03-14 16:16 cfg
-rwxr-xr-x 1 u0_a129 u0_a129 2345332 2017-03-14 16:16 cppcheck
-rwxr-xr-x 1 u0_a129 u0_a129 1211424 2017-03-14 16:16 libgnustl_shared.so
ZTE_BLADE_V0800:/data/data/my.app.package $ export PATH=$PATH:./app_sdk/cppcheck#1.64#1/bin
ZTE_BLADE_V0800:/data/data/my.app.package $ export LD_LIBRARY_PATH=./app_sdk/cppcheck#1.64#1/bin
ZTE_BLADE_V0800:/data/data/my.app.package $ cppcheck --version
Cppcheck 1.65 dev
ZTE_BLADE_V0800:/data/data/my.app.package $
Now let's try to do the same in Runtime:
ProcessBuilder processBuilder = new ProcessBuilder();
String path =
System.getenv("PATH") +
":./app_sdk/cppcheck#1.64#1/bin";
processBuilder.command(new String[] {
// "sh", "-c", "echo $PATH", // (1) working
// "sh", "-c", "echo $LD_LIBRARY_PATH", // (2) working
"./app_sdk/cppcheck#1.64#1/bin/cppcheck", "--version" // (3) working
// "cppcheck", "--version" // (4) NOT working even with PATH env variable passed
});
processBuilder.directory(new File("/data/data/my.app.package/"));
Map<String, String> env = processBuilder.environment();
env.put("PATH", path);
env.put("LD_LIBRARY_PATH", "./app_sdk/cppcheck#1.64#1/bin");
process = processBuilder.start();
and i get IOException thrown:
Cause: error=13, Permission denied
Cannot run program "cppcheck" (in directory
"/data/data/my.app.package"): error=13
Let's see if PATH is passed correctly.
Uncomment comment (1) and comment the other command lines, confirm it's set:
/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin:./app_sdk/cppcheck#1.64#1/bin
Let's see if LD_LIBRARY_PATH is passed correctly.
Uncomment comment (2) and comment the other command lines, confirm it's set:
./app_sdk/cppcheck#1.64#1/bin
Now let's see if i'm able to run the tool passing full path.
Uncomment comment (3) and comment the other command lines, see it's working now:
Cppcheck 1.65 dev
Wow, even with PATH passed i have to pass full path for the executable. If i use short tool name, i'm getting Permission denied error.
Is it Nougat (since i'm having it starting Nougat only) feature or issue or i missed anything?
I know Nougat introduced more strict security policies but i see no reason for this in my case to stop working as all the files are in app sandbox (internal directory in my app directory).
PS. I can't just replace all short executable names in command-lines as executable can run another executable too using short executable name, so i need to get PATH variable taken into account eventually.

I did not get any response from Google (they are working on it starting Jan 25) so i had to workaround it passing full executable path like in comment (3).

Related

Android Shell root rm folder failed

I created a folder hdr in /sdcard/DCIM/Camera/ by linux c function: mkdir(), but when I set permission, I used '777' but not '0777' uncarefully, and the folder permission like this:
xxx:/sdcard/DCIM/Camera # ll
total 6
drwxrws--T 5 u0_a217 media_rw 3452 2022-03-01 09:26 hdrd
...
xxx:/sdcard/DCIM/Camera/hdrd # ll
total 9
drwxrws--T 2 u0_a217 media_rw 3452 2022-02-25 10:13 20220225_101334_1645755214821
...
xxx:/sdcard/DCIM/Camera/hdrd/20220225_101334_1645755214821 # ll
total 1952
-rw-rw---- 1 u0_a217 media_rw 460800 2022-02-25 10:13 IMG_20220225_101334_1645755214821_0_640x480_p_640x480_SRC.NV12
then , I wanna delete this hdrd folder so I used rm -r hdrd, there is an error:
xxx:/sdcard/DCIM/Camera # rm -r hdrd/
rm: IMG_20220225_101334_1645755214821_0_640x480_p_640x480_SRC.NV12: Math result not representable
...
I don't know why delete failed, I was in root state.
PS: I use lsattr fuction, but not succeed:
xxx:/sdcard/DCIM/Camera # lsattr hdrd
lsattr: reading flags 'hdrd/20220225_101334_1645755214821': Function not implemented

Install directory of Android service

I am analyzing a custom Android device. I tried to enumerate services running in the system (adb shell service list) and I found out that there is a service (let's call it MyService) that I would like to analyze more in depth. It might be a privileged (system) service, if that is a relevant information.
When I run adb shell service list | grep MyService, it returns something like aaa.bbb.ccc.ddd.MyService. I would like to get the code/binary/APK of this service. However, when I run adb shell pm path aaa.bbb.ccc.ddd.MyService, it returns error code 1 and doesn't print any path. The same situation occurs when I execute adb shell pm list packages | grep -i XXX, where XXX is any of aaa,bbb,ccc,ddd or MyService (for the record, aaa and bbb return some packages, but they do not have anything in common with the specific service).
My question is: How can I extract the code/binary/APK/... of the service? How do I find where it is installed?
If root access is needed, that shouldn't be a problem.
I'm new to this problem as well, and had some fun exploring the Android internals. Eventually, I was only able to find the process id that provides the service, and any information associated with that, through /proc and /sys VFS.
Here are my findings:
My first discovery was that, dumpsys <SERVICE_SHORT_NAME> can connect to any service, and ask it to dump its internal state. But this doesn't always include the package name or install directory for that service. I decided to trace system calls from this dumpsys program, using strace. But it turns out that IPC happens through a non-standard /dev/binder device that strace doesn't understand:
$ su
# strace -f -y dumpsys telephony_ims | grep binder | tail
openat(AT_FDCWD, "/dev/binder", O_RDWR|O_CLOEXEC) = 3</dev/binder>
ioctl(3</dev/binder>, BINDER_VERSION, 0x7fd88906b4) = 0
ioctl(3</dev/binder>, BINDER_SET_MAX_THREADS, 0x7fd88906a8) = 0
mmap(NULL, 1040384, PROT_READ, MAP_PRIVATE|MAP_NORESERVE, 3</dev/binder>, 0) = 0x7990b83000
ioctl(3</dev/binder>, BINDER_WRITE_READ, 0x7fd8890460) = 0
ioctl(3</dev/binder>, BINDER_WRITE_READ, 0x7fd8890110) = 0
[pid 15836] ioctl(3</dev/binder>, BINDER_WRITE_READ, 0x7990b7e8a0) = 0
[pid 15836] ioctl(3</dev/binder>, BINDER_WRITE_READ <unfinished ...>
[pid 15836] ioctl(3</dev/binder>, BINDER_THREAD_EXIT, 0) = 0
Luckily, there is still a method to trace what happens inside this binder device. With the help from this other Stack Overflow page, I was able to find the pid running any service.
I will examine the service telephony_ims as an example.
Please run the following commands as root.
First, we need to set up Android Binder Tracing, using commands from the other Stack Overflow page.
cd /sys/kernel/debug/tracing; echo > set_event; echo 1 > events/binder/enable; echo 1 > tracing_on
Then, we must run dumpsys, and immediately afterwards, read the trace logs.
Prerequisite: I used less command, which isn't available on all android devices. If your bash cannot find less, then you could dump the results to a file on SD Card, and open it using a text viewer.
Run (cat /proc/uptime; dumpsys telephony_ims >/dev/null & echo $!; cat /proc/uptime; cat /sys/kernel/debug/trace | tail -n 1000) | less
Look at the resulting output
The first three lines are
16682.46 92635.05
20823
16682.47 92635.12
Search for 20823 from the second line, which is the PID of dumpsys. (The first and third lines are start time timestamp, and end time timestamp, respectively)
Found out that dumpsys is talking with servicemanager:
dumpsys-20823 [006] .... 16682.479173: binder_transaction: transaction=10738057 dest_node=1 dest_proc=563 # more content afterwards, ignored. pid 563 is "servicemanager"
# ... more lines ...
servicemanager-563 [003] .... 16682.479283: binder_transaction: transaction=10738058 dest_node=0 dest_proc=20823 # more content afterwards, ignored.
Then, it turns out that dumpsys-20823 started a child process, 20827:
dumpsys-20823 [004] .... 16682.479808: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
dumpsys-20823 [004] .... 16682.479810: binder_transaction_received: transaction=10738061
dumpsys-20823 [004] .... 16682.479811: binder_return: cmd=0x80407203 BR_REPLY
dumpsys-20823 [004] .... 16682.479812: binder_read_done: ret=0
dumpsys-20823 [004] .... 16682.479813: binder_ioctl_done: ret=0
dumpsys-20827 [006] .... 16682.480058: binder_ioctl: cmd=0xc0306201 arg=0x780a5668a0
dumpsys-20827 [006] .... 16682.480060: binder_command: cmd=0x40406300 BC_TRANSACTION
dumpsys-20827 [006] .... 16682.480077: binder_transaction: transaction=10738063 dest_node=29113 dest_proc=2574 dest_thread=0 reply=0 flags=0x10 code=0x5f444d50
Eventually, it's this child process who gave away the PID of the service ("dest_proc=2574"):
dumpsys-20827 [006] .... 16682.480077: binder_transaction: transaction=10738063 dest_node=29113 dest_proc=2574 dest_thread=0 reply=0 flags=0x10 code=0x5f444d50
Look into this process for its package name / related jars and apks
$ ps -A | grep 2574
radio 2574 875 14414052 120280 SyS_epoll_wait 0 S com.android.phone
$ ls -l /proc/2574/fd | egrep 'apk|jar' | head
lr-x------ 1 root root 64 2020-12-15 13:42 10 -> /apex/com.android.art/javalib/bouncycastle.jar
lr-x------ 1 root root 64 2020-12-15 13:42 102 -> /system/app/Stk/Stk.apk
lr-x------ 1 root root 64 2020-12-15 13:42 11 -> /apex/com.android.art/javalib/apache-xml.jar
lr-x------ 1 root root 64 2020-12-15 13:42 12 -> /system/framework/framework.jar
lr-x------ 1 root root 64 2020-12-15 13:42 13 -> /system/framework/ext.jar
lr-x------ 1 root root 64 2020-12-15 13:42 14 -> /system/framework/telephony-common.jar
lr-x------ 1 root root 64 2020-12-15 13:42 15 -> /system/framework/voip-common.jar
lr-x------ 1 root root 64 2020-12-15 13:42 16 -> /system/framework/ims-common.jar
lr-x------ 1 root root 64 2020-12-15 13:42 18 -> /system/framework/framework-atb-backward-compatibility.jar
lr-x------ 1 root root 64 2020-12-15 13:42 19 -> /apex/com.android.conscrypt/javalib/conscrypt.jar

How to pull via adb the latest screenshot from an Android device?

Is there a method to pull via ADB the latest screenshot from my device ?
-rw-rw---- 1 root sdcard_rw 137047 2017-11-04 14:02 Screenshot_20171104-140236.png
-rw-rw---- 1 root sdcard_rw 67459 2017-11-04 14:05 Screenshot_20171104-140533.png
-rw-rw---- 1 root sdcard_rw 33939 2017-11-04 14:05 Screenshot_20171104-140557.png
-rw-rw---- 1 root sdcard_rw 329546 2017-11-06 11:12 Screenshot_20171106-111218.png
-rw-rw---- 1 root sdcard_rw 437013 2017-11-13 17:57 Screenshot_20171113-175727.png
-rw-rw---- 1 root sdcard_rw 1200088 2017-11-19 13:44 Screenshot_20171119-134405.png
-rw-rw---- 1 root sdcard_rw 146758 2017-12-12 20:19 Screenshot_20171212-201936.png
-rw-rw---- 1 root sdcard_rw 128158 2017-12-18 11:11 Screenshot_20171218-111151.png
How to pull the latest screenshot ?
-rw-rw---- 1 root sdcard_rw 128158 2017-12-18 11:11 Screenshot_20171218-111151.png
Currently i'm pulling all the files using :
adb pull /mnt/sdcard/Screenshots c:\screenshots
Then organize them by date in Windows Explorer
Edit1 I can get the latest file using :
adb shell stat -c %y /mnt/sdcard/Screenshots
ADB doesn't support flags, so you'll have to pull all the files(names), then do some logic to find the most recent file, then pull that.
It's possible using a script, more info in this related question.
I'd suggest capturing the output of the adb command that gets ya the latest file and redirecting that to an adb command that does the pulling.
Based off a somewhat related answer for saving the output of a command to a variable...
FOR /F "tokens=* USEBACKQ" %%F IN (`command`) DO (
SET var=%%F
)
... replace command with the command's output to be captured, then...
adb pull %var% c:\screenshots
... or...
adb pull /mnt/sdcard/Screenshots/%var% c:\screenshots
... should do kinda what ya want.

lib/ directory missing after installing 64 bit Android application

My 32-bit ARM Android apps come with .so files that I dlopen() in my native code. This works just fine, and I can dlopen them at the /data/data/com.domain.app/lib/libX.so location.
If I add 64-bit binaries to my package (arm64-v8a) and install it on a 64 bit Android device, then there will be no /data/data/com.domain.app/lib directory present.
After some investigation, I found that the .so files on a 64-bit Android device end up in a different directory:
/data/app/com.domain.app-1/lib/arm64
And to make matters worse, the '-1' suffix varies, and could be '-2' or something else.
This is a way to check what got installed in the application's home directory:
$ adb shell run-as com.steenriver.biplane '/system/bin/sh -c "pwd"'
/data/data/com.steenriver.biplane
$ adb shell run-as com.steenriver.biplane '/system/bin/sh -c "ls -al"'
drwxrwx--x u0_a108 u0_a108 2017-01-17 15:04 app_.gpg.classloader
drwxrwx--x u0_a108 u0_a108 2017-01-17 15:04 cache
drwxrwx--x u0_a108 u0_a108 2017-01-17 15:04 code_cache
drwxrwx--x u0_a108 u0_a108 2017-01-17 15:04 files
A 32 bit device will have a lib/ entry listed here.
Is there an Android call I can do (Either in Java or native code) that will tell me where the .so files have ended up, so I can dlopen() them?
For 64-bit ARM, there is no longer a symbolic link made to the library directory. To find the .so files, you can use the following Java code in onCreate()
import android.content.pm.PackageInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
...
ApplicationInfo ainfo = this.getApplicationContext().getPackageManager().getApplicationInfo
(
"com.domain.app",
PackageManager.GET_SHARED_LIBRARY_FILES
);
Log.v( TAG, "native library dir " + ainfo.nativeLibraryDir );
Compare this with 32-bit ARM, where a symlink is provided:
$ adb shell run-as com.steenriver.littlecrane '/system/bin/sh -c "pwd"'
/data/data/com.steenriver.littlecrane
$ adb shell run-as com.steenriver.littlecrane '/system/bin/sh -c "ls -al"'
drwxrwx--x u0_a109 u0_a109 2017-01-18 11:48 app_.gpg.classloader
drwxrwx--x u0_a109 u0_a109 2017-01-18 11:26 cache
drwxrwx--x u0_a109 u0_a109 2017-01-18 11:48 code_cache
drwxrwx--x u0_a109 u0_a109 2017-01-18 11:47 files
lrwxrwxrwx root root 2017-01-18 11:48 lib -> /data/app/com.steenriver.littlecrane-2/lib/arm

Managing files in Android terminal

Using a terminal emulator in my android phone I accidentally copied /proc directory into another user directory. Now I want to delete the copy but I don't have the permissions to do so. I tried to change ownership and permissions to 777 but with no success. I am using Oneplus 2 and termux application. Any suggestions?
Edit:
The original /proc directory :
dr-xr-xr-x 459 root root 0 Jan 1 1970 proc/
it was copied to /.../line/proc:
Line:
drwxrwxrwx 4 u0_a45 u0_a45 4096 Oct 17 12:23 line/
Line/proc:
dr-xr-xr-x 52 u0_a45 u0_a45 4096 Jan 1 1970
proc/
The new proc directories are not removable:
rm -rf line/proc
rm: can't remove 'line/proc/12159/task/12247': Permission denied
...

Categories

Resources