Почему требуется thunking
Драйверы режима ядра должны проверять размер любого буфера ввода-вывода, передаваемого из приложения пользовательского режима. Если 32-разрядное приложение передает буфер, содержащий типы данных с точностью указателя, в 64-разрядный драйвер и не выполняется ломка, драйвер ожидает, что буфер будет больше, чем на самом деле. Это связано с тем, что точность указателя составляет 32 бита в 32-разрядной версии Microsoft Windows и 64 бита в 64-разрядной версии Windows. Например, рассмотрим следующее определение структуры:
typedef struct _DRIVER_DATA
{
HANDLE Event;
UNICODE_STRING ObjectName;
} DRIVER_DATA;
В 32-разрядной версии Windows размер структуры DRIVER_DATA составляет 12 байт. В этой таблице показаны размеры элементов Event и ObjectName структуры DRIVER_DATA:
Событие | ObjectName (длина USHORT) | ObjectName (максимальная длина USHORT) | ObjectName (буфер PWSTR) |
---|---|---|---|
32 бита | 16 бит | 16 бит | 32 бита |
(4 байта) | (2 байта) | (2 байта) | (4 байта) |
В 64-разрядной версии Windows размер структуры DRIVER_DATA составляет 24 байта. (Требуется 4 байта заполнения структуры, чтобы элемент Buffer можно было выровнять по 8-байтовой границе.)
Событие | ObjectName (длина USHORT) | ObjectName (максимальная длина USHORT) | Пустой (заполнение структуры) | ObjectName (буфер PWSTR) |
---|---|---|---|---|
64 бита | 16 бит | 16 бит | 32 бита | 64 бита |
(8 байт) | (2 байта) | (2 байта) | (4 байта) | (8 байт) |
Если 64-разрядный драйвер получает 12 байт DRIVER_DATA если ожидается 24 байта, проверка размера завершится ошибкой. Чтобы избежать этого, драйвер должен определить, была ли DRIVER_DATA структура отправлена 32-разрядным приложением, и, если да, сорвать ее соответствующим образом перед выполнением проверки.
Например, thunked версию приведенной выше структуры DRIVER_DATA можно определить следующим образом:
typedef struct _DRIVER_DATA32
{
VOID *POINTER_32 Event;
UNICODE_STRING32 ObjectName;
} DRIVER_DATA32;
Так как он содержит только типы данных с фиксированной точностью, эта новая структура имеет одинаковый размер в 32-разрядной и 64-разрядной версиях Windows.
Событие | ObjectName (длина USHORT) | ObjectName (максимальная длина USHORT) | Буфер ULONG |
---|---|---|---|
32 бита | 16 бит | 16 бит | 32 бита |
(4 байта) | (2 байта) | (2 байта) | (4 байта) |