【发布时间】:2022-11-25 06:39:30
【问题描述】:
我有两个可执行文件。第一个(目标)将数据打印到标准输出,从标准输入读取数据并将另一个数据打印到标准输出。第二个(包装器)是第一个的包装器。它分叉,更改子标准输入和标准输出,然后执行目标。
我希望包装器获取目标的标准输出、打印它、将数据发送到目标的标准输入并获取最后一个目标的数据。但是命令方块没有打印任何东西。
目标代码(我有一个约束,我不能修改这段代码):
#include <stdio.h>
int main(){
char buffer[0x100] = { 0 };
printf("First line\n");
printf("Input:");
scanf("%s", buffer);
printf("Last line\n");
return 0;
}
包装器代码:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#define READING_IDX 0
#define READING_IDX 0
#define WRITING_IDX 1
int main(int argc, char *argv[], char *env[]){
pid_t pid = 0;
int pipeStdin[2] = {0};
int pipeStdout[2] = {0};
char buffer[1024] = {0};
int ret = 0;
if (pipe(pipeStdout) == -1){
perror("pipe");
return 1;
}
if (pipe(pipeStdin) == -1){
perror("pipe");
return 1;
}
if ((pid = fork()) == -1){
perror("fork");
return 1;
}
else if (pid == 0){
close(pipeStdin[WRITING_IDX]);
close(pipeStdout[READING_IDX]);
if (dup2(
pipeStdin[READING_IDX],
STDIN_FILENO
) == -1){
perror("dup2");
return 1;
}
if (dup2(
pipeStdout[WRITING_IDX],
STDOUT_FILENO
) == -1){
perror("dup2");
return 1;
}
if (execve(
"./target",
argv + 1,
env
) == -1){
perror("execve");
return 1;
}
}
else{
close(pipeStdin[READING_IDX]);
close(pipeStdout[WRITING_IDX]);
ret = read(
pipeStdout[READING_IDX],
buffer,
1023);
if(ret == -1){
perror("read");
return 1;
}
printf("%d\n", ret);
buffer[ret] = 0;
printf("%s\n", buffer);
ret = write(
pipeStdin[WRITING_IDX],
"Response\n",
sizeof("Response\n")
);
}
return 0;
}
我构建这两个可执行文件:
gcc -o target target.c && gcc -o wrapper wrapper.c
感谢任何帮助。
I see that child process block at read syscall. I think it is at the scanf line. But target does not write any data.
The strace logs:
>! execve("./wrapper", ["./wrapper"], 0x7ffca81b4f78 /* 50 vars */) = 0
brk(NULL) = 0x55bc56890000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=310009, ...}) = 0
mmap(NULL, 310009, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f28eaf36000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260A\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1820400, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f28eaf34000
mmap(NULL, 1832960, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f28ead74000
mprotect(0x7f28ead96000, 1654784, PROT_NONE) = 0
mmap(0x7f28ead96000, 1339392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f28ead96000
mmap(0x7f28eaedd000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x169000) = 0x7f28eaedd000
mmap(0x7f28eaf2a000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7f28eaf2a000
mmap(0x7f28eaf30000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f28eaf30000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f28eaf35500) = 0
mprotect(0x7f28eaf2a000, 16384, PROT_READ) = 0
mprotect(0x55bc55a1b000, 4096, PROT_READ) = 0
mprotect(0x7f28eafa9000, 4096, PROT_READ) = 0
munmap(0x7f28eaf36000, 310009) = 0
pipe([3, 4]) = 0
pipe([5, 6]) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f28eaf357d0) = 13384
strace: Process 13384 attached
[pid 13383] close(5 <unfinished ...>
[pid 13384] close(6 <unfinished ...>
[pid 13383] <... close resumed> ) = 0
[pid 13384] <... close resumed> ) = 0
[pid 13383] close(4 <unfinished ...>
[pid 13384] close(3 <unfinished ...>
[pid 13383] <... close resumed> ) = 0
[pid 13384] <... close resumed> ) = 0
[pid 13383] read(3, <unfinished ...>
[pid 13384] dup2(5, 0) = 0
[pid 13384] dup2(4, 1) = 1
[pid 13384] execve("./target", [], 0x7ffec0e88de8 /* 50 vars */) = 0
[pid 13384] brk(NULL) = 0x5564da73c000
[pid 13384] access("/etc/ld.so.preload", R_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid 13384] openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[pid 13384] fstat(3, {st_mode=S_IFREG|0644, st_size=310009, ...}) = 0
[pid 13384] mmap(NULL, 310009, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fbfc376b000
[pid 13384] close(3) = 0
[pid 13384] openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
[pid 13384] read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260A\2\0\0\0\0\0"..., 832) = 832
[pid 13384] fstat(3, {st_mode=S_IFREG|0755, st_size=1820400, ...}) = 0
[pid 13384] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbfc3769000
[pid 13384] mmap(NULL, 1832960, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fbfc35a9000
[pid 13384] mprotect(0x7fbfc35cb000, 1654784, PROT_NONE) = 0
[pid 13384] mmap(0x7fbfc35cb000, 1339392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7fbfc35cb000
[pid 13384] mmap(0x7fbfc3712000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x169000) = 0x7fbfc3712000
[pid 13384] mmap(0x7fbfc375f000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7fbfc375f000
[pid 13384] mmap(0x7fbfc3765000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fbfc3765000
[pid 13384] close(3) = 0
[pid 13384] arch_prctl(ARCH_SET_FS, 0x7fbfc376a500) = 0
[pid 13384] mprotect(0x7fbfc375f000, 16384, PROT_READ) = 0
[pid 13384] mprotect(0x5564d8c2f000, 4096, PROT_READ) = 0
[pid 13384] mprotect(0x7fbfc37de000, 4096, PROT_READ) = 0
[pid 13384] munmap(0x7fbfc376b000, 310009) = 0
[pid 13384] fstat(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
[pid 13384] brk(NULL) = 0x5564da73c000
[pid 13384] brk(0x5564da75d000) = 0x5564da75d000
[pid 13384] fstat(0, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
[pid 13384] read(0, kolk
<unfinished ...>
[pid 13383] <... read resumed> 0x7ffec0e888d0, 1023) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
[pid 13383] --- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
[pid 13383] read(3, <unfinished ...>
[pid 13384] <... read resumed> 0x5564da73d270, 4096) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
[pid 13384] --- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
[pid 13384] read(0, <unfinished ...>
[pid 13383] <... read resumed> 0x7ffec0e888d0, 1023) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
[pid 13384] <... read resumed> 0x5564da73d270, 4096) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
[pid 13383] --- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
[pid 13384] --- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
[pid 13383] read(3, <unfinished ...>
[pid 13384] read(0,
【问题讨论】:
-
您确定程序
"./target"确实是问题中显示的程序吗?请edit你的问题并显示你用来构建和运行程序的命令。请注意,./target是相对于当前工作目录的,它不一定与包装程序可执行文件的位置相同。请将strace输出添加到您的问题中,而不是依赖外部资源。顺便说一句:为什么要将argv + 1传递给execve?通常,argv[0]应该是程序名称,即"./target"。 -
谢谢你的回应。我确定包装器启动目标。两个源代码和两个可执行文件存储在同一个文件夹中。 target 和 wrapper 是更复杂程序的简化。但是我需要解决这个具体问题才能前进。