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


Почему требуется 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 байта)