我正在测试一种模拟应用程序特定输入的方法。 这是应用程序:
#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函数中输入自动化的概念,我通过逆向工程二进制文件获得此功能,是否可以自动输入?
感谢您的帮助。
谢谢,
答案 0 :(得分:1)
您正在混合scanf()
(section 3 man page)和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
所以只需使用缓冲函数或无缓冲函数。选一个。
答案 1 :(得分:0)
永远不要将像scanf这样的stdio函数与低级别的io函数(如read)混合使用。 Stdio维护一个缓冲区以提高效率,如果在调用scanf时有任何额外数据可用,它可能会读取它以填充缓冲区。
使用fread而不是read。另外,不要忘记检查这些功能的返回值。
答案 2 :(得分:0)
这里发生了什么?
echo
正在使用您在命令行中放置的完全相同的字符进行写入(因为您使用-n
标志它不会输出最终的\n
字符。 scanf()
,因此首先读取完整缓冲区,然后扫描缓冲区以获取整数。它执行n = read(0, buffer, BUFSIZ);
返回11作为读取到scanf的字符数,然后scanf扫描缓冲区,返回1337
作为读取的数字,并将所有字符留在缓冲区中。read(0, buffer, 6);
,并且没有用数据初始化缓冲区。 fifos(或管道)与输入端子的行为完全不同。当您按下enter
键时,终端驱动程序只会读取完成,读取以获取一个输入行读取的实际字符数。使用fifo执行此操作时,将阻止读取器进程,直到将足够的字符(读取请求的实际数量)提供给进程,然后通过读取返回该数字(实际上是请求的字符数)。
如果您有预先检查read(2)
返回值的预防措施,则应获取实际的字符数(0
应为scanf(3)
已经吃掉了完整的缓冲区,因为它在第一次读取时小于BUFSIZ
常数