Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Esta seção descreve como implementar código compatível com integridade de memória.
Observação
A integridade de memória é por vezes referida como integridade de código protegida por hipervisor (HVCI) ou integridade de código imposta pelo hipervisor e foi originalmente lançada como parte do Device Guard. O Device Guard não é mais usado, exceto para localizar a integridade da memória e as configurações do VBS na Diretiva de Grupo ou no Registro do Windows.
Para implementar código compatível, certifique-se de que o código do driver faça o seguinte:
- Opta pelo NX por padrão
- Usa APIs/sinalizadores NX para alocação de memória (NonPagedPoolNx)
- Não usa seções que são graváveis e executáveis
- Não tenta modificar diretamente a memória executável do sistema
- Não usa código dinâmico no kernel
- Não carrega arquivos de dados como executáveis
- O alinhamento da seção é um múltiplo de 0x1000 (PAGE_SIZE). Por exemplo, DRIVER_ALIGNMENT=0x1000
A seguinte lista de DDIs que não estão reservadas para uso do sistema pode ser afetada:
Use os testes de integridade de código no HLK para verificar a compatibilidade do driver de integridade de memória.
Para obter mais informações sobre o teste de segurança dos fundamentos relacionados do sistema, consulte HyperVisor Code Integrity Readiness Test e Memory integrity and VBS.
Para obter mais informações sobre o teste de fundamentos do dispositivo relacionado, consulte os testes Device.DevFund .
Use a tabela a seguir para interpretar a saída e determinar quais alterações de código de driver são necessárias para corrigir os diferentes tipos de incompatibilidades de integridade de memória.
| Aviso | Redenção |
Executar tipo de piscina |
O chamador especificou um tipo de pool executável. Chamando uma função de alocação de memória que solicita memória executável. Certifique-se de que todos os tipos de pool contenham um sinalizador NX não executável. |
Executar proteção de página |
O chamador especificou uma proteção de página executável. Especifique uma máscara de proteção de página "no execute". |
Executar mapeamento de página |
O chamador especificou um mapeamento de lista de descritores de memória executável (MDL). Verifique se a máscara usada contém MdlMappingNoExecute. Para obter mais informações, consulte MmGetSystemAddressForMdlSafe |
Secção Execute-Write |
A imagem contém uma seção executável e gravável. |
Falhas de alinhamento de seção |
A imagem contém uma seção que não está alinhada à página. O alinhamento da seção deve ser um múltiplo de 0x1000 (PAGE_SIZE). Por exemplo, DRIVER_ALIGNMENT=0x1000 |
IAT na seção executável |
A tabela de endereços de importação (IAT) não deve ser uma seção executável da memória. Esse problema ocorre quando o IAT, está localizado em uma seção somente leitura e execução (RX) da memória. Isso significa que o sistema operacional não será capaz de gravar no IAT para definir os endereços corretos da localização da DLL referenciada. Uma forma de isso acontecer é ao usar a opção /MERGE (Combinar seções) na vinculação de código. Por exemplo, se .rdata (dados inicializados somente leitura) for mesclado com dados .text (código executável), é possível que o IAT acabe em uma seção executável da memória. |
Relocações não suportadas
No Windows 10, versão 1507 até Windows 10, versão 1607, devido ao uso de Address Space Layout Randomization (ASLR), um problema pode surgir com o alinhamento de endereços e realocação de memória. O sistema operacional precisa realocar o endereço de onde o vinculador definiu seu endereço base padrão para o local real que a ASLR atribuiu. Essa realocação não pode ultrapassar um limite de página. Por exemplo, considere um endereço de 64 bits que começa no offset (deslocamento) 0x3FFC numa página. O valor do endereço sobrepõe-se à página seguinte no deslocamento 0x0003. Este tipo de relocações sobrepostas não é suportado antes do Windows 10, versão 1703.
Essa situação pode ocorrer quando um inicializador de variável do tipo struct global tem um ponteiro desalinhado para outra variável global, disposto de tal forma que o ligador não pode mover a variável para evitar a realocação entrelaçada. O vinculador tentará mover a variável, mas há situações em que pode não ser capaz de fazê-lo (por exemplo, com grandes estruturas desalinhadas ou grandes matrizes de estruturas desalinhadas). Quando apropriado, os módulos devem ser montados usando a opção /Gy (COMDAT) para permitir que o vinculador alinhe o código do módulo tanto quanto possível.
#include <pshpack1.h>
typedef struct _BAD_STRUCT {
USHORT Value;
CONST CHAR *String;
} BAD_STRUCT, * PBAD_STRUCT;
#include <poppack.h>
#define BAD_INITIALIZER0 { 0, "BAD_STRING" },
#define BAD_INITIALIZER1 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0 \
BAD_INITIALIZER0
#define BAD_INITIALIZER2 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1 \
BAD_INITIALIZER1
#define BAD_INITIALIZER3 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2 \
BAD_INITIALIZER2
#define BAD_INITIALIZER4 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3 \
BAD_INITIALIZER3
BAD_STRUCT MayHaveStraddleRelocations[4096] = { // as a global variable
BAD_INITIALIZER4
};
Existem outras situações envolvendo o uso do código assembler, onde esse problema também pode ocorrer.
Integridade do código do Verificador de Condutor
Use o sinalizador de opção de integridade de código do Verificador de Driver (0x02000000) para habilitar verificações adicionais que validam a conformidade com esse recurso. Para habilitar isso a partir da linha de comando, use o seguinte comando.
verifier.exe /flags 0x02000000 /driver <driver.sys>
Para escolher essa opção se estiver usando a GUI do verificador, selecione Criar configurações personalizadas (para desenvolvedores de código), selecione Avançare, em seguida, selecione Verificações de integridade do código.
Você pode usar a opção de linha de comando /query do verificador para exibir as informações atuais do verificador de driver.
verifier /query