Помощь - Поиск - Пользователи - Календарь
Полная версия: Взять текст из i-ой строчки ListBox
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Delphi
TarasBer
Порядок действий такой:
Сначала посылаем сообщение LB_GETTEXTLEN, чтобы узнать длину текста и i-ой строчке. Потом посылаем сообщение LB_GETTEXT для копирования в специально заготовленный с учётом этой длины буфер. В ВЦЛ тоже ровно так и делается.
Но что меня напрягло. Вторая часть (копирование в буфер) не умеет принимать параметр "максимальная длина буфера". То есть она просто копирует до встречи с нулевым символом. А это значит, что если между узнаванием длины и копированием текста произошло что-то с этим ListBox, например, текст в i-ой строчке удлинился, то получится пресловутое переполнение буфера!
Насколько мои опасения оправданы (ну может там блокировка встроена против такого, мало ли, или копируется не больше байт, чем полученно во время последнего LB_GETTEXTLEN), и как с этим делом бороться? Насколько я видел в ВЦЛ, там нет блокировки компонента на время взятия текста.
IUnknown
Цитата
например, текст в i-ой строчке удлинился, то получится пресловутое переполнение буфера!
Получится. Это известная уязвимость. И не только LB_GETTEXTLEN + (что-то произошло) + LB_GETTEXT могут привести к подобной проблеме... Вот тут почитай еще: http://www.smolensk.ru/user/sgma/MMORPH/N-...ashenkova-1.htm
-TarasBer-
Прочитал ссылку.
И что с этим делать?
Есть ли хотя бы заведомое ограничение на длину текста, чтобы сначала выделить буфер большего размера, а потом сократить?
IUnknown
Цитата
И что с этим делать?
Ничего с этим сделать нельзя. Кроме как надеяться, что между получением размера и получением текста тебе не подсунут данные, вызывающие переполнение. Ну, или не использовать эти сообщения/макросы.

Что интересно, GetWindowText, значит, проверяет длину буфера (The buffer that will receive the text. If the string is as long or longer than the buffer, the string is truncated and terminated with a null character), а для других методов получения текста, этого сделать не догадались. На Embarcadero QualityCentral, кстати, писали об этих уязвимостях еще для версии D6, но репорт закрыт, вышел уже добрый десяток новых версий, а воз и ныне там...
Гость
> Ничего с этим сделать нельзя.

То есть глюк винды?

> На Embarcadero QualityCentral, кстати, писали об этих уязвимостях еще для версии D6

То есть глюк дельфы?

> Ну, или не использовать эти сообщения/макросы.

А какие нужно использовать?
Есть ли что-то вроде "блокировки окна"?
Я без ВЦЛ обойдусь как-нибудь, если что.

> Что интересно, GetWindowText, значит, проверяет длину буфера

Ну дык потому что у сообщения WM_GETTEXT есть параметр, задающий максимальное кол-во копируемых символов.
IUnknown
Много тебе блокировка поможет? Ты от кого защититься-то хочешь? В своем приложении что-ли, на время чтения из ListBox-а обезопасить себя? Тогда EnableWindow и читай спокойно, пользователь твоей программы не изменит данные. А вот от намеренной атаки снаружи, из чужого процесса, это не спасет.

А уж если ты хочешь получать данные из чужого листбокса - так там еще веселее будет, его ж блокировать не будешь, а подсунуть оттуда тебе неправильные данные (как раз и подменить их при получении LB_GETTEXTLEN, ага, чтоб ты выделил память одного размера, а получил - другой) - вообще "как два байта переслать" (С)
-TarasBer-
> А вот от намеренной атаки снаружи, из чужого процесса, это не спасет.

Да, я про этот случай.
Ну и мало ли, не повезёт.

Или надо просто принять, что Винда - это такое место, где нет смысла думать о высоких материях, типа безопасность, реальность времени итд?
IUnknown
А чего Винда-то сразу? Другие ОСи не лучше:
Цитата
Никогда не предполагайте, что файл или каталог не существуют, даже если проверили его наличие. Взломщик может воспользоваться временем между проверкой существования и созданием файла. Может показаться, что промежуток слишком мал, и шансов успешной атаки практически нет, но не обольщайтесь! Множество успешных разрушающих атак были проведены на UNIX-системы в условиях конкуренции за ресурсы, и имеется несколько свидетельств об успешных нападениях такого типа на Windows. Это не значит, что Windows менее уязвима — просто она, как правило, не поддерживает несколько одновременно работающих локальных пользователей, если только не запущена служба терминалов (Terminal Services).
(С) Майкл Ховард, "Защищенный код".

Кстати, почитай эту книгу, если еще не читал. Там много полезного...
-TarasBer-
> А чего Винда-то сразу? Другие ОСи не лучше:

Ну есть же разница "под эту систему можно случайно написать незащищённую программу" и "под эту систему вообще хрен ты напишешь защищённую программу".
IUnknown
Стоп... Каким образом можно подсунуть в ListBox новое значение элемента вместо старого? Я знаю один способ: LB_INSERTSTRING в нужное место другой строки + LB_DELETESTRING старой + (если нужно) LB_SETCURSEL. Тебе известны еще способы сделать это?

Вышеуказанный метод блокируется запретом LB_INSERTSTRING/LB_DELETESTRING на то время, пока получается размер строки/выделяется буфер/читается строка.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.