簡體   English   中英

在Android中重定向C程序的STDIN和STDOUT

[英]Redirecting STDIN and STDOUT of C program in Android

我正在嘗試使用JNI將C程序移植到android。 我已經能夠設置程序並使java和c一起正常工作。 問題是我需要能夠使用STDIN,因為C程序從STDIN讀取輸入並通過STDOUT返回響應(C程序是服務器 - 客戶端應用程序)。 我不知道是否值得一提,但C程序使用STDIN_FILENO文件描述符來讀取STDIN的輸入。 如何使用Java從STDOUT和WRITE讀取到STDIN?

我做了一些研究,並在以下鏈接中找到了一些模糊的解釋: https//groups.google.com/forum/#!topic / installer -ndk / Brm6jPr4C0Y ,我不明白。

這是C代碼https://github.com/unekwu/kemi/blob/master/jni/dnscat/dnscat.c#L1270

更多細節

C程序通常從命令行運行,如dnscat --dns <ip> <port>之后,它開始偵聽來自用戶的消息。 通常從stdin輸入。

現在在我的Android應用程序中,我可以通過調用main和不同的名稱並將ann數組字符串傳遞給它來運行它與JNI。 我驗證程序是否開始糾正。 問題是我將如何將消息發送到程序,因為android上沒有stdin。

我在github上創建了一個項目,你可以從這里下載

它創建了2個命名管道(FIFO),一個用於輸入,另一個用於輸出。

它在本機代碼中以只寫模式打開管道的一端,在Java代碼中以只讀模式打開管道的另一端。 本機代碼中的文件描述符映射到STDOUT,即1,此后對本機代碼中的STDOUT的任何寫入將被重定向到可以用Java代碼讀取的管道的另一端。

它在本機代碼中以只讀模式打開管道的一端,在Java代碼中以只寫模式打開管道的另一端。 本機代碼中的文件描述符映射到STDIN,即0,此后對Java代碼中管道的另一端的任何寫入將由本機代碼使用STDIN讀取。

要實現STDOUT重定向:

本地代碼:

    /*
     * Step 1: Make a named pipe
     * Step 2: Open the pipe in Write only mode. Java code will open it in Read only mode.
     * Step 3: Make STDOUT i.e. 1, a duplicate of opened pipe file descriptor.
     * Step 4: Any writes from now on to STDOUT will be redirected to the the pipe and can be read by Java code.
     */
    int out = mkfifo(outfile, 0664);
    int fdo = open(outfile, O_WRONLY);
    dup2(fdo, 1);
    setbuf(stdout, NULL);
    fprintf(stdout, "This string will be written to %s", outfile);
    fprintf(stdout, "\n");
    fflush(stdout);
    close(fdo);

Java代碼:

/*
 * This thread is used for reading content which will be written by native code using STDOUT.
 */

new Thread(new Runnable() {

    @Override
    public void run() {
        BufferedReader in = null;
        try {
            in = new BufferedReader(new FileReader(mOutfile));
            while(in.ready()) {
                final String str = in.readLine();
                mHandler.post(new Runnable() {

                    @Override
                    public void run() {

                        Toast.makeText(RedirectionJni.this, str, Toast.LENGTH_LONG).show();
                    }

                });
            }
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();

要實現STDIN重定向:

本地代碼:

    /*
     * Step 1: Make a named pipe
     * Step 2: Open the pipe in Read only mode. Java code will open it in Write only mode.
     * Step 3: Make STDIN i.e. 0, a duplicate of opened pipe file descriptor.
     * Step 4: Any reads from STDIN, will be actually read from the pipe and JAVA code will perform write operations.
     */
    int in = mkfifo(infile, 0664);
    int fdi = open(infile, O_RDONLY);
    dup2(fdi, 0);
    char buf[256] = "";
    fscanf(stdin, "%*s %99[^\n]", buf); // Use this format to read white spaces.
    close(fdi);

Java代碼:

/*
 * This thread is used for writing content which will be read by native code using STDIN.
 */
new Thread(new Runnable() {

    @Override
    public void run() {
        BufferedWriter out = null;
        try {
                out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(mInfile)));
            String content = "This content is written to " + mInfile;
            out.write(content.toCharArray(), 0, content.toCharArray().length);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();

如果您需要任何幫助,請告訴我。

在Java代碼中,獲取命令行

Process p;
p = Runtime.getRuntime().exec("su"); // or execute something else, su is just to get root
DataOutputStream dos = new DataOutputStream(p.getOutputStream());
dos.writeBytes(ForExampleABinaryPath+" &\n");
dos.flush();

// to read (might has to run parallel in different thread)
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
is.readLine() // will get you a line o null

使用write && flush並行讀取,您可能能夠實現目標。 祝好運

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM