使用 EOL 模拟对 STDIN 的输入
Simulate input to STDIN with EOL
我正在测试一种模拟应用程序特定输入的方法。
这是应用程序:
#include <stdio.h>
int main()
{
int num1;
char buffer[6] = {0};
scanf("%d", &num1);
read(0, buffer, 6);
printf("num1 = %d\n", num1);
for(num1=0; num1 < 6; num1++)
{
printf("%02X\n", buffer[num1]);
}
return 0;
}
我正在尝试使用以下 bash 命令模拟输入:
echo -ne "1337\x0A\x31\x02\x03\x04\x05\x06" | ./test
我得到的输出如下:
num1 = 1337
00
00
00
00
00
00
如您所见,缓冲区中没有填充传递给 STDIN 的值。
编辑:
下面的函数只是用来说明混合i/o函数中输入自动化的一个思路,这个函数是我逆向一个二进制文件得到的,是否可以实现输入自动化?
感谢您的帮助。
谢谢,
切勿将 scanf 等 stdio 函数与 read 等低级 io 函数混合使用。 Stdio 维护一个缓冲区以提高效率,如果在调用 scanf 时有任何额外数据可用,它可能会读取它来填充缓冲区。
使用 fread 而不是 read。另外,不要忘记检查这些函数的 return 值。
您正在混合 scanf()
(section 3 man page) and read()
(section 2 man page)。 scanf()
系列函数执行 缓冲 读取和写入。第 2 read()
部分是无缓冲的。您尝试使用 read()
读取的字节已被读取并放入缓冲区 scanf()
正在使用。
如果您注释掉 scanf()
行,并将命令更改为
echo -ne "\x0A\x31\x02\x03\x04\x05\x06" | ./test
你会得到
num1 = 0
0A
31
02
03
04
05
因此只需使用缓冲函数或非缓冲函数即可。选一个。
这里发生了什么?
echo
正在写入与您在命令行中输入的字符一样多的字符(当您使用 -n
标志时,它不会输出最终的 \n
字符)。
- 您正在管道上使用
scanf()
,因此它首先读取完整的缓冲区,然后扫描缓冲区以查找整数。它执行 n = read(0, buffer, BUFSIZ);
returning 11 作为读取到 scanf 的字符数,然后 scanf 扫描缓冲区,returning 1337
作为读取的数字并保留所有字符将其传递到缓冲区中。
- 然后你做一个
read(0, buffer, 6);
returns 0 并且缓冲区没有用数据初始化。
- 然后将之前未初始化的缓冲区内容打印到标准输出。
fifos(或管道)在输入时的行为与终端完全不同。当您按下 enter
键时,终端驱动程序只是使读取完成,使读取得到一个输入行读取的实际字符数。当您使用 fifo 执行此操作时,reader 进程将被阻塞,直到将足够多的字符(实际请求的字符数)提供给进程,然后该数字(实际请求的字符数)为 return 阅读。
如果你有检查 read(2)
return 值的预防措施,你应该得到读取字符的实际数量(应该是 0
作为 scanf(3)
已经吃掉了完整的缓冲区,因为它小于 BUFSIZ
常量,在第一次读取时)
我正在测试一种模拟应用程序特定输入的方法。 这是应用程序:
#include <stdio.h>
int main()
{
int num1;
char buffer[6] = {0};
scanf("%d", &num1);
read(0, buffer, 6);
printf("num1 = %d\n", num1);
for(num1=0; num1 < 6; num1++)
{
printf("%02X\n", buffer[num1]);
}
return 0;
}
我正在尝试使用以下 bash 命令模拟输入:
echo -ne "1337\x0A\x31\x02\x03\x04\x05\x06" | ./test
我得到的输出如下:
num1 = 1337
00
00
00
00
00
00
如您所见,缓冲区中没有填充传递给 STDIN 的值。
编辑: 下面的函数只是用来说明混合i/o函数中输入自动化的一个思路,这个函数是我逆向一个二进制文件得到的,是否可以实现输入自动化?
感谢您的帮助。
谢谢,
切勿将 scanf 等 stdio 函数与 read 等低级 io 函数混合使用。 Stdio 维护一个缓冲区以提高效率,如果在调用 scanf 时有任何额外数据可用,它可能会读取它来填充缓冲区。
使用 fread 而不是 read。另外,不要忘记检查这些函数的 return 值。
您正在混合 scanf()
(section 3 man page) and read()
(section 2 man page)。 scanf()
系列函数执行 缓冲 读取和写入。第 2 read()
部分是无缓冲的。您尝试使用 read()
读取的字节已被读取并放入缓冲区 scanf()
正在使用。
如果您注释掉 scanf()
行,并将命令更改为
echo -ne "\x0A\x31\x02\x03\x04\x05\x06" | ./test
你会得到
num1 = 0
0A
31
02
03
04
05
因此只需使用缓冲函数或非缓冲函数即可。选一个。
这里发生了什么?
echo
正在写入与您在命令行中输入的字符一样多的字符(当您使用-n
标志时,它不会输出最终的\n
字符)。- 您正在管道上使用
scanf()
,因此它首先读取完整的缓冲区,然后扫描缓冲区以查找整数。它执行n = read(0, buffer, BUFSIZ);
returning 11 作为读取到 scanf 的字符数,然后 scanf 扫描缓冲区,returning1337
作为读取的数字并保留所有字符将其传递到缓冲区中。 - 然后你做一个
read(0, buffer, 6);
returns 0 并且缓冲区没有用数据初始化。 - 然后将之前未初始化的缓冲区内容打印到标准输出。
fifos(或管道)在输入时的行为与终端完全不同。当您按下 enter
键时,终端驱动程序只是使读取完成,使读取得到一个输入行读取的实际字符数。当您使用 fifo 执行此操作时,reader 进程将被阻塞,直到将足够多的字符(实际请求的字符数)提供给进程,然后该数字(实际请求的字符数)为 return 阅读。
如果你有检查 read(2)
return 值的预防措施,你应该得到读取字符的实际数量(应该是 0
作为 scanf(3)
已经吃掉了完整的缓冲区,因为它小于 BUFSIZ
常量,在第一次读取时)