Compartir a través de


¿Por qué es necesario Thunking?

Los controladores en modo kernel deben validar el tamaño de cualquier búfer de E/S pasado desde una aplicación en modo de usuario. Si una aplicación de 32 bits pasa un búfer que contiene tipos de datos de precisión de puntero a un controlador de 64 bits y no tiene lugar ningún matones, el controlador esperará que el búfer sea mayor que realmente. Esto se debe a que la precisión del puntero es de 32 bits en Microsoft Windows de 32 bits y 64 bits en Windows de 64 bits. Por ejemplo, considere la siguiente definición de estructura:

typedef struct _DRIVER_DATA
{
    HANDLE           Event;
    UNICODE_STRING   ObjectName;
} DRIVER_DATA;

En Windows de 32 bits, el tamaño de la estructura de DRIVER_DATA es de 12 bytes. En esta tabla se muestran los tamaños del miembro Event y los miembros ObjectName de la estructura DRIVER_DATA:

Evento ObjectName (longitud de USHORT) ObjectName (longitud máxima de USHORT) ObjectName (Búfer PWSTR)
32 bits 16 bits 16 bits 32 bits
(4 bytes) (2 bytes) (2 bytes) (4 bytes)

En Windows de 64 bits, el tamaño de la estructura de DRIVER_DATA es de 24 bytes. (Se requieren 4 bytes de relleno de estructura para que el miembro buffer se pueda alinear en un límite de 8 bytes).

Evento ObjectName (longitud de USHORT) ObjectName (longitud máxima de USHORT) Vacío (relleno de estructura) ObjectName (Búfer PWSTR)
64 bits 16 bits 16 bits 32 bits 64 bits
(8 bytes) (2 bytes) (2 bytes) (4 bytes) (8 bytes)

Si un controlador de 64 bits recibe 12 bytes de DRIVER_DATA cuando esperaba 24 bytes, se producirá un error en la validación del tamaño. Para evitar esto, el controlador debe detectar si una aplicación de 32 bits envió una estructura de DRIVER_DATA y, si es así, thunkla correctamente antes de realizar la validación.

Por ejemplo, una versión thunked de la estructura de DRIVER_DATA anterior podría definirse de la siguiente manera:

typedef struct _DRIVER_DATA32
{
    VOID *POINTER_32   Event;
    UNICODE_STRING32   ObjectName;
} DRIVER_DATA32;

Dado que solo contiene tipos de datos de precisión fija, esta nueva estructura tiene el mismo tamaño en Windows de 32 bits y Windows de 64 bits.

Evento ObjectName (longitud de USHORT) ObjectName (longitud máxima de USHORT) Búfer de ULONG
32 bits 16 bits 16 bits 32 bits
(4 bytes) (2 bytes) (2 bytes) (4 bytes)