使用 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 常量,在第一次读取时)