Почему fgets терпит неудачу, когда я использую 0 как FILE * для чтения из stdin в цепочке rop?

#buffer-overflow #stack-overflow

#переполнение буфера #переполнение стека

Вопрос:

Я создаю цепочку rop для вызова fgets с stdin в качестве входных данных, чтобы иметь возможность создавать базовый stackoverflow.

Но моя проблема в том, что когда я вызываю fgets с 0 в качестве третьего аргумента (для stdin), fgets вылетает при

  <fgets 49>       mov    ecx, DWORD PTR [esi]
  

где esi является третьим аргументом, которым я управляю, почему он падает? С 0 он не должен пытаться прочитать его содержимое и просто читать из stdin, нет?

Полезная часть моей цепочки ropchain выглядит так :

 fgets.plt
pop_pop_pop_ret
buffer
0x500
0
  

Я понятия не имею, почему это не работает
, выполненный вызов выглядит примерно так :

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

Спасибо

Комментарии:

1. Этот вопрос относится к StackOverflow, а не к безопасности StackExchange.

2. Третий аргумент, ожидаемый fgets, является указателем на FILE структуру, а не целочисленным файловым дескриптором.

3. потому что 0 не является допустимым ФАЙЛОМ * ? Что происходит при вызове fgets(buffer, 0x500, NULL) на C?

Ответ №1:

Вы путаете файлы stdio ( FILE* высокоуровневый интерфейс для файлов) и дескрипторы файлов (число). fgets является функцией stdio и принимает a FILE* в качестве аргумента. Стандартным вводом является дескриптор файла 0, но stdin в интерфейсе stdio. Аналогично, стандартный вывод равен 1 и stdout , а стандартная ошибка равна 2 и stderr .

Передача 0 (или любого небольшого целого числа), где fgets ожидается a, FILE* приводит к тому, что программа пытается разыменовать это значение как адрес, что приводит к сбою (для 0, который является нулевым указателем, происходит сбой из-за ошибки сегментации; в зависимости от архитектуры, значения, которые не кратны размеру слова, могут завершиться ошибкойс ошибкой шины или незаконной инструкцией).

Комментарии:

1. Спасибо, вы правы, тогда извините за мой глупый вопрос!