C - 输出中的垃圾字符

Yee*_*eez 6 c fork character execl

比方说,我有两个程序--input.c&output.c我想做的就是使用execl()函数将一些"半金字塔"格式的有效载荷/字符发送到另一个.

Input.c中

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#define SIZE 1024

int length;

int main(int argc, char *argv[])
{
    pid_t pid;
    char *target;
    //char payload[length+1];
    char payload[SIZE + 1];
    int status;
    int i = 0;

    if(argc < 2)
    {
        printf("Usage %s <length> <target>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    length = atoi(argv[1]);
    target = argv[2];

    while(i < length)
    {
        pid = fork();

        if(pid != 0)
        {
            waitpid(-1, &status, 0);
            //exit(0);
        }

        if(pid == 0)
        {
            payload[i] = 'A';
            payload[i + 1] = '\0';
            execl(target, target, payload, NULL);
            //printf("%s\n", payload);
        }
        ++i;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

评论段落仅用于调试目的.因为你可以看到(尝试时),当你想要打印它时,一切正常.

output.c(或者如果你想要' target.c ')

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char buffer[30];
    strncpy(buffer, argv[1], sizeof(buffer));
    printf("Output: %s\n", buffer);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我编译input.c时:

gcc input.c -o input
Run Code Online (Sandbox Code Playgroud)

&output.c:

gcc output.c -o output
Run Code Online (Sandbox Code Playgroud)

好.现在,一切都准备好了.让我们说,我想发送一个有效载荷 - 长度为6

./input 6 ./output
Run Code Online (Sandbox Code Playgroud)

但我输出的只是这个(或简单地用另一个junks字符):

Output: A
Output: 0A
Output: 0,A
Output: 0,?A
Output: 0,?8A
Output: 0,?8?A
Run Code Online (Sandbox Code Playgroud)

我尝试了很多东西,但是所有这些都失败了,输出仍然是相同的,正如你在上面看到的那样.

如果有人能帮助我并且可能告诉我问题在哪里,我将非常感激.使用fork()和execl()函数可能会有问题吗?

Ame*_*hel 5

得到它,你不应该更新payload 子块码...

这是一个修复程序(现在无法测试):

 while(i < length)
    {
        pid = fork();
        payload[i] = 'A';
        payload[i + 1] = '\0';

        if(pid != 0)
        {
            waitpid(-1, &status, 0);
            //exit(0);
        }

        if(pid == 0)
        {
            execl(target, target, payload, NULL);
            //printf("%s\n", payload);
        }
        ++i;
    }
Run Code Online (Sandbox Code Playgroud)

[删除不相关的句子]

编辑(附加说明):payload更新必须同时包含父代码和子代码.如果您不明白为什么,我可以添加更多解释.

EDIT2(根据要求).您希望更新有效负载用于下一个分叉子进程.在代码中,所有的子代码被替换execl()target代码.因此,fork()在执行仅通过第一父进程(根之一).

您必须通过第一个父级更新有效负载,并使所有子级都可以访问它.将它放入此块也不起作用:

// block only executed by the first parent.
if(pid != 0)
{
    waitpid(-1, &status, 0);
}
Run Code Online (Sandbox Code Playgroud)

因此,您必须在父级和子级都可访问的位置更新它:fork()if(pid == 0)块之前,之后.

在您的代码中,您i在公共块中递增,但父payload对象永远不会更新.所以在子块中,就在之前execl(),A\0'未初始化的 C字符串末尾添加' .