Compartilhar via


/GS (verificação de segurança de buffer)

Detecta alguns estouros de buffer que substituem o endereço de retorno de uma função, endereço do manipulador de exceção ou certos tipos de parâmetros.Causar uma saturação de buffer é uma técnica usada por hackers para explorar o código que não impõe restrições de tamanho de buffer.

/GS[-]

Comentários

/GSé ativado por padrão.Se você espera que seu aplicativo para não que nenhuma exposição de segurança, use /GS-.Para obter mais informações sobre /GS, consulte Compilador verifica na profundidade de segurança.Para obter mais informações sobre a supressão de detecção de saturação de buffer, consulte safebuffers.

Verificações de segurança

Nas funções que o compilador reconhece como sujeitos a problemas de saturação de buffer, o compilador aloca espaço na pilha antes do endereço do remetente.Entrada da função, o espaço alocado é carregado com um o cookie de segurança que é calculado de uma vez no carregamento de módulo.Na saída da função e durante o desenrolar do quadro em sistemas operacionais de 64 bits, uma função auxiliar é chamada para certificar-se de que o valor do cookie ainda é o mesmo.Outro valor indica que pode ter ocorrido uma substituição da pilha.Se for detectado um valor diferente, o processo é encerrado.

Buffers de GS

Uma verificação de segurança de saturação de buffer é realizada em um buffer GS.Um buffer de GS pode ser um destes procedimentos:

  • Uma matriz maior que 4 bytes, tem mais de dois elementos e tem um tipo de elemento não é um tipo de ponteiro.

  • Uma estrutura de dados cujo tamanho é maior que 8 bytes e não contém nenhum ponteiros.

  • Um buffer alocado usando o _alloca função.

  • Qualquer classe ou estrutura que contém um buffer de GS.

Por exemplo, as seguintes instruções declare buffers GS.

    char buffer[20];
    int buffer[20];
    struct { int a; int b; int c; int d; } myStruct;
    struct { int a; char buf[20]; };

No entanto, as instruções a seguir não declarará buffers GS.As duas primeiras declarações contenham elementos de tipo de ponteiro.As declarações de terceira e quarta declarar matrizes cujo tamanho é muito pequeno.A quinta instrução declara uma estrutura cujo tamanho em uma plataforma x86 não é mais de 8 bytes.

    char *pBuf[20];
    void *pv[20];
    char buf[4];
    int buf[2];
    struct { int a; int b; };

O /GS opção de compilador requer que o cookie de segurança seja inicializada antes que qualquer função que usa o cookie seja executada.O cookie de segurança deve ser inicializado na entrada para um arquivo EXE ou DLL.Isso é feito automaticamente se você usar os pontos de entrada padrão do CRT (mainCRTStartup, wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartup ou _DllMainCRTStartup).Se você usar um ponto de entrada alternativos, você deve inicializar manualmente o cookie de segurança chamando __security_init_cookie.

O que é protegido.

O /GS opção de compilador protege os seguintes itens:

  • O endereço de retorno de chamada de função.

  • O endereço de um manipulador de exceção para uma função.

  • Parâmetros da função vulnerável.

Em todas as plataformas, /GS tenta detectar saturações de buffer para o endereço do remetente.Saturações de buffer são exploradas com mais facilidade em plataformas como, por exemplo, x86 e x64, as convenções de chamada de uso que armazenam o endereço de uma função de retorno de chamada na pilha.

Em x86, se uma função usa um manipulador de exceção, o compilador injeta um cookie de segurança para proteger o endereço do manipulador de exceção.O cookie é verificado durante o desenrolar do quadro.

/GSprotege parâmetros vulneráveis que são passados para uma função.Um parâmetro vulnerável é um ponteiro, uma referência de C++, uma C-estrutura (tipo de C++ POD) que contém um ponteiro ou um buffer de GS.

Um parâmetro vulnerável é alocado antes do cookie e variáveis locais.Uma saturação de buffer pode substituir esses parâmetros.E código da função que usa esses parâmetros pode causar um ataque antes que a função retornará e a verificação de segurança é realizada.Para minimizar essa possibilidade, o compilador faz uma cópia dos parâmetros vulneráveis durante o prólogo da função e coloca-os abaixo da área de armazenamento para os buffers.

O compilador não faz cópias dos parâmetros vulneráveis nas seguintes situações:

  • Funções que não contêm um buffer de GS.

  • Otimizações (/O opções) não estão ativados.

  • Funções que tem uma lista de argumentos variável (...).

  • Funções que são marcadas com nua.

  • Funções que contêm o código de assembly embutido na primeira instrução.

  • Um parâmetro é usado apenas em formas que têm menor probabilidade de ser explorada no caso de uma saturação de buffer.

O que não está protegido

O /GS opção de compilador não protege contra todos os ataques de segurança de saturação de buffer.Por exemplo, se você tiver um buffer e uma vtable em um objeto, uma saturação de buffer pode corromper o vtable.

Mesmo que você use /GS, tente sempre escrever código seguro que tenha há saturações de buffer.

Para definir essa opção de compilador em Visual Studio

  1. Em Solution Explorer, o botão direito do mouse no projeto e, em seguida, clique em Propriedades.

    Para obter mais informações, consulte Como: abrir páginas de propriedades do projeto.

  2. No Páginas de propriedades caixa de diálogo, clique no C/C++ pasta.

  3. Clique no Geração de código página de propriedades.

  4. Modificar o Buffer Security Check propriedade.

Para definir essa opção de compilador programaticamente

Exemplo

Esta amostra saturações de um buffer.Isso faz com que o aplicativo falhar em tempo de execução.

// 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);
}

Consulte também

Referência

Opções do compilador

Configurando opções de compilador