/GS (verificação de segurança de buffer)
Detecta alguns estouros de buffer que substituem o endereço de retorno da função, 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 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 de retorno. 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 uma substituição da pilha pode ter ocorrido. Se um valor diferente for detectado, o processo é encerrado.
Buffers de GS
Uma verificação de segurança de saturação de buffer é realizada em um o buffer de 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 é de mais de 8 bytes e não ponteiros.
Um buffer alocado usando o _alloca função.
Qualquer classe ou estrutura que contém um buffer do GS.
Por exemplo, as seguintes instruções declare buffers do 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 seguintes instruções declarar não buffers do 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; };
Inicializar o Cookie de segurança
O /GS opção de compilador requer que o cookie de segurança seja inicializada antes de qualquer função que usa o cookie é executar. 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 de retorno. Saturações de buffer são mais facilmente exploradas em plataformas como, por exemplo, x86 e x64, as convenções de chamada de uso que armazenam o endereço de retorno de uma função 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 é executada. Para minimizar esse risco, 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 de parâmetros vulneráveis nas seguintes situações:
Funções que não contêm um buffer do GS.
Otimizações (/O opções) não estão ativados.
Funções que têm uma lista de argumento 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 buffer saturação segurança ataques. 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 possui nenhum saturações de buffer.
Para definir esta opção de compilador no Visual Studio
Em Solution Explorer, o botão direito do mouse no projeto e, em seguida, clique em Propriedades.
For more information, see Como: Abrir páginas de propriedades do projeto.
No Property Pages caixa de diálogo, clique no C/C++ pasta.
Clique na A geração de código página de propriedades.
Modificar o Buffer Security Check propriedade.
Para definir esta opção de compilador programaticamente
- See BufferSecurityCheck.
Exemplo
Este exemplo 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);
}