Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Обнаруживает некоторые переполнения буфера, которые перезаписывают возвращаемый адрес функции, адрес обработчика исключений или определенные типы параметров. Причина переполнения буфера — это метод, используемый хакерами для использования кода, который не применяет ограничения размера буфера.
Синтаксис
/GS[-]
Замечания
/GS включен по умолчанию. Если приложение не будет подвержено безопасности, используйте /GS-. Дополнительные сведения о подавлении обнаружения переполнения буфера см. в разделе "Безопасные буфферы".
Проверки безопасности
В функциях, которые компилятор распознает как предмет проблем переполнения буфера, компилятор выделяет место в стеке перед возвращаемым адресом. При входе функции выделенное пространство загружается с помощью файла cookie безопасности, вычисляемого один раз при загрузке модуля. При выходе функции и во время очистки кадра в 64-разрядных операционных системах вызывается вспомогательной функцией, чтобы убедиться, что значение файла cookie по-прежнему совпадает. Другое значение означает, что возможно, произошла перезапись стека. Если обнаружено другое значение, процесс завершается.
Буферы GS
Проверка безопасности переполнения буфера выполняется в буфере GS. Буфер GS может быть одним из следующих:
- Массив размером более 4 байтов, содержит более двух элементов и имеет тип элемента, который не является типом указателя.
- Структура данных, размер которой превышает 8 байтов и не содержит указателей.
- Буфер, выделенный
_allocaс помощью функции. - Любой класс или структура, содержащая буфер GS.
Например, следующие инструкции объявляют буферы GS.
char buffer[20];
int buffer[20];
struct { int a; int b; int c; int d; } myStruct;
struct { int a; char buf[20]; };
Однако следующие инструкции не объявляют буферы GS. Первые два объявления содержат элементы типа указателя. Третий и четвертый операторы объявляют массивы, размер которых слишком мал. Пятая инструкция объявляет структуру, размер которой на платформе x86 составляет не более 8 байт.
char *pBuf[20];
void *pv[20];
char buf[4];
int buf[2];
struct { int a; int b; };
Инициализация файла cookie безопасности
Параметр компилятора /GS требует, чтобы файл cookie безопасности был инициализирован перед запуском любой функции, которая использует файл cookie. Файл cookie безопасности должен быть инициализирован немедленно при входе в EXE или DLL. Это выполняется автоматически, если вы используете точки входа VCRuntime по умолчанию: mainCRTStartup, , wmainCRTStartup, WinMainCRTStartupwWinMainCRTStartupили _DllMainCRTStartup. При использовании альтернативной точки входа необходимо вручную инициализировать файл cookie безопасности путем вызова __security_init_cookie.
Что защищено
Параметр компилятора /GS защищает следующие элементы:
- Возвращаемый адрес вызова функции.
- Адрес обработчика исключений для функции.
- Уязвимые параметры функции.
На всех платформах /GS пытается обнаружить переполнение буфера в возвращаемый адрес. Переполнение буферов проще использовать на таких платформах, как x86 и x64, которые используют соглашения о вызовах, которые хранят обратный адрес вызова функции в стеке.
Если функция использует обработчик исключений, компилятор внедряет файл cookie безопасности для защиты адреса обработчика исключений. Файл cookie проверяется во время очистки кадра.
/GS защищает уязвимые параметры , передаваемые в функцию. Уязвимый параметр — это указатель, ссылка на C++, тип C-структуры (тип POD C++), содержащий указатель или буфер GS.
Уязвимый параметр выделяется перед файлами cookie и локальными переменными. Переполнение буфера может перезаписать эти параметры. И код в функции, которая использует эти параметры, может вызвать атаку до возврата функции и проверки безопасности. Чтобы свести к минимуму эту опасность, компилятор создает копию уязвимых параметров во время пролога функции и помещает их под область хранения для всех буферов.
Компилятор не делает копии уязвимых параметров в следующих ситуациях:
- Функции, не содержащие буфер GS.
- Оптимизация (
/Oпараметры) не включена. - Функции с списком аргументов переменной (...).
- Функции, помеченные голыми.
- Функции, содержащие встроенный код сборки в первой инструкции.
- Параметр используется только способами, которые, скорее всего, будут использоваться в случае переполнения буфера.
Что не защищено
Параметр компилятора /GS не защищает от атак безопасности всех буферов. Например, если у вас есть буфер и vtable в объекте, переполнение буфера может повредить vtable.
Даже если вы используете /GS, всегда старайтесь писать безопасный код без переполнения буфера.
Установка параметра компилятора в Visual Studio
- Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.
- Перейдите на страницу свойств Свойства конфигурации>C/C++>Создание кода.
- Измените свойство "Проверка безопасности буфера".
Установка данного параметра компилятора программным способом
- См. раздел BufferSecurityCheck.
Пример
Этот пример перезапустит буфер. Это приводит к сбою приложения во время выполнения.
// compile with: /c /W1
#include <cstring>
#include <stdlib.h>
#pragma warning(disable : 4996) // for strcpy use
// Vulnerable function
void vulnerable(const char *str) {
char buffer[10];
strcpy(buffer, str); // overrun buffer !!!
// use a secure CRT function to help prevent buffer overruns
// truncate string to fit a 10 byte buffer
// strncpy_s(buffer, _countof(buffer), str, _TRUNCATE);
}
int main() {
// declare buffer that is bigger than expected
char large_buffer[] = "This string is longer than 10 characters!!";
vulnerable(large_buffer);
}
См. также
Параметры компилятора MSVC
Синтаксис командной строки компилятора MSVC