Freigeben über


Warum Thunking notwendig ist

Kernelmodustreiber müssen die Größe eines E/A-Puffers überprüfen, der von einer Benutzermodusanwendung übergeben wird. Wenn eine 32-Bit-Anwendung einen Puffer mit Datentypen mit Zeigergenauigkeit an einen 64-Bit-Treiber übergibt und kein Thunking stattfindet, erwartet der Treiber, dass der Puffer größer ist als er tatsächlich ist. Dies liegt daran, dass die Zeigergenauigkeit 32 Bit unter 32-Bit-Microsoft Windows und 64 Bit unter 64-Bit-Windows beträgt. Betrachten Sie beispielsweise die folgende Strukturdefinition:

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

Unter 32-Bit-Windows beträgt die Größe der DRIVER_DATA-Struktur 12 Bytes. In dieser Tabelle werden die Größen des Event-Members und des ObjectName-Elements der DRIVER_DATA-Struktur angezeigt:

Ereignis ObjectName (USHORT-Länge) ObjectName (maximale USHORT-Länge) ObjectName (PWSTR-Puffer)
32 Bit 16 Bit 16 Bit 32 Bit
(4 Bytes) (2 Bytes) (2 Bytes) (4 Bytes)

Unter 64-Bit-Windows beträgt die Größe der DRIVER_DATA-Struktur 24 Bytes. (Die 4 Bytes des Strukturauffüllungs sind erforderlich, damit der Puffermember an einer 8-Byte-Grenze ausgerichtet werden kann.)

Ereignis ObjectName (USHORT-Länge) ObjectName (maximale USHORT-Länge) Leer (Strukturfüllung) ObjectName (PWSTR-Puffer)
64 Bit 16 Bit 16 Bit 32 Bit 64 Bit
(8 Bytes) (2 Bytes) (2 Bytes) (4 Bytes) (8 Bytes)

Wenn ein 64-Bit-Treiber 12 Bytes DRIVER_DATA empfängt, wenn er 24 Bytes erwartet, schlägt die Größenüberprüfung fehl. Um dies zu verhindern, muss der Treiber erkennen, ob eine DRIVER_DATA-Struktur von einer 32-Bit-Anwendung gesendet wurde, und wenn dies der Fall ist, muss sie vor der Überprüfung entsprechend thun.

Beispielsweise könnte eine Thunkversion der obigen DRIVER_DATA-Struktur wie folgt definiert werden:

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

Da sie nur Datentypen mit fester Genauigkeit enthält, hat diese neue Struktur die gleiche Größe unter 32-Bit-Windows und 64-Bit-Windows.

Ereignis ObjectName (USHORT-Länge) ObjectName (maximale USHORT-Länge) ULONG-Puffer
32 Bit 16 Bit 16 Bit 32 Bit
(4 Bytes) (2 Bytes) (2 Bytes) (4 Bytes)