android java程序中調用shell命令

在android 應用的java程序中使用不需要SU權限的shell腳本很簡單:

final String command = "am dumpheap -n " + packageName1 + " /storage/sdcard0/" + packageName1 + "_"
                            + Util.getTime();

try {
                            Runtime.getRuntime().exec(command);
                        } catch (IOException e1) {}

上面的代碼需要程序有system權限。

如果執行需要SU權限的shell,可以這樣:

step1:

#define LOG_TAG "fuck"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <utils/Log.h>
#include <unistd.h>
#include <time.h>
#include <pwd.h>

#include <private/android_filesystem_config.h>
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "Reboot", __VA_ARGS__)

/*
 * SU can be given a specific command to exec. UID _must_ be
 * specified for this (ie argc => 3).
 *
 * Usage:
 * su 1000
 * su 1000 ls -l
 */

static char* whitelist[]= {
    //您程序的包名。

};

//check if the process is permitted to exec spsu
//parameters
//  pid: process id
//return value
//  0: process is in the white list
//  1: process is not in the white list
int checkWhiteList(int pid)
{
    char cmdline[NAME_MAX +1]={0x0};
    char cmdlinePath[PATH_MAX + 1]={0x0};
    FILE* fd;

    sprintf(cmdlinePath, "/proc/%d/cmdline", pid);
    fd = fopen(cmdlinePath, "r");
    if(NULL != fd) {
        if(NULL != fgets(cmdline, sizeof(cmdline), fd)) {
            int i = 0;
            for(i = 0; i < sizeof(whitelist)/sizeof(char*); i++) {
                //because cmdline is divided by '\0', so can directly compare with whitelist
                if(0 == strncmp(whitelist[i], cmdline, strlen(cmdline))) {
                    fclose(fd);
                    return 0;
                }
            }
        }
        fclose(fd);
    }
    return 1;
}

int main(int argc, char **argv)
{
    struct passwd *pw;
    int uid, gid, myuid, ppid;

    if(argc < 2) {
        uid = gid = 0;
    } else {
        pw = getpwnam(argv[1]);

        if(pw == 0) {
            uid = gid = atoi(argv[1]);
        } else {
            uid = pw->pw_uid;
            gid = pw->pw_gid;
        }
    }

    /* Until we have something better, only root and the shell can use su. */
    myuid = getuid();
    ppid = getppid();


/*
    if (0 != checkWhiteList(ppid)) {
    
        return 1;
    }
*/
    if(setgid(gid)) {
  
        return 1;
    }

    if (setuid(uid)) {
        fprintf(stderr,"su: permission denied\n");
        return 1;    
    }
 
    /* User specified command for exec. */
    if (argc == 3 ) {
        if (execlp(argv[2], argv[2], NULL) < 0) {
            fprintf(stderr, "su: exec failed for %s Error:%s\n", argv[2],
                    strerror(errno));
            return -errno;
        }
    } else if (argc > 3) {
        /* Copy the rest of the args from main. */
        char *exec_args[argc - 1];
        memset(exec_args, 0, sizeof(exec_args));
        memcpy(exec_args, &argv[2], sizeof(exec_args));
        if (execvp(argv[2], exec_args) < 0) {
           
                    strerror(errno));
            return -errno;
        }
    }

    /* Default exec shell. */
    execlp("/system/bin/sh", "sh", NULL);

    LOGD("-------mysu: exec failed----------\n");

    return 1;
}


編譯成庫文件mysu, 

#for spsu
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= su.c

LOCAL_MODULE:= mysu

#LOCAL_FORCE_STATIC_EXECUTABLE := true

LOCAL_SHARED_LIBRARIES := libc \
        libcutils \
        libutils


#LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := optional

include $(BUILD_EXECUTABLE)

------------------------------

step2:


adb push ./modules/mysu /system/xbin/

adb shell busybox chmod u+s /system/xbin/mysu

adb shell busybox chmod g+s /system/xbin/mysu

------------------------------------

step3:

public class ShellEngine {
    private static final String TAG = "fuck";
    public ShellEngine() {
        super();
    }

    public final boolean execute(String command) {
        Log.d(TAG, "execute: " + command);

        boolean retval = false;
        try {
            if (null != command) {
                Process process = Runtime.getRuntime().exec("/system/xbin/mysu");
                DataOutputStream os = new DataOutputStream(process.getOutputStream());
                os.writeBytes(command + "\n");
                os.flush();
                os.writeBytes("exit\n");
                os.flush();
                BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                int read;
                char[] buffer = new char[4096 * 1024];
                StringBuffer output = new StringBuffer();
                while ((read = reader.read(buffer)) > 0) {
                    output.append(buffer, 0, read);
                }
                reader.close();
                try {
                    int suProcessRetval = process.waitFor();
                    if (255 != suProcessRetval) {
                        retval = true;
                    } else {
                        retval = false;
                    }
                    Log.d(TAG, "process waitfor: Retval = " + suProcessRetval + " output = " + output.toString());
                } catch (Exception ex) {
                    Log.d(TAG, "Error executing root action", ex);
                }
            }
        } catch (IOException ex) {
            Log.d(TAG, "Can't get root access", ex);
        } catch (SecurityException ex) {
            Log.d(TAG, "Can't get root access", ex);
        } catch (Exception ex) {
            Log.d(TAG, "Error executing internal operation", ex);
        }
        return retval;
    }

--------------------

step4:

調用ShellEngine的excute方法即可執行shell命令。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章