Разработка динамических сайтов
SEO услуги
Управление контекстной рекламой

Вход на хостинг

Имя пользователя:*

Пароль пользователя:*

IT-новости

20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла

Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......

подробнее

30.07.2015 Ищем уникальный контент для сайта

Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......

подробнее

11.05.2015 Распространённые ошибки разработчиков сайтов

Не секрет, что в сети Интернет насчитывается миллионы сайтов, и каждый день появляются тысячси новых......

подробнее

Наибольшую угрозу для безопасности системы представляют именно указатели, поскольку они позволяют атакующему осуществлять запись в произвольные ячейки памяти или передавать управление по произвольным адресам, например, на начало самого переполняющегося буфера, в котором расположен машинный код, специально подготовленный злоумышленником и обычно называемый shell-кодом.

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

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

В зависимости от своего местоположения буфера делятся на три независимые категории:

n  локальные буфера, расположенные в стеке и часто называемые автоматическими переменными;

n  статичные буфера, расположенные в секции (сегменте) данных;

n  динамические буфера, расположенные в куче. Все они имеют свои специфичные особенности переполнения, которые мы обязательно рассмотрим во всех подробностях, но сначала немного пофилософствуем.

Неизбежность ошибок переполнения в исторической перспективе

Ошибки переполнения – это фундаментальные программистские ошибки, которые чрезвычайно трудно отслеживать и фундаментальность которых обеспечивается самой природой языка Си – наиболее популярного языка программирования всех времен и народов, – а точнее его низкоуровневым характером взаимодействия с памятью. Поддержка массивов реализована лишь частично, и работа с ними требует чрезвычайной аккуратности и внимания со стороны программиста. Средства автоматического контроля выхода за границы отсутствуют, возможность определения количества элементов массива по указателю и не ночевала, строки, завершающиеся нулем, – вообще песня…

Дело даже не в том, что малейшая небрежность и забытая или некорректно реализованная проверка корректности аргументов приводит к потенциальной уязвимости программы. Корректную проверку аргументов невозможно осуществить в принципе! Рассмотрим функцию, определяющую длину переданной ей строки и посимвольно читающую эту строку до встречи с завершающим ее нулем. А если завершающего нуля на конце не окажется? Тогда функция вылетит за пределы утвержденного блока памяти и пойдет чесать непаханую целину посторонней оперативной памяти! В лучшем случае это закончится выбросом исключения. В худшем – доступом к конфиденциальным данным. Можно, конечно, передать максимальную длину строкового буфера с отдельным аргументом, но кто поручится, что она верна? Ведь этот аргумент приходится формировать вручную, и, следовательно, он не застрахован от ошибок. Короче говоря, вызываемой функции ничего не остается, как закладываться на корректность переданных ей аргументов, а раз так – о каких проверках мы вообще говорим?!

С другой стороны – выделение буфера возможно лишь после вычисления длины принимаемой структуры данных, т.е. должно осуществляться динамически. Это препятствует размещению буферов в стеке, поскольку стековые буфера имеют фиксированный размер, задаваемый еще на стадии компиляции. Зато стековые буфера автоматически освобождаются при выходе из функции, снимая это бремя с плеч программиста и предотвращая потенциальные проблемы с утечками памяти. Динамические буфера, выделяемые из кучи, намного менее популярны, поскольку их использование уродует структуру программы. Если раньше обработка текущих ошибок сводилась к немедленному return, то теперь перед выходом из функции приходится выполнять специальный код, освобождающий все, что программист успел к этому времени понавыделять. Без критикуемого goto эта задача решается только глубоко вложенными if, обработчиками структурных исключений, макросами или внешними функциями, что захламляет листинг и служит источником многочисленных и трудноуловимых ошибок.


Предыдущая страницаОглавлениеСледующая страница
 
[001] [002] [003] [004] [005] [006] [007] [008] [009] [010] [011] [012] [013] [014] [015] [016] [017] [018] [019] [020]
[021] [022] [023] [024] [025] [026] [027] [028] [029] [030] [031] [032] [033] [034] [035] [036] [037] [038] [039] [040]
[041] [042] [043] [044] [045] [046] [047] [048] [049] [050] [051] [052] [053] [054] [055] [056] [057] [058] [059] [060]
[061] [062] [063] [064] [065] [066] [067] [068] [069] [070] [071] [072] [073] [074] [075] [076] [077] [078] [079] [080]
[081] [082] [083] [084] [085] [086] [087] [088] [089] [090] [091] [092] [093] [094] [095] [096] [097] [098] [099] [100]
[101] [102] [103] [104] [105] [106] [107] [108] [109] [110] [111] [112] [113] [114] [115] [116] [117] [118] [119] [120]
[121] [122] [123] [124] [125] [126] [127] [128] [129] [130] [131] [132] [133] [134] [135] [136] [137] [138] [139] [140]
[141] [142] [143] [144] [145] [146] [147] [148]

+7 (831) 413-63-27
ООО Дельта-Технология ©2007 - 2023 год
Нижний Новгород, ул. Дальняя, 17А.
Rambler's Top100