Поделиться через


Почему требуется thunking

Драйверы режима ядра должны проверять размер любого буфера ввода-вывода, переданного из приложения пользовательского режима. Если 32-разрядное приложение передает буфер, содержащий типы данных с точностью указателя, 64-разрядному драйверу и не выполняется thunking, драйвер ожидает, что буфер будет больше, чем на самом деле. Это связано с тем, что точность указателя составляет 32 бита в 32-разрядной версии Windows и 64 бита в 64-разрядной версии Windows. Например, рассмотрим следующее определение структуры:

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

В 32-разрядной версии Windows размер структуры DRIVER_DATA составляет 12 байт. В этой таблице показаны размеры элемента события и элементов ObjectName структуры DRIVER_DATA:

Событие ObjectName (USHORT длина) ObjectName (USHORT максимальная длина) ObjectName (буфер PWSTR)
32 бита 16 бит 16 бит 32 бита
(4 байта) (2 байта) (2 байта) (4 байта)

В 64-разрядной версии Windows размер структуры DRIVER_DATA составляет 24 байта. (Требуется 4 байта заполнения структуры, чтобы элемент буфера можно было выровнять по 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-разрядной версии Windows и 64-разрядной версии Windows.

Событие ObjectName (USHORT длина) ObjectName (USHORT максимальная длина) Буфер ULONG
32 бита 16 бит 16 бит 32 бита
(4 байта) (2 байта) (2 байта) (4 байта)