Non-root grasping package implementation method on Android devices (Tcpdump method) _android

Source: Internet
Author: User
Tags connect socket readline reserved strlen

Usually we use "runtime.getruntime ()" () EXEC ("command path") when executing a command in an Android application, but when we perform a scratch operation, this command is not available in any way, and the result is printed by the following code. This command must be performed under root permissions.

BufferedReader BRW = new BufferedReader (New InputStreamReader (P.geterrorstream ()));
while (str = Brw.readline ())!= null)
log.d ("Cwmp", "W:" +str);

But our Android devices (including set-top boxes, cell phones, etc.) do not usually have root, and APK's highest privileges are only system privileges. The first thing we need to know is that there are more methods than problems, and in the/system/bin path of the Android device we see a lot of binaries that can get root permissions. Therefore, we can use the C language to achieve grasping package function, through NDK the C code cross compiled into a binary file into the/system/bin path, and given its root permissions, at this time, this binary file has the ability to grasp the package. Now the problem is coming, we now want to call through the APK to the grasp of the package specified, after the completion of the bag and how to inform APK? In fact, Android can use the socket to make the bottom and the framework layer to communicate, specifically, refer to Android using sockets to make the underlying and framework communication implementation method.

Next we will post the key implementation code.

1, write socket service-side code fstiService.cpp, generate executable script Fstiservice

#define SOCKET_NAME "Fstiservice" #define LOGD (...) __android_log_print (Android_log_debug, "itv_assistance", __VA_ args__) #include <jni.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include < string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys /wait.h> #include <sys/un.h> #include <cutils/sockets.h> #include <android/log.h> #include <
unistd.h> #include <time.h> #include <sys/time.h> #include <pthread.h> pthread_t thread[2]; Char s_time[10]; Grasping the time substring char s_command[256];
Grasping package instruction substring//grasping Package instruction: System ("/system/bin/tcpdump-v-w/sdcard/te.pcap"); Get process tcpdump of process number int getpid () {//for Linux C//file *fp = Popen ("ps-e | grep \ ' Tcpdump\ ' |
awk \ ' {print $1}\ ' "," R "); For Android (ARM)//file *FP = Popen ("PS |
grep \ ' Tcpdump\ ', "R"); FILE *FP = Popen ("PS |
grep \ ' Tcpdump\ ', "R");
Char buff[1024] = {0}; while (NULL!= fgets (buff, sizeof (buff), FP));
Cancel line Feed (Buff[strlen) (Buff)-1] = ' yes ';
Pclose (FP);
Char Dst[5] = {0};
char *p = buff;
char *q = DST;
The second string for each line of process information is the process number while (*p!= ') p++;
while (*p = = ") p++;
while (*p!= ') * (q++) = * (p++);
* (q++) = ' ";
Return atoi (DST); //intercept substring (seconds): Grab command) void substring (char *time, Char *command, char *src) {char *p = src; char *q = time; char *s = com
Mand;
while (*p!= '/') * (q++) = * (p++);
* (q++) = ' ";
If the tcpdump command has added an environment variable, add the downlink code//Otherwise delete the next line of code, the client-passed parameter format must be: Num/tcpdump the path p++;
while (*p) * (s++) = * (p++);
* (s++) = ' ";  //Grab package thread void *thread1 (void *arg) {System (S_command);} void *thread2 (void *arg) {int i_time = atoi (s_time); int begin =
Time ((time_t*) NULL); while (1) {if ((time_t*) NULL)-Begin < I_time) {//printf ("Current time (s):%ld\n", Times ((time_t*) null)); continue; El
se {int n = Kill (Getpid (), SIGKILL);
LOGD ("The Kill process result is n=%d", N);
Break
} return 0; ///Create child thread void Thread_create () {int temp; memset (&thread, 0, sizeof (thread));
if (temp = Pthread_create (&thread[0], NULL, THREAD1, NULL)!= 0) logd ("Create tcpdump thread Failure");
Else Logd ("Create tcpdump thread Success");
if (temp = Pthread_create (&thread[1], NULL, THREAD2, NULL)!= 0) logd ("Create count Thread Failure");
Else Logd ("Create count Thread Success");
} void Thread_wait () {if (Thread[0]!= 0) {pthread_join (thread[0], NULL);
LOGD ("Tcpdump thread has terminated");
} if (Thread[1]!= 0) {//pthread_join (thread[1], NULL); printf ("Counter thread has terminated");}  /** * Native Layer socket service End/int main () {int connect_number = 6; int fdlisten =-1, new_fd =-1; int ret; struct Sockaddr_un
PEERADDR;
socklen_t Socklen = sizeof (PEERADDR);
int numbytes;
Char buff[256]; The key step is to get the socket//get the bound socket named "Fstiservice" configured in Init.rc, return-1 is the error condition Fdlisten = Android_get_control_socket (
Socket_name);
if (Fdlisten < 0) {LOGD ("failed to get socket '" socket_name "' errno%d", errno);
Exit (-1); /** * Method Description: Start listening (wait for parameter Fdlisten socket connection, Parameters connect_number specifies the maximum connection requirements that can be processed at the same time) * The client side will receive a econnrefused error if the connection count reaches this limit. The Listen function does not start the connection, just sets the * socket to listen mode, and the client-side connection is actually accept ().
Typically listen () is called after the socket () * bind (), and then the Accept () is invoked.
* Return value: Successful return of 0, failure return-1, error reason exists errno = Listen (Fdlisten, connect_number);
LOGD ("Listen result%d", ret);
if (Ret < 0) {/** * PERROR (s) outputs the reason for the error of a function to the standard device (stderr) * parameter s The string that is referred to is printed first, followed by the error reason String */Perror ("Listen"); exit (-1);
/** * Method Description: Accept (int s, struct sockaddr * addr, socklen_t * Addrlen) is used to accept the socket connection of the parameter S. * Socket must be the bind (), listen () function processing, when there is a socket client connection will return a new socket processing * Code, the next data transfer and read through the new socket processing, And the original parameter S socket can continue to use accept () to accept the new * connection request.
When the connection succeeds, the structure of the parameter addr is populated by the system into the address data of the remote host, and the parameter Addrlen is the SOCKADDR's * structure length.
* Return value: Successfully returned the new socket processing code, failed to return 1, the error reason exists in errno.
* * new_fd = Accept (Fdlisten, (struct sockaddr *) &peeraddr, &socklen);
LOGD ("Accept_fd%d", new_fd); if (NEW_FD < 0) {logd ("%d", errno); Perror ("Accept Error"); exit (-1);}//Loop wait for socket client to send message while (1) {/** * method Description: Rec V (int s, void *buf, size_t len, unsigned int flags is used to receive data from the client socket and to save the data to the memory space pointed to by the parameter buf, and the parameter Len is the maximum length of the data that can be received. * Parameter Flags General SET 0 * return value: Failed return-1/if (numbytes = recv (new_fd, buff, sizeof (buff), 0)) = = 1) {logd ("%d", errno); Perror ("Rec
V ");
Continue
} logd ("The parameter received from socket client is%s", buff); if (strcmp (Buff, "exit")!= 0) {substring (s_time, s_command, Buff); Thread_create (); thread_wait ();} char result[10] = "Su
CCESSP "; /** * Method Description: Send (int s, const void *msg, size_t len, unsigned int flags) * parameter s for the connected socket, parameter msg points to the data content to send, parameter len is the data length, Fla
GS General set 0.
* Return value: Failed return-1, error reason exists errno/int sendr = Send (NEW_FD, result, strlen (result), 0);
APK exit, the buff still cache the previous call command, this time will be an additional scratch bag, fixed the following substitution rewrite buff data strcpy (buff, "exit");
if (Sendr = = 1) {perror ("send"); Close (NEW_FD); exit (0);}
Close (NEW_FD);
Close (Fdlisten);
return 0; }

2, configure the Init.rc file, add the following configuration

Service Fstiservice/system/bin/fstiservice
Socket Fstiservice Stream 777 system system
class main

A service named "Fstiservice" is configured here, and the Android device will automatically start and run the/system/bin/fstiservice script file on startup. Once the server-side code is complete, we need to compile it into an executable script fstiservice,android.mk content as follows:

Local_path: = $ (call My-dir)
include $ (clear_vars)
#指定该模块在所有版本下都编译
local_module_tags: =optional
Local_module: = Fstiservice
local_src_files: = FstiService.cpp
local_ldlibs: =-llog
#编译成动态库
# Include $ (build_shared_library)
#编译成可执行文件
include $ (build_executable)

3. Android Client code

public class Socketclient {private final String socket_name = "Fstiservice"; private localsocket client = null; private
Localsocketaddress address = null;
Private Boolean isconnected = false;
private int connecttime = 1; 
Public socketclient () {client = new Localsocket (),//a socket in the Android reserved namespace In/dev/socket. Only the INIT process could create a socket here = new Localsocketaddress (Socket_name, Localsocketaddress.namespac
e.reserved);
New Connectsocketthread (). Start ();  /** * Send Message * @param msg * @return return the socket service side message Receipt/public string sendmsg (String msg) {if (!isconnected) back Connect
Failure ";
try{BufferedReader in = new BufferedReader (New InputStreamReader (Client.getinputstream ()));
PrintWriter out = new PrintWriter (Client.getoutputstream ());
OUT.PRINTLN (msg);
Out.flush ();
return In.readline ();
}catch (IOException e) {e.printstacktrace ();} return "no Return"; /** * Socket connection thread, if the connection failed will attempt to reconnect 3 times * @author Administrator * * * Private class ConnectsOcketthread extends thread{@Override public void Run () {while (!isconnected && connecttime <= 3) {try{sleep (1
000); LOG.D ("Itv_assistance", "Try to connect socket;")
Connecttime: "+connecttime);
Client.connect (address);
IsConnected = true;
}catch (Exception e) {connecttime++; isconnected = false;
LOG.D ("Itv_assistance", "Connect failure"); /** * Close socket/public void closesocket () {try{client.close ();}
catch (IOException e) {e.printstacktrace ();}} }

At this point, the implementation of the grab on Android devices based on non-root is done, and the next step is to compile the system for testing, and I didn't do it myself, But the Fstiservice script and init.rc configuration file operation to the cooperation manufacturer to do, APK is our own, after testing everything OK.

Click to download Source: Http://xiazai.jb51.net/201611/yuanma/AndroidFstiService (jb51.net)

The above is a small set to introduce the Android device is not the root of the Grasp method (Tcpdump method), to achieve a simulation of the background data login effect, I hope to help everyone, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.