您的位置:首页 > 运维架构 > Shell

android java程序中调用shell命令

2013-10-23 11:42 441 查看
在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命令。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: