I am coding a native application in android and I need to get the default gateway of a device on my application. Here is my current code to get the default gateway.
static int get_default_gateway(char *def_gateway, int buf_size)
{
FILE* pipe;
char buffer[128];
char result[2049];
char cmd[] = "netstat -r | grep ^default | awk '{print $2}'";
pipe = popen(cmd, "r");
if (!pipe) return 1;
memset(result, 0, sizeof(result));
while(!feof(pipe)) {
memset(buffer, 0, sizeof(buffer));
if(fgets(buffer, 128, pipe) != NULL)
{
strcat(result, buffer);
}
}
pclose(pipe);
memset(def_gateway, 0, buf_size);
strncpy (def_gateway, result, buf_size );
return 0;
}
It works on my LG p500 but on some devices it doesn't return anything.
My question is: Does popen() works on android? I read somewhere that it is not included in bionic.
And is there any other method to get the default gateway? I need it to be written in C and not java.
Thank you
Yea, probably popen() should work on any Android. But unfortunately grep and awk - not. Take a look at /proc/net/route - line where Destination equals to 00000000 is your default gateway. Also perhaps you can use NETLINK_ROUTE socket, though I never used it and can't say more.
See also this related question.
Related
The android debug bridge daemon adbd that runs on Android devices may be compiled without root support (ALLOW_ADBD_ROOT=0).
There is a tool called rootadb which is able to patch an existing adbd binary by (as I understood it) replacing the calls to setuid() and setgid() with NOP instructions, effectively preventing it from dropping its privileges.
I don't understand how the code finds the place of the syscalls inside the binary.
As far as I see, it iterates over the all the bytes and checks if the bytes match something:
u32 *sgid = (u32*)&setgid;
int fd = open( "/sbin/adbd", O_RDWR );
fstat( fd, &st );
buf = memalign( 32, st.st_size );
read( fd, buf, st.st_size );
lseek64( fd, 0, SEEK_SET );
for( start = buf, end = start + st.st_size - 0x20; start < end; start++ )
if( !memcmp( &start[1], &sgid[1], sizeof( u32 ) * 2 ) )
memcpy( &start[1], patch, sizeof( patch ) );
How does this work?
With what kind of data are sgid and __setuid actually filled?
I'm not 100% sure, but I have a reasonable idea.
The first line of code loads a pointer to the address of setgid, and treats it as a 32 bit pointer.
The loop iterates over the binary, and looks for occurrences of 8 bytes that equal address of the setgid function. If it finds one, it applies the patch, starting at the first byte of that location.
With what kind of data are sgid and __setuid actually filled?
'u32 *sgid' contains the address of the function 'setgid' and 'u32 *cap' contains the address of 'capset'. __setuid is the function itself but written without the parenthesis '()' we can retrieve the function's address.
I am confident that 0xe3a00000 is not an address to any function's stack frame. And it doesn't point to any location in memory.
With the information given I think 0xe3a00000 in 'patch' is used in the program to restore the state after the sub-routine call and prevent operations that happens after the call,
u32 patch[] =
{
0xe3a00000,
0
};
Below is the snippet that searches and replaces instructions following the call,
for( start = buf, end = start + st.st_size - 0x20; start < end; start++ )
if( !memcmp( &start[1], &sgid[1], sizeof( u32 ) * 2 ) )
memcpy( &start[1], patch, sizeof( patch ) );
Here the next 8 bytes from &sgid[1] should have state information along with the jump instructions to setgid function which is replaced by instruction in patch.
This effectively results in no-op. This is my understanding.
Please check how stack and frame tends to grow in android architecture also about the prologue and epilogue of the functions in this architecture. It will point you in the right direction as to why &sgid[1] (or sgid + 4 bytes) was used.
You could also refer,
https://softwareengineering.stackexchange.com/questions/195385/understanding-stack-frame-of-function-call-in-c-c
https://en.wikipedia.org/wiki/Call_stack#Stack_and_frame_pointers
I am working on Android platform, and I wonder if it is possible to start an Android app from the kernel source code. For example, at certain point along the linux kernel resume path, I want to start a specific app, say my custom lock screen app. Is that possible?
Edit:
the call_usermodehelper does not work with the "am" utility.
I have code like this in a kernel module:
int result = 0;
char *argv[] = { "/system/bin/am", "start", "-n", "com.twitter.android/com.twitter.applib.HomeTabActivity", NULL};
char *argv[] = {"/system/bin/ls", NULL};
static char *envp[] = {"HOME=/", "PATH=/sbin:/system/sbin:/system/bin:/system/xbin", NULL };
result = call_usermodehelper(argv[0], argv, envp, 1);
but when I insmod, the nothing happens, and result = -8
anyone can help?
I can't speak for certain about Android, but in vanilla Linux, there's a bunch of API's in kmod.h which can do what you want. See this article for details.
Does anyone understand which system call belong I/O component (WiFi, SDcard or GSP etc.)?
I am using strace to trace application, and now, I have A application (A application just have wifi on/off functions, A's PID=999), and I use cmd to key command
./strace -p 999 -t -v
if I use this command ./strace -p 999 -t -v -e trace=open,close,read,write output for example:
04:18:11.473383 read(52, "D", 1) = 1
04:18:11.476191 write(39, "W", 1) = 1
04:18:11.477198 write(53, "u", 1) = 1
04:18:11.478114 read(38, "W", 16) = 1
04:18:11.583430 read(52, "D", 1) = 1
04:18:11.584315 write(39, "W", 1) = 1
04:18:11.586787 write(53, "u", 1) = 1
04:18:11.587824 read(38, "W", 16) = 1
04:18:11.794337 read(38, "W", 16) = 1
04:18:11.800227 read(38, "W", 16) = 1
04:18:11.802210 syscall_983042(0x4e1d5428, 0x4e1d542c, 0, 0xfff, 0x408e54d8, 0x4e1d5428, 0x4e1d8469, 0xf0002, 0, 0x4e1d542c, 0xf81ef003, 0x14, 0, 0xbee5c738, 0x408b6093, 0x4006c8fc, 0x40000010, 0x4e1d5428, 0, 0, 0xc764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) =
But output have so many...I can't explain then...
So, I want to know
What system call name is belong component (belong wifi or belong SDcard)
How can I use component to get component's system call(What command should I ues?)
How should using "strace" to trace SDcard? Should I have B application (B application just have open SDcard or close SDcard?) I don't know what experiment I can do.
All this calls belong to file-system component. Which are then routed through the kernel to the actual hardware drives. So there is no way to know just by looking at system calls.
What you need to do is to look for the open calls to see what file is being opened. The call will return a number, called file handle. This number is later used as a first argument to read / write / close calls.
Things are even tricker for WIFI, since you will have to monitor a whole bunch of socket calls as well as things like sendto. Plus you'll need to cross reference the routing map.
Basically, what you are trying to do is really hard to do on syscall level. I used to do such things in the past by going a level deeper, to the kernel and drivers. There you are
much closer to actual hardware to see the context.
Note that to get a bit more visibility on what the file descriptors are (if you continue to play with strace), you can use the -y option of recent strace versions (at least 4.8 has it). -y will decode the the file descriptors to a path.
I have a question about ADB, does anyone know what is the difference between:
adb shell & adb hell commands?
I'm wondering if except the "hellish" terminal color(only on Linux, in Windows you just get some prefixes) there are any other differences?
Seriously check yourself.
Reading the source:
if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
int r;
int fd;
char h = (argv[0][0] == 'h');
if (h) {
printf("\x1b[41;33m");
fflush(stdout);
}
if(argc < 2) {
D("starting interactive shell\n");
r = interactive_shell();
if (h) {
printf("\x1b[0m");
fflush(stdout);
}
...
if (h) {
printf("\x1b[0m");
fflush(stdout);
}
This code confirms that if the shell or hell command starts with an h, extra control sequences for changing terminal colors are output but nothing else.
As far as i know there is no other difference between the two.
I'm facing a wierd problem something can not explain ;)
now i'm developing client program working on the android phone.
this app connects remote server and does something.
core library which's made in C++ (NDK) and Android UI works fine when using WIFI mode
but system freezes when 3G data mode.
i got where this freezing causes, it was in connect() function.
the wierd thing is socket is already set NON-BLOCK mode before connect() line.
m_nSock = socket(AF_INET, SOCK_STREAM, 0);
if (m_nSock <= 0)
{
close(m_nSock);
return -1;
}
flags = fcntl(m_nSock, F_GETFL, 0);
fcntl(m_nSock, F_SETFL, flags | O_NONBLOCK);
struct sockaddr_in AddrClient;
memset(&AddrClient, 0x00, sizeof(AddrClient));
AddrClient.sin_family = AF_INET;
AddrClient.sin_addr.s_addr = inet_addr(szIP);
AddrClient.sin_port = htons(nPort);
nRet = connect(m_nSock, (struct sockaddr*)&AddrClient, sizeof(AddrClient));
blocking takes always about 21 seconds. (it may show default time is used somewhere in the kernel, i think.) how can i fix this? what should i search for?
any suggestion is welcome.
thanks in advance.
Try these changes:
put socket to non-blocking mode:
dword mode = 1;
ioctl(socket, FIONBIO, &mode);
back to blocking mode:
mode = 0;
ioctl(socket, FIONBIO, &mode);
This is how it works for me to set blocking mode
Your blocking code doesn't look right - you should be using F_SETFL as the command to set the flags. So:
int flags = fcntl(sock, F_GETFL);
fcntl(sock, F_SETFL, flags | O_NONBLOCK);