Как проверить длину полученного массива байтов, который не завершается нулем?
-
25-09-2019 - |
Вопрос
У меня есть код на C \ C ++, который получает структуру по сети из этой формы:
struct DataStruct
{
int DataLen;
BYTE* Data;
}
Код, который у меня есть, выполняется поверх Data
в цикле DataLen
вычисляет время и обрабатывает данные.
...Проблема:
После того, как код попал к экспертам по безопасности для тестирования на проникновение, они подготовили поддельное приложение, которое отправляет эту структуру с DataLen
больше, чем реальная длина Data
.Это вызывает, конечно, исключение нарушения доступа.
Итак, вопрос в том, как я могу проверить реальную длину полученного Data
?Возможно ли это без изменения структуры?
Заранее благодарю.
Решение
Отличные эксперты по безопасности!Я хотел бы, чтобы в моей компании был такой отдел.
Всякий раз, когда данные принимаются из сети, сетевой ввод-вывод сообщает количество байтов, фактически записанных в буфер, независимо от того, использовали ли вы read(2)
, recv(2)
, или boost::asio::async_read
или что-нибудь еще, что я видел.Типичный вариант использования, когда в заголовке вашей структуры данных есть поле "количество байтов для отслеживания", заключается в повторном вызове read /recv /etc до тех пор, пока не будет получено столько байтов (или пока не возникнет ошибка), и только тогда он должен сконструировать и вернуть вашу структуру данных (или сообщить об ошибке).
Другие советы
Вы знаете, сколько байтов вы получили, так что просто сравните его с DataLen
.
Это невозможно без изменения структуры. Данные, полученные от гнезда TCP / IP, является простым потоком. Логично, он не разделен на пакеты. Физический пакет может содержать одно или несколько экземпляров обработки данных, один экземпляр данных может быть разделен на две или более физических пакетов. Текущая информационная структура может использоваться только в том случае, если нет ошибок связи или недопустимых пакетов.
Коррупция легко, если у вас нет никаких внутренних ограничений.
Некоторые механизмы защиты будут:
- Попробуй
realloc()
буфер, в пределах допустимого размера (еслиData
динамичен) - Исключения являются Друзья: используйте
SIGSEGV
вsignal(2)
,signal(7)
а такжеsetjmp(2)
сделать полезное Попробуйте поймать Кодовая структура. Видеть Сочетание setjmp () / longjmp () и обработка сигналов Для быстрого введения на эту тему. Использоватьsigaction(2)
идти глубже (получая неисправный адрес;).