Por que a conversão é necessária
Os drivers no modo kernel devem validar o tamanho de qualquer buffer de E/S passado de um aplicativo no modo de usuário. Se um aplicativo de 32 bits passar um buffer contendo tipos de dados de precisão de ponteiro para um driver de 64 bits e nenhuma conversão ocorrer, o driver esperará que o buffer seja maior do que realmente é. Isso ocorre porque a precisão do ponteiro é de 32 bits no Microsoft Windows de 32 bits e 64 bits no Windows de 64 bits. Por exemplo, considere a seguinte definição de estrutura:
typedef struct _DRIVER_DATA
{
HANDLE Event;
UNICODE_STRING ObjectName;
} DRIVER_DATA;
No Windows de 32 bits, o tamanho da estrutura de DRIVER_DATA é de 12 bytes. Esta tabela mostra os tamanhos dos membros Event e ObjectName da estrutura DRIVER_DATA:
Evento | ObjectName (comprimento USHORT) | ObjectName (comprimento máximo do USHORT) | ObjectName (Buffer PWSTR) |
---|---|---|---|
32 bits | 16 bits | 16 bits | 32 bits |
(4 bytes) | (2 bytes) | (2 bytes) | (4 bytes) |
No Windows de 64 bits, o tamanho da estrutura DRIVER_DATA é de 24 bytes. (Os 4 bytes de preenchimento de estrutura são necessários para que o membro buffer possa ser alinhado em um limite de 8 bytes.)
Evento | ObjectName (comprimento USHORT) | ObjectName (comprimento máximo do USHORT) | Vazio (Preenchimento de Estrutura) | ObjectName (Buffer PWSTR) |
---|---|---|---|---|
64 bits | 16 bits | 16 bits | 32 bits | 64 bits |
(8 bytes) | (2 bytes) | (2 bytes) | (4 bytes) | (8 bytes) |
Se um driver de 64 bits receber 12 bytes de DRIVER_DATA quando esperava 24 bytes, a validação de tamanho falhará. Para evitar isso, o driver deve detectar se uma estrutura de DRIVER_DATA foi enviada por um aplicativo de 32 bits e, nesse caso, conversá-la adequadamente antes de executar a validação.
Por exemplo, uma versão com conversão da estrutura de DRIVER_DATA acima pode ser definida da seguinte maneira:
typedef struct _DRIVER_DATA32
{
VOID *POINTER_32 Event;
UNICODE_STRING32 ObjectName;
} DRIVER_DATA32;
Como ele contém apenas tipos de dados de precisão fixa, essa nova estrutura tem o mesmo tamanho no Windows de 32 bits e no Windows de 64 bits.
Evento | ObjectName (comprimento USHORT) | ObjectName (comprimento máximo do USHORT) | ULONG Buffer |
---|---|---|---|
32 bits | 16 bits | 16 bits | 32 bits |
(4 bytes) | (2 bytes) | (2 bytes) | (4 bytes) |