为什么当我使用 0 作为 FILE* 从 rop 链中的标准输入读取时 fgets 失败?

Why does fgets fail when I use 0 as FILE* to read from stdin in rop chain?

我正在 rop chain 以标准输入作为输入调用 fgets 以实现基本堆栈溢出。

但我的问题是,当我使用 0 作为第三个参数(对于标准输入)调用 fgets 时,fgets 在

处崩溃
 <fgets+49>       mov    ecx, DWORD PTR [esi]

其中 esi 是我控制的第三个参数,为什么会崩溃?对于 0,它不应该尝试读取它的内容而只是从标准输入读取,不是吗?

我的 ropchain 的有用部分如下所示:

fgets.plt
pop_pop_pop_ret
buffer
0x500
0

我不知道为什么它不起作用。 调用类似于:

_IO_fgets(buf=0xf7f77000, n=0x500, fp=0x0)

因为stdin不是数字。它是 libc.

中的一个对象
zeltrax@ubuntu:~$ readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep "stdin"
377: 00000000001eb980   224 OBJECT  GLOBAL DEFAULT   31 _IO_2_1_stdin_@@GLIBC_2.2.5
546: 00000000001ec790     8 OBJECT  GLOBAL DEFAULT   31 stdin@@GLIBC_2.2.5

检查这个例子:

#include <stdio.h>
#include <stdlib.h>

int main()
{
        printf("stdin : %p\n", stdin);
        printf("printf: %p\n", printf);
        
        return 0;
}

输出:

zeltrax@ubuntu:~$ gcc test.c
zeltrax@ubuntu:~$ ./a.out
stdin : 0x7fcec21dc980
printf: 0x7fcec2055e10