Я читаю Взламывание: Искусство Эксплуатации (2-й Выпуск), и я в настоящее время нахожусь на разделе о переполнении буфера.
В первом примере переменные объявляются/инициализируются в этом порядке:
int auth_flag = 0;
char password_buffer[16];
Пример продолжает объяснять, что можно использовать gdb для исследования auth_flag
и password_buffer
адреса, и Вы заметите это auth_flag
адрес выше, чем password_buffer
. Вещи иметь в виду: я выполняю все это в Ubuntu в Virtualbox на MacBook Pro (процессор Intel, 64-разрядный).
Я скомпилировал код первого примера как это: gcc -g -fno-stack-protector -o auth_overflow auth_overflow.c
Как ожидалось, auth_flag
адрес выше, чем password_buffer
.
Для исправления проблемы, представленной выше, автор объясняет, что необходимо переключить упорядочивание объявлений:
char password_buffer[16];
int auth_flag = 0;
Я скомпилировал код тот же путь: gcc -g -fno-stack-protector -o auth_overflow2 auth_overflow2.c
К сожалению, я не видел auth_flag
причем адрес ниже, чем password_buffer
. На самом деле это было еще выше. Почему это? Что я делаю неправильно?
Компиляторы могут изменять порядок переменных по своему усмотрению. Я считаю, что единственное ограничение в порядке членов структуры. Они должны находиться в памяти в том же порядке, что и в структуре.
Компилятору разрешено выбирать любой порядок, какой он захочет, чтобы обеспечить более оптимальный код, или даже просто случайный, потому что его легче реализовать. Можно попробовать использовать флаг -O0
, который отключает все оптимизации.
Я нашел эту тему довольно интересной:
http://www.mail-archive.com/avr-gcc-list@nongnu.org/msg05043.html
Цитата: Теоретически это можно сделать
-fdata-section
У Apple есть функция безопасности для предотвращения именно такого типа взлома, о котором вы говорите - Существует определенная степень рандомизации того, где все хранится в памяти, так что вы не можете, например, найти память, выделенную для определенной программы, и перейти к 1502-му байту, где находится функция для открытия замков хранилища повышенной безопасности, потому что она не всегда находится в одном и том же месте в памяти.
Смотрите http://en.wikipedia.org/wiki/Address_space_layout_randomization для подробностей о том, как это работает.
Забавное совпадение, что вы столкнулись с этим, а Мэтт Джойнер наткнулся на ответ, когда пытался сжечь яблоко.