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) |