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

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

我正在制作一个 rop 链来调用 fgets 并将 stdin 作为输入,以便能够制作一个基本的 Whosebug。

但我的问题是,当我使用 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)

谢谢

您混淆了 stdio files (FILE*, a high-level interface to files) and file descriptors(一个数字)。 fgets 是一个 stdio 函数,它接受一个 FILE* 作为参数。标准输入是文件描述符 0,但在 stdio 接口中是 stdin。同样,标准输出为 1 和 stdout,标准错误为 2 和 stderr.

fgets 期望 FILE* 的地方传递 0(或任何小整数)会导致程序尝试将此值取消引用为地址,但失败(对于 0,这是一个空指针,它因分段错误而失败;根据体系结构,不是字长倍数的值可能因总线错误或非法指令而失败。