Правильный фрейм стека или переполнение буфера в нём

Тема в разделе "WASM.BEGINNERS", создана пользователем ajak, 7 авг 2008.

  1. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Привет народ. Помогите, дайте правильный кадр стека, а то я совсем замучался, везде приводят разные рисунки и структуры. Вот я сам накатал общий. Подправьте плиз, что где не так, и скажите какие размеры у полей которые постоянны.

    ------+-------------------------------------------
    размер|другой локальный буфер
    ------+-------------------------------------------
    размер|локальный буфер фиксированного размера
    ------+-------------------------------------------
    размер|служебная инф-ция (зависит от компилятора)
    ------+-------------------------------------------
    размер|адрес возврата
    ------+-------------------------------------------
    размер|адрес передаваемого параметра
    ------+-------------------------------------------
    размер|адрес передаваемого параметра
    ------+-------------------------------------------

    1). Где должно быть поле, которые с сохранёнными регистрами при вызове функции?
    2)И второй вопрос. Почему ишад ошибки на тех прогах в никсах у которых установлены флаги suid, sgid? А то я пока не селён в никсах. Спасибо.
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    1. Я не думаю, что есть понятие "правильного" кадра стека. Это скорее зависит от компилятора.

    Например, кадр может выглядеть так:
    0: аргумент.
    4: аргумент.
    8: адрес возврата.
    C: адрес предыдущего стекового кадра.
    10: локальная переменная.
    14: локальная переменная.
    14: сохраненный ebx
    18: сохраненный esi
    1С: сохраненный edi

    2. Имелось в виду, что есть много ошибок в программах с установленным SUIG/SGID? В какой программе вы нашли ошибку?

    Кстати, раз уж речь зашла о стековых кадрах, кто-нибудь знает, откуда они появились? Я подозреваю, что это пережиток 16битного режима, где нельзя было адресоваться относительно sp. Сейчас такой необходимости нет, адресация [esp] разрешена. Получается, что стековый кадр удобен только в случае, когда пишешь на ассемблере и в ф-ии много локальных переменных.
     
  3. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Только каждая команда с [esp+N] занимает на байт больше, чем через [ebp+N].
     
  4. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Ауч. вот как. Ща покурю инфу напишу ещё. Есть вопросики.:)
     
  5. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    А что эти флаги то показывают. Незря ж в них ишят ошибки. Видать они приоритетом выше чтоль
     
  6. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Почему так ?
     
  7. Subrealist

    Subrealist Member

    Публикаций:
    0
    Регистрация:
    17 июл 2006
    Сообщения:
    134
    suid - идентификатор суперпользователя, sgid - идентификатор группы суперпользователя. Программы, у которых установлены данные флаги, позволяют запускать их обычным пользователям с правами администратора. Например, форматирование дискеты в линукс операция привелигерованная, и может выполняться только с правами администатора. В результате, если найти в такой программе ошибку переполнения, можно сделать так, что программа с правами администратора станет выполнять произвольный код, например придостовляющей доступ к оболочке командного интерпретатора - shell. Отсюда и пошло слово шеллкод.
     
  8. Subrealist

    Subrealist Member

    Публикаций:
    0
    Регистрация:
    17 июл 2006
    Сообщения:
    134
    глюки с инетом
     
  9. Subrealist

    Subrealist Member

    Публикаций:
    0
    Регистрация:
    17 июл 2006
    Сообщения:
    134
    удалено
     
  10. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Вот кусок из книги Касперского

    Атака на счётчик цикла

    f(char *dst, char *src)
    {
    char buf[xxx]; int a; intb;
    ...
    b = strlen(src);
    ...
    for(a = 0; a<b; a++) *dst++=*src++;
    }

    И вот что он пишет.

    Если переполнение буфера buf произоёдёт после вызова strlen, переменная b будет жестоко затёрта и наш цикл вылетит далеко на пределы src и dst

    А теперь вопрос. Как вообще может затереться b если buf объявлена перед ней. И значит при переполнении мусор полезет к старшим адресам, а переменная b находиться ниже.
     
  11. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Потому что Intel расширили возможности адресации в 32битном режиме. Код, которым кодируется регистр esp (100b) используется для указания, что в инструкции есть дополнительный байт -- SIB. Этот байт позволяет создавать инструкции типа 'command reg, [base + index * {1, 2, 4, 8} ]'. В результате, единственная возможность закодировать адресацию по esp -- кодировать его в SIB, т.к. код esp в байте MODRM сам по себе используется для указания наличия SIB. По этой же причине регистр esp не может быть индексным регистром, т.к. в случае адресации типа [esp] в байте SIB необходимо указать, что индексный регистр отсутствует. Например, команда 'mov eax, [esp]' кодируется как 'mov eax, [esp + esp * 1]'. Процессор игнорирует esp в качестве индексного регистра, поэтому получается 'mov eax, [esp]'.

    Но обо всех этих деталях лучше почитать в Intel Manual 2A. Там в самом начале рассмотрен формат инструкции.
     
  12. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Ебануться
    ТАк получается переменную b мона затереть вниз, в сторону младших адресов?
     
  13. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Ещё раз прочел,нихрена не понял, какое отношение это имеет к примеру %)
     
  14. Subrealist

    Subrealist Member

    Публикаций:
    0
    Регистрация:
    17 июл 2006
    Сообщения:
    134
    Ну, тут зависит какой код выполнить после
    b = strlen(src);

    Код (Text):
    1.     std
    2.              lea        edi, buff
    3.     lea esi, buff1
    4.     repe    movsb
    то запись будет осуществляться в сторону младших адресов
    А с другой стороны, надо посмотреть, как конкретно кампилятор расставит переменные
     
  15. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    я посмотрел. Вот так
    --------
    return addres
    ----------
    ...
    ---------
    buf[xxx]
    ----------
    int a
    ---------
    int b
    --------

    я так думал что переполнении всегда идёт к старшим адресам
    то есть к адресу возврата, а что мона в другую сторону?
     
  16. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Есть здесь джедаи переполнения
     
  17. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Ерунда стёрта.
     
  18. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Народ, ну помогите, объясниите, в чём прикол. Почему он так пришет?

    Если переполнение буфера buf произоёдёт после вызова strlen, переменная b будет жестоко затёрта и наш цикл вылетит далеко на пределы src и dst

    Я не понимаю. Как может b затереться. Плиз :)
     
  19. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    ajak
    Вообще Subrealist Вам уже объяснил. Я только повторю.
    Не знаю, где Вы смотрели, но MSVC6.0 размещает a и b в стэке по адресам, старшим, чем адрес buf[xxx].
    О возможности переполнения "в обратную сторону" Subrealist тоже упомянул, но такое встречается реже.