Чтение онлайн

на главную

Жанры

Защита от хакеров корпоративных сетей

авторов Коллектив

Шрифт:

Из рисунка видно следующее. Буфер памяти, инициализированный строкой «Hello World», занимает 16 байт, а каждое целое число занимает область памяти размером по 4 байта. Шестнадцатеричные числа слева от дампа – статические адреса стека, которые определяются компилятором во время трансляции и которые Windows редко использует. Статические адреса стека потребуются для задания точек перехода при изучении возможности использования переполнения буфера в своих целях. Из рисунка 8.3 видно, что в области стека буфер памяти занимает 16 байт, а не 15, как определено в программе. Большинство компиляторов выравнивают область стека и области данных в стеке на границу двойного слова, поэтому области стека и данных начинаются с адреса памяти, кратного четырем. Это является обязательным условием повышения производительности процессора, и многие программы предполагают, что выравнивание обязательно выполняется. Поэтому буфер памяти занимает 16 байт в области стека, а не 15.

Разнообразие стеков

После инициализации стек может измениться по

многим причинам. Опции компилятора влияют на размер и выравнивание стека программы, а настройки оптимизации генерируемого компилятором кода могут сильно изменить механизм создания стека и получения к нему доступа.

Некоторые функции в прологе сохраняют в стеке содержимое отдельных регистров. Во-первых, это делать необязательно, а во-вторых, это полностью зависит от компилятора и функции. В генерируемом компилятором коде может быть или несколько команд сохранения регистров, или одна команда pusha, которая сразу сохраняет содержимое всех регистров. К тому же в прологе могут быть изменены размеры стека и некоторые смещения.

Многие современные компиляторы языков С и С++ оптимизируют генерируемый код различными способами, что сказывается на работе со стеком и стековыми переменными. Например, в одном из наиболее часто встречающихся вариантов оптимизации генерируемого программного кода для доступа к данным в стеке вместо регистра EBP используются ESP. Код получается сложным и трудно поддается анализу, но при этом освобождается лишний регистр, который компилятор использует для генерации более быстрого кода. Другим примером влияния оптимизации кода на работу со стеком служит размещение компиляторами временных переменных в области стека. По разным причинам компиляторы размещают временные переменные в области стека, например для сокращения времени выполнения циклов в программе. Всегда подобные действия сопровождаются тщательной настройкой указателя смещения для доступа к данным стека.

Рассматривая проблемы работы со стеками, нельзя не упомянуть о новых способах защиты стеков программным кодом, генерируемым компиляторами. На них основан проект Crispin Cowen\'s Immunix (www.immunix.com). В проекте используется модифицированный GCC компилятор с языка C для генерации программного кода, практически не позволяющего выполнить злонамеренную программу в результате подмены содержимого регистра EIP при переполнении буфера. Как правило, используется способ, получивший название проверочных величин (canary values). Он основан на записи в прологе дополнительной величины в стек и проверке ее значения в эпилоге функции. При совпадении обоих значений гарантируются целостность стека и неизменность значений сохраненных в стеке регистров EIP и EBP.

Стековый фрейм функции

Как было упомянуто ранее, стек позволяет решить многие задачи. Во-первых, обеспечить локальное хранение переменных и данных функции. Во-вторых, передавать параметры в вызываемую функцию. В этой части главы будет рассказано, как компиляторы передают параметры вызываемым функциям и как это влияет на стек. Кроме того, будет уделено внимание разъяснению вопросов использования стека в командах процессора вызов функции call и возврата из нее ret.

Основные сведения

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

Для того чтобы понять, как работает стек, следует немного знать о командах процессора Intel call и ret. Команда call – основная команда для существования функции. Команда позволяет выполнить другую часть кода, запомнив при этом адрес точки возврата в стеке. Для этого команда call работает следующим образом:

1) проталкивает в стек адрес следующей команды, который является адресом точки возврата – точки, куда процессор передаст управление (возвратится) после выполнения функции;

2) передает управление по указанному в команде call адресу для выполнения команд функции.

А команда ret делает противоположное. Ее задача состоит в том, чтобы возвратиться из вызываемой функции к команде, следующей за командой call. Для этого команда ret выполняет следующие действия:

1) извлекает из стека сохраненный адрес точки возврата;

2) передает управление по только что извлеченному из стека адресу точки возврата.

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

Передача

параметров в функцию. Простой пример

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

На рисунке 8.4 приведена программа, которая поясняет структуру фреймового стека функции и его использование в командах call и ret.

Рис. 8.4. Пример программы, демонстрирующей использование стека в командах вызова и возврата

Дизассемблирование

Приведенная на рис. 8.4 программа была скомпилирована как консольное приложение Windows в режиме построения окончательной версии Release. Результаты дизассемблирования функций callex и main приведены на рис. 8.5 и демонстрируют машинный код функций callex и main после компиляции. Обратите внимание на передачу по ссылке буфера памяти buffer из функции main функции callex. Другими словами, функция callex получает указатель на буфер buffer, а не копию содержащихся в нем данных. Это означает, что все изменения в буфере buffer, выполненные в функции callex, тут же отражаются на содержимом буфера buffer в main, поскольку на самом деле это одна и та же переменная.

Рис. 8.5. Дизассемблированный вид функции callex

Дампы стека

На рисунках 8.6–8.9 представлен стек в различные моменты выполнения программы. Воспользуемся приведенными на рисунках 8.6–8.9 дампами, исходным текстом программы на языке C и ее дизассемблерным видом, для того чтобы лучше понять происходящие в стеке изменения и их причины. Это поможет понять принципы работы фреймового стека функции и его роль и место в программе.

На рисунке 8.6 показан дамп стека сразу после инициализации переменных, но до операций вызова функции и записи в стек ее входных параметров. Это пример «чистого» стека функции.

Рис. 8.6. Дамп стека после инициализации переменных в функции main

Далее, перед вызовом функции callex в стек были помещены ее три параметра (см. рис. 8.7).

Рис. 8.7. Дамп стека до вызова функции callex из функции main

Обратите внимание на произошедшие изменения в дампе стека по сравнению с рис. 8.6. После размещения переменных в области стека функции main в стек были записаны параметры вызываемой функции callex, но сама функция пока еще не была вызвана. На рисунке 8.8 приведен дамп стека функции callex после ее вызова.

Рис. 8.8. Дамп стека после вызова функции callex и выполнения команд пролога, но перед выполнением оператора printf в функции callex

Показанный на рис. 8.8 стек проинициализирован функцией callex. Единственное, что осталось выяснить, – это вид стека перед обращением к функции printf, список параметров которой состоит из четырех элементов.

Наконец, перед обращением в функции callex к функции вывода значений переменных printf в стек помещаются четыре параметра. Это видно из дампа стека, представленного на рис. 8.9.

Рис. 8.9. Дамп стека перед обращением к функции printf в функции callex

Поделиться:
Популярные книги

Машенька и опер Медведев

Рам Янка
1. Накосячившие опера
Любовные романы:
современные любовные романы
6.40
рейтинг книги
Машенька и опер Медведев

Идущий в тени 4

Амврелий Марк
4. Идущий в тени
Фантастика:
боевая фантастика
6.58
рейтинг книги
Идущий в тени 4

Real-Rpg. Еретик

Жгулёв Пётр Николаевич
2. Real-Rpg
Фантастика:
фэнтези
8.19
рейтинг книги
Real-Rpg. Еретик

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

(Противо)показаны друг другу

Юнина Наталья
Любовные романы:
современные любовные романы
эро литература
5.25
рейтинг книги
(Противо)показаны друг другу

Афганский рубеж

Дорин Михаил
1. Рубеж
Фантастика:
попаданцы
альтернативная история
7.50
рейтинг книги
Афганский рубеж

Последний Паладин. Том 7

Саваровский Роман
7. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 7

Мымра!

Фад Диана
1. Мымрики
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Мымра!

Волк 5: Лихие 90-е

Киров Никита
5. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волк 5: Лихие 90-е

Новый Рал

Северный Лис
1. Рал!
Фантастика:
фэнтези
попаданцы
5.70
рейтинг книги
Новый Рал

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Системный Нуб

Тактарин Ринат
1. Ловец душ
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Системный Нуб

Приручитель женщин-монстров. Том 5

Дорничев Дмитрий
5. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 5

Неверный. Свободный роман

Лакс Айрин
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Неверный. Свободный роман