C - 输出垃圾字符
C - Junk characters on output
比方说,我有两个程序 - input.c 和 output.c
我想要做的就是使用 execl() 函数将 payload/characters 格式的 payload/characters 发送到另一个格式。
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] = '[=10=]';
execl(target, target, payload, NULL);
//printf("%s\n", payload);
}
++i;
}
return 0;
}
评论的段落仅用于调试目的。因为如您所见(在尝试时),当您只想打印它时,一切正常。
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;
}
当我编译 input.c 时:
gcc input.c -o input
&output.c:
gcc output.c -o output
好的。现在,一切准备就绪。比方说,我想发送一个有效载荷 - 长度 6
./input 6 ./output
但我得到的输出只是这个(或者只是用另一个垃圾字符):
Output: A
Output: 0A
Output: 0,A
Output: 0,�A
Output: 0,�8A
Output: 0,�8�A
我尝试了很多东西,但都失败了,输出仍然是一样的,正如你在上面看到的。
如果有人能帮助我并告诉我哪里出了问题,我将不胜感激。一起使用 fork() 和 execl() 函数会不会有问题?
知道了,你不应该更新 payload
in child 块代码...
这是一个修复程序(现在无法测试):
while(i < length)
{
pid = fork();
payload[i] = 'A';
payload[i + 1] = '[=10=]';
if(pid != 0)
{
waitpid(-1, &status, 0);
//exit(0);
}
if(pid == 0)
{
execl(target, target, payload, NULL);
//printf("%s\n", payload);
}
++i;
}
[删除了不相关的句子]
编辑(补充说明):payload
更新必须在parent和child代码中进行。如果你不明白为什么,我可以补充更多解释。
EDIT2(根据要求)。您需要为 next 分支的 child 进程更新负载。在您的代码中,所有 child 代码都被 execl()
替换为 target
代码。因此 fork()
仅由第一个 parent 进程 (根进程)执行 。
您必须在第一个 parent 之前更新有效载荷并使其在所有 children 中都可以访问。将它放入此块中也不起作用:
// block only executed by the first parent.
if(pid != 0)
{
waitpid(-1, &status, 0);
}
因此,您必须在 parent 和 child 都可以访问的地方更新它:在 fork()
块之后,在 if(pid == 0)
块之前。
在您的代码中,您在公共块中递增 i
,但 parent 的 payload
永远不会更新。因此,在 child 块中,就在 execl()
之前,您在 未初始化的 C 字符串的末尾添加 'A[=22=]'
。
当您的程序分叉时,它会创建一个新进程。这个新进程,在 if(pid == 0)
之后,改变 payload
,并运行 exec(即执行 output
,然后死掉。即,您对有效负载的更改保留在子进程中,并且不影响父进程。只有 ++i
有,这就是为什么您看到的是单元化数据。
在 fork 之前移动有效载荷更改(或至少移出 child-only 块),因此它也在父块中。
比方说,我有两个程序 - input.c 和 output.c 我想要做的就是使用 execl() 函数将 payload/characters 格式的 payload/characters 发送到另一个格式。
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] = '[=10=]';
execl(target, target, payload, NULL);
//printf("%s\n", payload);
}
++i;
}
return 0;
}
评论的段落仅用于调试目的。因为如您所见(在尝试时),当您只想打印它时,一切正常。
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;
}
当我编译 input.c 时:
gcc input.c -o input
&output.c:
gcc output.c -o output
好的。现在,一切准备就绪。比方说,我想发送一个有效载荷 - 长度 6
./input 6 ./output
但我得到的输出只是这个(或者只是用另一个垃圾字符):
Output: A
Output: 0A
Output: 0,A
Output: 0,�A
Output: 0,�8A
Output: 0,�8�A
我尝试了很多东西,但都失败了,输出仍然是一样的,正如你在上面看到的。
如果有人能帮助我并告诉我哪里出了问题,我将不胜感激。一起使用 fork() 和 execl() 函数会不会有问题?
知道了,你不应该更新 payload
in child 块代码...
这是一个修复程序(现在无法测试):
while(i < length)
{
pid = fork();
payload[i] = 'A';
payload[i + 1] = '[=10=]';
if(pid != 0)
{
waitpid(-1, &status, 0);
//exit(0);
}
if(pid == 0)
{
execl(target, target, payload, NULL);
//printf("%s\n", payload);
}
++i;
}
[删除了不相关的句子]
编辑(补充说明):payload
更新必须在parent和child代码中进行。如果你不明白为什么,我可以补充更多解释。
EDIT2(根据要求)。您需要为 next 分支的 child 进程更新负载。在您的代码中,所有 child 代码都被 execl()
替换为 target
代码。因此 fork()
仅由第一个 parent 进程 (根进程)执行 。
您必须在第一个 parent 之前更新有效载荷并使其在所有 children 中都可以访问。将它放入此块中也不起作用:
// block only executed by the first parent.
if(pid != 0)
{
waitpid(-1, &status, 0);
}
因此,您必须在 parent 和 child 都可以访问的地方更新它:在 fork()
块之后,在 if(pid == 0)
块之前。
在您的代码中,您在公共块中递增 i
,但 parent 的 payload
永远不会更新。因此,在 child 块中,就在 execl()
之前,您在 未初始化的 C 字符串的末尾添加 'A[=22=]'
。
当您的程序分叉时,它会创建一个新进程。这个新进程,在 if(pid == 0)
之后,改变 payload
,并运行 exec(即执行 output
,然后死掉。即,您对有效负载的更改保留在子进程中,并且不影响父进程。只有 ++i
有,这就是为什么您看到的是单元化数据。
在 fork 之前移动有效载荷更改(或至少移出 child-only 块),因此它也在父块中。