Reputation: 79
I cross-compiled my C application for Android ARM with arm-linux-gnueabi tool under Ubuntu 16.04 LTS. I compiled it with static linking flag. This C application is big and it has complicated makefile. It compiled successfully without any errors. But it behaves differently on Android phone and Ubuntu PC. More precisely i have two problems:
popen()
and system()
functions don't work on Android. They are carried out but do nothing and don't give any errors. This problem i solved with dirty hack.fgets()
functions works strange on Android.1. About first problem.
I did small research and found that Android doesn't use ordinary libc library (glibc or another library which implements POSIX standard properly). It uses Bionic library instead of it (sorry, Android is new OS for me). I looked into popen()
and system()
functions code and noticed that these functions use _PATH_BSHELL
macros. _PATH_BSHELL
is path to the actual system shell. This path is "/system/bin/sh" on Android and "/bin/sh" on Ubuntu.
When i understood it i tried to hook popen()
and system()
functions. I copied code of these functions from the Bionic source, than i defined macros #define _MY_PATH_BSHELL "/system/bin/sh"
and replaced calls like execve(_MY_PATH_BSHELL, argp, environ);
by execve(_MY_PATH_BSHELL, argp, environ);
calls. So it started work properly.
2. About second problem.
On Ubuntu this code works properly:
is_received = false;
while(!is_received) {
FILE *cmd = popen(command, "r");
is_received = fgets(buf, sizeof(buf), cmd) == NULL ? false : true;
}
But on Android fgets()
always returns NULL
and this loop works infinitely long. I tried to use read()
function instead of fgets()
and it worked.
On Android this code with read()
works properly:
is_received = false;
while(!is_received) {
FILE *cmd = hooked_popen(command, "r");
int fd = fileno(cmd);
is_received = read(fd, buf, sizeof(buf)) == 0 ? false : true;
}
My questions.
popen()
and system()
neatly and correctly? I think i have to link statically with Bionic library. Is it right? How can i do it in console without Android Studio? I read that it is necessary to use NDK but it is not clear to me how. fgets()
behavior isn't similar on Android and Ubuntu?Upvotes: 3
Views: 454