Как дополнения в строке формата C / C ++ хранятся в виртуальной памяти Linux? - PullRequest
0 голосов
/ 12 октября 2018

Например, когда мы используем %64d в printf, означает ли это, что 64 байта данных с содержимым кода ASCII для пространства сохраняются в стеке из-за этого %64?(чтобы передать параметры в printf)?

Я спрашиваю это, потому что я смотрел видео, где парень набрал более 100 миллионов пробелов для использования эксплойта строки формата (чтобы затем использовать %nи поэтому пишите конкретный адрес в это место), но я не понимаю, как кто-то может использовать более 100-150 МБ данных (пробелов) в стеке, не выходя за пределы стека?Я думал, что выполнение этого в Linux вызовет ошибку сегмента?

Если наша программа простая printf, то обычно, как долго мы можем идти вверх (в Linux), пока не достигнем конца стека и, таким образом, вызвать ошибку сегмента?

И также,не вызовет ли это проблемы с нашей программой, если мы перезапишем содержимое начала в стеке?Я думал, что это важные вещи, которые нужны программе, такие как переменные env и тому подобное?

Видео, о котором я говорю (оно в конце видео):

https://www.youtube.com/watch?v=t1LH9D5cuK4&t=616s

также в других видео, в которых нет также строки, переданной основной функции, строка формата, которую мы вставили, все еще находится в стеке, а не в куче (используя gdb для показа стека)

1 Ответ

0 голосов
/ 12 октября 2018

Когда вы вызываете printf с такими аргументами, как "%64d" и любым целым числом, которое должно быть напечатано, с добавлением 64 пробелов, пространство, занимаемое стеком, является только пространством, необходимым для самих аргументов: указатель настрока (без учета оптимизации) и целое число.Сами аргументы не расширены для учета заполнения - это работа printf.

Что касается самого расширения, то это может произойти в стеке при достаточно малых размерах заполнения (это то, чтоБиблиотека GNU C работает по крайней мере; я не проверял, определяет ли это стандарт C), но для действительно больших размеров заполнения, таких как упомянутые в вашем примере, расширение будет происходить в куче (если размер заполнения не настолько велик, чтобыprintf завершается неудачно и возвращает ошибку с errno, установленным на EOVERFLOW).

В видео строка формата, используемая для записи более 100M пробелов, представляет собой строку, начинающуюся с целого числа 0x08049724, за которым следует "AAAABBBBCCCC%4$134513000x %4$n" с последующим количеством символов «X», необходимых для заполнения строки до 512 байт.Все, что нужно в стеке для вызова printf, - это указатель на эту строку;поскольку он считывается в буфер в стеке, он также живет в стеке, но это не требование, относящееся к printf.GOT не перезаписывается переполнением буфера, он записывается с помощью аргумента %n в printf, который принимает адрес, явно заданный ему.Автор недвусмысленно говорит, что есть всего 512 символов, с которыми можно поиграться;он никогда не говорит (или не показывает), что миллионы символов записаны где-либо в памяти процесса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...