1

Cで基本的なリバースシェルを書いています:

if(-1 ==  (myShell->pid = fork()))
{
    PipeSet_close(&myShell->pipeSet);
    return RS_ERROR;
}

if(myShell->pid == 0)
{
    /* close pipe ends child doesn't need */
    close(myShell->pipeSet.stdInPipe[1]);
    close(myShell->pipeSet.stdOutPipe[0]);
    close(myShell->pipeSet.stdErrPipe[0]);

    /* dupe 2 the pipes we DO need frm their originals */
    dup2(myShell->pipeSet.stdInPipe[0], fileno(stdin));
    dup2(myShell->pipeSet.stdOutPipe[1],fileno(stdout));
    dup2(myShell->pipeSet.stdErrPipe[1],fileno(stderr));

    /* bash now replaces child process. only returns after bash terminates */
    execl(getenv("SHELL"),NULL,NULL);
    return RS_SUCCESS;
}

親プロセスを使用して、3 つのパイプから読み書きできます。これにより、子を介して基本的なシェル コマンドを実行できます。ls -l、ps、chmod +x など。私が問題を抱えているのは、シェルを使用してユーザー入力を必要とする単純なプログラムを実行するときです。これをテストするには、次のプログラムを使用します。

int main()
{
int opt;
while (1==1)
{
    printf("-----Remote Shell Menu test:------\n");
    printf("   1. print 1\n");
    printf("   2. print 2\n");
    printf("   3. exit\n");
    fflush(stdin);
    scanf("%d",&opt);

    switch (opt)
    {
    case 1: printf("Pressed 1\n"); break;
    case 2: printf("Pressed 2\n"); break;
    case 3: return 0;
    default: printf("unknown menu option %d\n",opt);
    }
}
}

リバース シェルを使用して通常どおりにこのサブ プログラムを操作し、"1" "2" 1" "3" を押しますが、メニューが表示されないか、stdout パイプを介して出力が表示されません。メニュー プログラム全体が終了するまで 3 を押します。

これは、分岐した bash 内から別の bash シェルを生成する場合には当てはまりません...

4

2 に答える 2

1

プロセスがEOFを検出する機会を得られるように、close後でパイプを複製する必要もあります。dup2

perror後に追加できexeclます; より良い使用execlp; argv[0]の代わりに与えNULLます。の場合getenv("SHELL")はどうなりNULLますか?よろしいですbashか?

主に、return何か。テスト1==1は役に立ちませんwhile(無限ループは通常、ので取得されwhile(1)ますfor(;;)

于 2013-03-02T11:30:04.660 に答える
1

あなたfflush(stdin)は何もしません。fflushは、出力ストリームでのみ使用されます。これをに変更するfflush(stdout)と、バッファリングの問題が解決すると思います。

于 2013-03-01T21:22:44.130 に答える