Почему переменная int не будет предшествовать массиву char с точки зрения адресации, независимо от того, как я ее кодирую в C? - PullRequest
8 голосов
/ 14 августа 2010

Я читаю Взлом: Искусство эксплуатации (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. На самом деле это было еще выше. Почему это? Что я делаю неправильно?

Ответы [ 4 ]

5 голосов
/ 14 августа 2010

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

1 голос
/ 14 августа 2010

Компиляторы могут свободно переставлять переменные, так как они чувствуют себя лучше. Я считаю, что это единственное ограничение в порядке членов структуры. Они должны быть в памяти в том же порядке, как объявлено в структуре.

0 голосов
/ 14 августа 2010

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

Подробнее о том, как это работает, см. http://en.wikipedia.org/wiki/Address_space_layout_randomization,

Забавное совпадение, что вы столкнетесь с этим, и что Мэтт Джойнер наткнется на ответ, пытаясь сжечь яблоко.

0 голосов
/ 14 августа 2010

Я нашел эту тему довольно интересной:

http://www.mail-archive.com/avr-gcc-list@nongnu.org/msg05043.html

Цитата: Теоретически это можно сделать

-fdata-section
...