Перейти к содержанию

stack overflowing в gcc-2.96


Гость

Рекомендуемые сообщения

Люди, подскажите, пжалста!!!

Вот пример проги с void.ru:

void function(int a, int b, int c) {

char buffer1[5];

char buffer2[15];

int *ret;

ret = buffer1 + 12;

/* прога отлично "работает" Smile на gcc-2.95.3 (под FreeBSD)

и на kgcc-2.91.66 (egcs под Linux-2.4.16), но под gcc-2.96 */

// ret = buffer1 + 28; // <-- приходится делать так...

(*ret) += 8; //(*ret) += 10; // и так

void main() {

int x;

x = 0;

function(1, 2, 3);

x = 1;

printf("%d\n",x);

}

В чем дело? Что еще запихивается в стек до buffer1, или там выравнивание проискодит по другому?

Ссылка на комментарий
Поделиться на другие сайты

nu vo pervih, void main() --> eto ploho.

pochemu? : smotri http://www.faqs.org/faqs/C-faq/faq/

vtoroe,

ret eto ukazatel'.

buffer1 --> eto massiv.

buffer1 --> facticheski buffer1[0];

tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu ugodno.

takim obrazom, ret = buffer1 + 12;

zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?).

neudivitel'no shto inogda ret pokazivaet kuda to, a inogda i za predeli. otsyuda i SIGSEGV.

krome togo, ret obyavlen ukazatelen typa int.,

a pokazivaet na char.

navernoe hotelos' sdelat' shto-to typa:

char buffer1[5];

char *ret = NULL;

ret = &buffer1 + 12;

odnako, 12 sovershenno ne garantiruet 12 elementov.Smile)

sovershenno verno bilo zamecheno, shto viravnivanie mozet proishodit....

pravilv'no bilo bi shto to typa:

ret = &buffer1;

ret += (12*sizeof(buffer1[0]));

Ссылка на комментарий
Поделиться на другие сайты

сделал вместо weekly daily...

На следующий день висят оба процесса logrotate

- за вчера (висит без остановки);

- за наступивший день.

Через неделю их будет семь...

Пробовал переносить логи на время в другое место - все равно висят.

В общем, бред...> ret eto ukazatel'.

Точнее в стеке хранится адрес возврата

> buffer1 --> facticheski buffer1[0];

buffer1 == &buffer1[0]

> tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu

> ugodno.

kgcc выделяет память под char buffer1[5], buffer2[10] и int *ret в стеке: "subl $28,%esp" с учетом сохранения стекового указателя

это проверяется командой kgcc -S ex.c (получится асмовский код)

А gcc-2.96 выделяет 56 байт в стеке ,причем, если добавить char buffer3[20], то будет выделено 88 байт....

> takim obrazom, ret = buffer1 + 12;

> zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?).

Не в никуда, а в конкретную ячейку стека (в нашем случае в ней хранится адрес возврата). И на других компиляторах все отлично работает! ВСЕГДА. На gcc-2.96 тоже всегда, но с другим смещенем. А что бы узнать это "другое" смещение нужно уже лезть в асм-файл.

> navernoe hotelos' sdelat' shto-to typa:

> char

Ссылка на комментарий
Поделиться на другие сайты

> ret eto ukazatel'.

Точнее в стеке хранится адрес возврата

> buffer1 --> facticheski buffer1[0];

buffer1 == &buffer1[0]

> tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu

> ugodno.

kgcc выделяет память под char buffer1[5], buffer2[10] и int *ret в стеке: "subl $28,%esp" с учетом сохранения стекового указателя

это проверяется командой kgcc -S ex.c (получится асмовский код)

А gcc-2.96 выделяет 56 байт в стеке ,причем, если добавить char buffer3[20], то будет выделено 88 байт....

> takim obrazom, ret = buffer1 + 12;

> zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?).

Не в никуда, а в конкретную ячейку стека (в нашем случае в ней хранится адрес возврата). И на других компиляторах все отлично работает! ВСЕГДА. На gcc-2.96 тоже всегда, но с другим смещенем. А что бы узнать это "другое" смещение нужно уже лезть в асм-файл.

> navernoe hotelos' sdelat' shto-to typa:

> char buffer1[5];

> char *ret = NULL;

> ret = &buffer1 + 12;

1) ret = buffer1 + 12;

2) тут действует стандартное преобразование типов. Фактически:

buffer1 = buffer1 + 12;

ret = buffer1;

---------------------

Так все таки почему gcc-2.96 отводит "левое" кол-во памяти???

Ссылка на комментарий
Поделиться на другие сайты

> ret eto ukazatel'.

Точнее в стеке хранится адрес возврата

> buffer1 --> facticheski buffer1[0];

buffer1 == &buffer1[0]

> tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu

> ugodno.

kgcc выделяет память под char buffer1[5], buffer2[10] и int *ret в стеке: "subl $28,%esp" с учетом сохранения стекового указателя

это проверяется командой kgcc -S ex.c (получится асмовский код)

А gcc-2.96 выделяет 56 байт в стеке ,причем, если добавить char buffer3[20], то будет выделено 88 байт....

> takim obrazom, ret = buffer1 + 12;

> zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?).

Не в никуда, а в конкретную ячейку стека (в нашем случае в ней хранится адрес возврата). И на других компиляторах все отлично работает! ВСЕГДА. На gcc-2.96 тоже всегда, но с другим смещенем. А что бы узнать это "другое" смещение нужно уже лезть в асм-файл.

> navernoe hotelos' sdelat' shto-to typa:

> char buffer1[5];

> char *ret = NULL;

> ret = &buffer1 + 12;

1) ret = buffer1 + 12;

2) тут действует стандартное преобразование типов. Фактически:

buffer1 = buffer1 + 12;

ret = buffer1;

---------------------

Так все таки почему gcc-2.96 отводит "левое" кол-во памяти???

Ссылка на комментарий
Поделиться на другие сайты

Вообще-то, чтобы получить return address в gcc есть

__builtin_return_address.....

А для того чтобы делать нелокальные переходы вообще-то лучше

setjmp/longjmp

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...